2

我在 Python 中有这个代码片段:

s = socket.create_connection(('192.168.0.111', 123), timeout=2.0)
s.sendall('REQUEST,status,interface'); result = s.recv(1024)

如何使用 Indy 组件中的 TIdTCPClient 在 Delphi 中执行“s.recv(1024)”?服务器返回一个没有任何终止符的字符串,所以 ReadLn 不起作用。

4

1 回答 1

4

在 Python 中,recv(1024)只需读取套接字上可用的任何内容,最多 1024 个字节。可以用TIdTCPClient(见下文)做同样的事情,但这不是处理套接字编程的最佳方式。您确实需要知道服务器实际上是如何终止数据的。发送数据后是否关闭连接的末端?如果不是,它是否希望您简单地读取任何可用的字节而不管实际长度如何?如果是这样,它希望您如何处理 TCP 数据包碎片(TCP/IP 可以将传输的数据分成多个数据包,并且即使它们不是这样发送的,也可以将数据作为多个数据包接收)?它是否希望您继续阅读,直到发生超时,表明不再发送数据?

它对您编写代码以正确处理读取的方式有很大的影响。例如:

IdTCPClient1.Host := '192.168.0.111';
IdTCPClient1.Port := 123;
IdTCPClient1.ConnectTimeout := 2000;
IdTCPClient1.Connect;
try
  IdTCPClient1.IOHandler.Write('REQUEST, status, interface');

  // wait for a disconnect then return everything that was received
  Result := IdTCPClient1.IOHandler.AllData;
finally
  IdTCPClient1.Disconnect;
end;

对比:

IdTCPClient1.Host := '192.168.0.111';
IdTCPClient1.Port := 123;
IdTCPClient1.ConnectTimeout := 2000;
IdTCPClient1.Connect;
try
  IdTCPClient1.IOHandler.Write('REQUEST, status, interface');

  // set the max number of bytes to read at one time
  IdTCPClient1.IOHandler.RecvBufferSize := 1024;

  // read whatever is currently in the socket's receive buffer, up to RecvBufferSize number of bytes
  IdTCPClient1.IOHandler.CheckForDataOnSource;

  // return whatever was actually read
  Result := IdTCPClient1.IOHandler.InputBufferAsString;
finally
  IdTCPClient1.Disconnect;
end;

对比:

IdTCPClient1.Host := '192.168.0.111';
IdTCPClient1.Port := 123;
IdTCPClient1.ConnectTimeout := 2000;
IdTCPClient1.Connect;
try
  IdTCPClient1.IOHandler.Write('REQUEST, status, interface');

  // keep reading until 5s of idleness elapses
  repeat until not IdTCPClient1.IOHandler.CheckForDataOnSource(5000);

  // return whatever was actually read
  Result := IdTCPClient1.IOHandler.InputBufferAsString;
finally
  IdTCPClient1.Disconnect;
end;
于 2013-01-11T02:31:16.560 回答