好的伙计们,我正在使用TClientSocket类和Threads与主机列表同时工作。这一切都很好,但我开始注意,经过一段时间后,所有线程都被卡入了一个ReceiveBuf调用...如果我打开10个线程,例如检查100个主机,它会启动良好,但是过了一段时间后所有线程都会被卡住,因为某些主机因为这个ReceiveBuf呼叫没有回复的原因...我试图做一个ReceiveLength并检查是否接收> 0,调用ReceiveBuf,但仍然无法正常工作。 我将在下面发布原始代码:
function Threads.ReceiveProtocolVersion;
var
ProtocolVersion: array[0..11] of AnsiChar;
begin
try
MySocket.Socket.ReceiveBuf(ProtocolVersion, SizeOf(ProtocolVersion));
Version:= AnsiString(ProtocolVersion);
...//continues but doesn't matter because many threads get stucked in the ReceiveBuf call...
except
Terminate; //we terminate thread if raise some exception..
好的,经过一些研究后,我开始尝试这样做:
function Threads.ReceiveProtocolVersion;
var
ProtocolVersion: array[0..11] of AnsiChar;
SizeBuf: integer;
begin
try
SizeBuf:= MySocket.Socket.ReceiveLength;
if SizeBuf > 0 then
begin
MySocket.Socket.ReceiveBuf(ProtocolVersion, SizeOf(ProtocolVersion));
Version:= AnsiString(ProtocolVersion);
....
end;
except
Terminate; //we terminate thread if raise some exception..
显然,它解决了线程陷入ReceiveBuf调用的问题,但由于某些未知的原因,没有(甚至那些工作正常的)线程进入'if SizeBuf> 0' 。 有什么帮助吗?
//编辑显示更多线程代码:: Thread.Execute是这样的:
procedure MyThread.Execute;
begin
while not(Terminated) do
begin
if SocketConnect then
begin
if ReceiveProtocolVersion then
begin
DoAuthentication;
end;
end;
MySocket.Close;
MySocket.Free;
end;
Terminate;
end;
SocketConnect功能是:
function MyThread.SocketConnect: bool;
begin
Result:= false;
MySocket:= TClientSocket.Create(Nil);
MySocket.Port:= StrToInt(Form1.Edit1.Text);
MySocket.ClientType:= ctBlocking;
MySocket.Host:= Host; //Host is a private variable for thread class
try
MySocket.Active:= true;
if (MySocket.Socket.Connected = true) then
Result:= true;
except
Terminate;
end;
end;
答案 0 :(得分:1)
我使用TWinSocketStream解决了这个问题。像这样:
function MyThread.CheckProtocol: bool;
var
SockStream: TWinSocketStream;
ProtocolVersion: array[0..11] of AnsiChar;
begin
try
SockStream := TWinSocketStream.Create(MySocket.Socket, 3000);
SockStream.Read(ProtocolVersion, SizeOf(ProtocolVersion));
RFBVer:= AnsiString(ProtocolVersion);
....
我读到使用阻塞模式套接字的正确方法是通过TWinSocketStream发送/接收数据: DocWiki Embarcadero
无论如何,感谢那些试图帮助的人!