您好我的以下代码有问题:
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;
有人可以帮助我吗?
答案 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.