hun*_*dym 5 delphi indy tcpclient tcpserver indy10
我的 Indy TCP 连接有问题。我使用带有 Indy 10 的 Turbo Delphi 2006。我想将多个 TCP 包从 idTCPClient 发送到 idTCPServer。
当我只想发送一个包时,它工作得很好,或者我在函数的两次调用之间插入了 sleep(100) 命令。但是如果我太频繁地调用这个函数,它就不会每次都调用服务器的 onExecute。
我的发送代码:
procedure SendData(var data: TIdBytes) ;
begin
FormMain.IdTCPClient.Connect ;
FormMain.IdTCPClient.Socket.Write(data);
FormMain.IdTCPClient.Disconnect ;
end ;
Run Code Online (Sandbox Code Playgroud)
我多次调用此函数(每秒 5-10 次),并希望在我的服务器应用程序中处理所有这些包:
procedure TFormMain.IdTCPServerMainExecute(AContext: TIdContext);
var
data: TIdBytes ;
begin
AContext.Connection.IOHandler.ReadBytes(data, 4, false)
// processing data
end
Run Code Online (Sandbox Code Playgroud)
提前感谢您的回答!
每次调用时Connect(),都会创建一个新连接,TIdTCPServer并将启动一个新线程来处理该连接(除非您启用线程池)。这真的是你想要的吗?让客户端保持连接打开一段时间并尽可能多地重用现有连接会更有效。只有当您真的不再需要它时才断开连接,例如它已经闲置了一段时间。在两端建立新连接都是一项代价高昂的操作,因此您应该尽可能减少这种开销。
在客户端,当您调用 时Write(data),它会发送整个TIdBytes,但您不会将其长度发送TIdBytes到服务器,因此它知道需要多少字节。 TIdIOHandler.Write(TIdBytes)不会为您执行此操作,您必须手动执行此操作。
在服务器端,您告诉您ReadBytes()一次只能读取 4 个字节。在每个 4 字节块之后,您将退出OnExecute事件处理程序并等待再次调用它以读取下一个 4 字节块。除非客户端源的长度TIdBytes是 4 的偶数倍,ReadBytes()否则在尝试读取客户端的最后一个小于 4 字节的块时会引发异常(导致服务器断开连接),因此您的服务器代码将无法接收那个块。
试试这个:
procedure SendData(var data: TIdBytes) ;
begin
FormMain.IdTCPClient.Connect;
try
FormMain.IdTCPClient.IOHandler.Write(Longint(Length(data)));
FormMain.IdTCPClient.IOHandler.Write(data);
finally
FormMain.IdTCPClient.Disconnect;
end;
end;
procedure TFormMain.IdTCPServerMainExecute(AContext: TIdContext);
var
data: TIdBytes;
begin
with AContext.Connection.IOHandler do
ReadBytes(data, ReadLongint, false);
// process data
end;
Run Code Online (Sandbox Code Playgroud)
话虽如此,如果TIdBytes出于某种原因无法更改客户端代码以发送长度,请改用此服务器代码:
procedure TFormMain.IdTCPServerMainExecute(AContext: TIdContext);
var
LBytes: Integer;
data: TIdBytes;
begin
// read until disconnected. returns -1 on timeout, 0 on disconnect
repeat until AContext.Connection.IOHandler.ReadFromSource(False, 250, False) = 0;
AContext.Connection.IOHandler.InputBuffer.ExtractToBytes(data);
// process data
end;
Run Code Online (Sandbox Code Playgroud)
或者:
procedure TFormMain.IdTCPServerMainExecute(AContext: TIdContext);
var
strm: TMemoryStream;
data: TIdBytes;
begin
strm := TMemoryStream.Create;
try
// read until disconnected
AContext.Connection.IOHandler.ReadStream(strm, -1, True);
strm.Position := 0;
ReadTIdBytesFromStream(strm, data, strm.Size);
finally
strm.Free;
end;
// process data
end;
Run Code Online (Sandbox Code Playgroud)
或者:
procedure TFormMain.IdTCPServerMainExecute(AContext: TIdContext);
var
strm: TMemoryStream;
begin
strm := TMemoryStream.Create;
try
// read until disconnected
AContext.Connection.IOHandler.ReadStream(strm, -1, True);
// process strm.Memory up to strm.Size bytes
finally
strm.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4371 次 |
| 最近记录: |