1

DelphiでのServerSocket使用方法を理解しようとしています。ClientSocket簡単なチャットプログラムを作成しましたが、クライアントが最初のメッセージを送信した後、このエラーが発生します(送信中に発生します-サーバーがメッセージを取得した直後)

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()する API 関数です。これは、サーバーに接続されていないのプロパティSocket.RemoteAddressを読み取ろうとしたことを意味します。RemoteAddressSocket

于 2012-11-12T05:09:01.663 に答える