好了,伙计们,我使用TClientSocket类和线程来同时处理一系列主机。这一切都很好,但我开始注意到,过了一段时间,所有线程都被塞进了一个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;发布于 2013-05-22 01:33:15
我使用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);
....我读到使用阻塞模式套接字的正确方法是在DocWiki Embarcadero中通过TWinSocketStream发送/接收数据
无论如何,感谢那些试图帮助我们的人!
https://stackoverflow.com/questions/16657649
复制相似问题