Ошибка сокета Delphi
Пытаясь понять, как использовать ServerSocket
а также ClientSocket
в Дельфи. Я сделал простую программу чата, но после того, как клиент отправил первое сообщение, эта ошибка apperas
(это происходит во время отправки - сразу после того, как сервер получает сообщение)
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
,
2 ответа
Мне очень жаль, если я опубликую это поздно, но я решил эту проблему, и вы можете не увидеть ее.
на стороне сервера убедитесь, что вы отправляете в сокет по индексу, например:
ServerSocket1.Socket.Connections[SocketIndex].SendText();
Не забудьте свойство .Connections.
Код ошибки 10057 есть WSAENOTCONN
, а также getpeername()
это функция API, которую Socket.RemoteAddress
свойство getter использует внутренне. Это означает, что вы пытались прочитать RemoteAddress
свойство Socket
это больше не было связано с сервером.