【发布时间】:2014-04-30 03:28:22
【问题描述】:
我有一个简单的过程,它使用 TIdTCPClient 连接到服务器。其目的是尝试到达服务器并阻塞线程,直到建立连接。它适用于稳定的互联网连接。问题是,当此客户端在某些计算机上执行时(所有这些计算机的互联网连接缓慢或不稳定,例如移动 3G 或只是在遥远的小城镇),它总是无法连接并出现“连接超时”异常。同时上述电脑运行浏览器、IM客户端等,这些应用程序运行良好。我的服务器应用程序也没有显示新客户端的迹象。
程序如下:
procedure ConnectToServer;
begin
EnterCriticalSection(CS_Connect);
try
while not Client.Connected do
begin
Log('Connection attempt...');
Client.Port := <port goes here>;
Client.IPVersion := Id_IPv4;
Client.Host := '<ip address here>';
Client.ConnectTimeout := 11500;
try
Client.Connect;
except
on E: Exception do
Log('Exception: ' + E.ToString);
end;
if Client.Connected then
begin
Log('Connected after ' + inttostr(attempts) + ' failed attempts');
Client.IOHandler.WriteLn(MSG_HELLO);
attempts := 0;
exit;
end;
Inc(attempts);
Log('Connection attempt failed');
Sleep( min(attempts * 1000, 50000) );
end;
finally
LeaveCriticalSection(CS_Connect);
end;
end;
【问题讨论】:
-
使用 EnterCriticalSection/LeaveCriticalSection 包装此代码看起来好像有多个线程可以尝试使用相同的(“全局”)TIdTCPClient 执行 ConnectToServer 方法。所以线程 A 连接,离开该部分,线程 B 将尝试“再次”连接一个已经打开的连接 - 关键部分不会阻止这一点。
-
关键部分在这里只是一个预防措施,至少现在是这样。该过程从主线程执行一次,并且在发现连接丢失时也在计时器线程(CreateTimerQueueTimer())中执行。