문제

Trying to understood how to use ServerSocket and ClientSocket in Delphi. I made a simple chat programm but after client sends first message this error apperas (it happens during sending - just after server get's the message )

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

Heres server code

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.

Here's client code

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

.

도움이 되었습니까?

해결책

i'm really sorry if i'm posting this late, but i solved this issue and you might not see it.

in the server-side, make sure that you send to the socket by index, example:

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

Don't forget the .Connections property.

다른 팁

Error code 10057 is WSAENOTCONN, and getpeername() is the API function that the Socket.RemoteAddress property getter uses internally. This means you tried to read the RemoteAddress property of a Socket that was no longer connected to the server.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top