我正在以阻塞模式使用TClientSocket / TServerSocket创建TCP客户端/服务器。已经使用telnet构建了概念证明服务器并对其进行了基本功能(接收数据)的测试。在客户端上,将有两个线程,一个用于写入,另一个用于读取。现在,为了测试“发送(或写入)线程”,我正在使用以下代码。但是stream.WaitForData(30000)总是超时。 Delphi帮助说:“在通过套接字连接读取或写入信息之前,请先调用WaitForData”。所以我想知道TWinSockStream如何知道我正在调用WaitForData进行写入而不是读取?
procedure TClientThread.Execute;
var
stream: TWinSocketStream;
buffer: string;
begin
stream := TWinSocketStream.Create(FClientSocket.Socket, 60000);
try
while (not Terminated) and (FClientSocket.Active) do
begin
try
//FSendDataEvent is a trigger used for testing purpose
if FSendDataEvent.WaitFor(1000) = wrSignaled then
begin
FSendDataEvent.ResetEvent;
if stream.WaitForData(30000) then
begin
buffer := 'Hello from client';
stream.Write(buffer, Length(buffer) + 1 );
end;
end;
//Other useful code
except
on E:Exception do
begin
DebugOutput('TClientThread.Execute: ' + E.Message);
end;
end;
end;
finally
stream.free;
end;
end;
即使删除了WaitForData(),文本也不会照原样发送到服务器。但是以下代码在直接调用时没有任何WaitForData()时可以正常工作。
FClientSocket.Socket.SendText('Hi from client');
那么,将TWinSocketStream与TClientSocket一起使用的正确方法是什么?
任何帮助将不胜感激。
最佳答案
该文档是错误的。 WaitForData()
仅适用于阅读,不适用于书写。
对于使用TWinSocketStream
写入数据,您在Write()
的第一个参数中传递了错误的值,这就是为什么它无法正确发送的原因。第一个参数是无类型的const
,因此您需要引用字符串以便传递第一个字符的内存地址,例如:
Stream.Write(Buffer[1], ...);
要么:
Stream.Write(PChar(Buffer)^, ...);