Delphi中的ClientSocket出错

时间:2015-02-28 20:59:48

标签: delphi

您好我的以下代码有问题:

program client;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils, System.Win.ScktComp, idContext, idGlobal;

var
  ClientSocket1: TClientSocket;
  m: TMethod;
  m2: TMethod;

procedure hi(Sender: TObject; Socket: TCustomWinSocket);
begin
  ClientSocket1.Socket.SendText('hello');
  Writeln('connect');
end;

Procedure read_data(Sender: TObject; Socket: TCustomWinSocket);
Var
  Raw: String;
Begin
  Raw := Socket.ReceiveText;
  Writeln(Raw);
End;

begin
  try

    ClientSocket1 := TClientSocket.Create(nil);
    ClientSocket1.Address := '127.0.0.1';
    ClientSocket1.Port := 123;
    ClientSocket1.Open;

    m.Code := @read_data;
    m.Data := ClientSocket1;
    ClientSocket1.OnRead := TSocketNotifyEvent(m);

    m2.Code := @hi;
    m2.Data := ClientSocket1;
    ClientSocket1.OnConnect := TSocketNotifyEvent(m2);

    while '1' = '1' do
    begin
      //
    end;

  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

end.

问题是没有从服务器接收任何信息,并且在程序中未检测到正确连接时。 该程序是一个使用ClientSocket组件进行连接的控制台应用程序。

服务器程序在图形应用程序中运行并使用启用ServerSocket组件的端口123,使用以下按钮:

procedure TForm1.Button1Click(Sender: TObject);
begin
  ServerSocket1.Socket.Connections[ListBox1.Itemindex].SendText(Edit1.Text);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  lugar: Integer;
begin
  ListBox1.Clear;
  for lugar := 0 To ServerSocket1.Socket.ActiveConnections - 1 do
  begin
    ListBox1.Items.add(ServerSocket1.Socket.Connections[lugar].RemoteHost);
  end;
end;

有人可以帮助我吗?

1 个答案:

答案 0 :(得分:0)

默认情况下,TClientSocket以非阻止模式运行。在该模式下,它在内部使用窗口消息来触发其事件。但是代码中没有消息循环,因此您需要添加一个消息循环。您也没有正确设置事件处理程序(您缺少明确的Self参数,因为您的处理程序不是类的成员)。

试试这个:

program client;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, System.Win.ScktComp, Winapi.Windows;

procedure socket_connected(Self: Pointer; Sender: TObject; Socket: TCustomWinSocket);
begin
  Writeln('connect');
  Socket.SendText('hello');
end;

procedure socket_disconnected(Self: Pointer; Sender: TObject; Socket: TCustomWinSocket);
begin
  Writeln('disconnect');
  PostQuitMessage(0);
end;

procedure socket_read(Self: Pointer; Sender: TObject; Socket: TCustomWinSocket);
var
  Raw: String;
begin
  Raw := Socket.ReceiveText;
  Writeln(Raw);
end;

procedure socket_error(Self: Pointer; Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
  Writeln('error');
  PostQuitMessage(0);
end;

var
  ClientSocket1: TClientSocket;
  m: TMethod;
  msg: TMsg;
begin
  try
    ClientSocket1 := TClientSocket.Create(nil);
    try
        ClientSocket1.Address := '127.0.0.1';
        ClientSocket1.Port := 123;

        m.Code := @socket_connected;
        m.Data := ClientSocket1;
        ClientSocket1.OnConnect := TSocketNotifyEvent(m);

        m.Code := @socket_disconnected;
        m.Data := ClientSocket1;
        ClientSocket1.OnDisconnect := TSocketNotifyEvent(m);

        m.Code := @socket_read;
        m.Data := ClientSocket1;
        ClientSocket1.OnRead := TSocketNotifyEvent(m);

        m.Code := @socket_error;
        m.Data := ClientSocket1;
        ClientSocket1.OnError := TSocketErrorEvent(m);

        ClientSocket1.Open;

        while GetMessage(msg, 0, 0, 0) do
        begin
          TranslateMessage(msg);
          DispatchMessage(msg);
        end;
      finally
        ClientSocket1.Free;
      end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;    
end.

否则,请将套接字更改为阻塞模式,并完全删除事件处理程序:

program client;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, System.Win.ScktComp;

var
  ClientSocket1: TClientSocket;
  Raw: String;
begin
  try
    ClientSocket1 := TClientSocket.Create(nil);
    try
        ClientSocket1.Address := '127.0.0.1';
        ClientSocket1.Port := 123;
        ClientSocket1.ClientType := ctBlocking;

        try
          ClientSocket1.Open;
          Writeln('connect');
          ClientSocket1.Socket.SendText('hello');
          repeat
            Raw := ClientSocket1.Socket.ReceiveText;
            if Raw <> '' then Writeln(Raw);
          until not ClientSocket1.Connected;
          Writeln('disconnect');
        except    
          Writeln('error');
          raise;
        end;
      finally
        ClientSocket1.Free;
      end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;    
end.