1

试图了解如何使用ServerSocketClientSocket在 Delphi 中。我做了一个简单的聊天程序,但是在客户端发送第一条消息后出现此错误(它发生在发送过程中 - 就在服务器收到消息之后)

Windows socket error: Запрос на отправку или получение данных (when sending ona datagram socket using a sendto call)no adress was supplied (10057), on API 'getpeername'

继承人服务器代码

unit Servert;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ScktComp;

type
  TForm1 = class(TForm)
    ServerSocket: TServerSocket;
    PortLabel: TLabel;
    Port: TEdit;
    Protocol: TGroupBox;
    mmoServer: TMemo;
    btnStart: TButton;
    btnStop: TButton;
    btnClear: TButton;
    btnEnd: TButton;
    btnSend: TButton;
    edtMsg: TEdit;
    lblUser: TLabel;
    procedure btnStartClick(Sender: TObject);
    procedure btnStopClick(Sender: TObject);
    procedure btnClearClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btnEndClick(Sender: TObject);
    procedure ServerSocketClientConnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ServerSocketClientDisconnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ServerSocketClientError(Sender: TObject;
      Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
      var ErrorCode: Integer);
    procedure ServerSocketClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure btnSendClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Usercount: Integer;

implementation

{$R *.dfm}

procedure TForm1.btnStartClick(Sender: TObject);
begin
  ServerSocket.Port:=StrToInt(Port.Text);
  ServerSocket.Active:=True;

  btnStart.Enabled:=False;
  btnStop.Enabled:=True;

  mmoServer.Lines.Add('Status: started');
end;

procedure TForm1.btnStopClick(Sender: TObject);
begin
ServerSocket.Port:=StrToInt(Port.Text);
  ServerSocket.Active:=False;

  btnStart.Enabled:=True;
  btnStop.Enabled:=False;

  mmoServer.Lines.Add('Status: stopped');
end;

procedure TForm1.btnClearClick(Sender: TObject);
begin
  mmoServer.Lines.Clear;
  mmoServer.Lines.Add('Server 1.0');
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  ServerSocket.Active:=False;
end;

procedure TForm1.btnEndClick(Sender: TObject);
begin
  ServerSocket.Active:=False;
  Application.Terminate;
end;



procedure TForm1.ServerSocketClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  mmoServer.Lines.Add('Status: Client ' + Socket.RemoteAddress + ' connected');
  Inc(Usercount);
  lblUser.Caption:= 'User:' + IntToStr(Usercount);
end;

procedure TForm1.ServerSocketClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  mmoServer.Lines.Add('Status: Client ' + Socket.RemoteAddress + ' disconnected');
  Dec(Usercount);
  lblUser.Caption:= 'User:' + IntToStr(Usercount);
end;

procedure TForm1.ServerSocketClientError(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
  mmoServer.Lines.Add('Status: Client ' + Socket.RemoteAddress + ' error:' + IntToStr(ErrorCode));
  Dec(Usercount);
  lblUser.Caption:= 'User:' + IntToStr(Usercount);
end;

procedure TForm1.ServerSocketClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var i:Integer; strRec:AnsiString;
begin
  strRec:=Socket.RemoteAddress + ': ' + Socket.ReceiveText;
  mmoServer.Lines.Add(strRec);

  for i:=0 to ServerSocket.Socket.ActiveConnections - 1 do  begin
    ServerSocket.Socket.Connections[i].SendText(strRec);
  end;


end;

procedure TForm1.btnSendClick(Sender: TObject);
var i:Integer;
begin
  for i:=0 to ServerSocket.Socket.ActiveConnections - 1 do
  begin
    ServerSocket.Socket.Connections[i].SendText('Ololo' + edtMsg.Text);
    mmoServer.Lines.Add('Ololo' + edtMsg.Text);
  end;
end;

end.

这是客户端代码

unit Client;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ScktComp, StdCtrls;

type
  TForm1 = class(TForm)
    lblHost: TLabel;
    edtHost: TEdit;
    lblPort: TLabel;
    edtPort: TEdit;
    btnConnect: TButton;
    btnDisconnect: TButton;
    grp1: TGroupBox;
    mmoClient: TMemo;
    grpSend: TGroupBox;
    mmoSend: TMemo;
    btnSend: TButton;
    ClientSocket: TClientSocket;
    procedure ClientSocketConnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure btnDisconnectClick(Sender: TObject);
    procedure btnConnectClick(Sender: TObject);
    procedure ClientSocketDisconnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);
    procedure btnSendClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ClientSocketConnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  mmoClient.Lines.Add('Status: connected ' + Socket.RemoteAddress);
end;

procedure TForm1.btnDisconnectClick(Sender: TObject);
begin
  ClientSocket.Host:=edtHost.Text;
  ClientSocket.Port:=StrToInt(edtPort.Text);
  ClientSocket.Active:=False;

  btnConnect.Enabled:=True;
  btnDisconnect.Enabled:=False;
end;

procedure TForm1.btnConnectClick(Sender: TObject);
begin
ClientSocket.Host:=edtHost.Text;
  ClientSocket.Port:=StrToInt(edtPort.Text);
  ClientSocket.Active:=True;

  btnConnect.Enabled:=False;
  btnDisconnect.Enabled:=True;
end;

procedure TForm1.ClientSocketDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
     mmoClient.Lines.Add('Status: disconnected ' + Socket.RemoteAddress)
end;

procedure TForm1.ClientSocketRead(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  mmoClient.Lines.Add(Socket.ReceiveText);
end;

procedure TForm1.btnSendClick(Sender: TObject);
begin
  ClientSocket.Socket.SendText(mmoSend.Text);
end;

end

.

4

2 回答 2

1

如果我发布这么晚,我真的很抱歉,但我解决了这个问题,你可能看不到它。

在服务器端,确保按索引发送到套接字,例如:

ServerSocket1.Socket.Connections[SocketIndex].SendText();

不要忘记.Connections属性。

于 2013-03-13T09:05:13.540 回答
0

错误代码 10057 是WSAENOTCONN,并且getpeername()Socket.RemoteAddress属性 getter 在内部使用的 API 函数。这意味着您试图读取不再连接到服务器RemoteAddress的 a 的属性。Socket

于 2012-11-12T05:09:01.663 回答