Question

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

.

Was it helpful?

Solution

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top