我的笔记本电脑连接到TIdTCPServer
时遇到了一个问题。问题是,它连接正常,发送了一个命令,但当它试图再次发送时,它得到了套接字错误10053或10004或10054。
相同的代码在其他计算机上工作正常,只是在这台笔记本电脑上发生了这个错误。
我在一个线程中使用连接,下面是代码:
type
TThreadCon = class(TThread)
private
TCPClient : TIdTCPClient;
protected
procedure Execute; override;
public
constructor Create;
destructor Destroy; override;
end;
procedure DJWRZORLBS(millisecs: Integer);
var
tick : dword;
AnEvent : THandle;
begin
AnEvent := CreateEvent(nil, False, False, nil);
try
tick := GetTickCount + dword(millisecs);
while (millisecs > 0) and (MsgWaitForMultipleObjects(1, AnEvent, False, millisecs, QS_ALLINPUT) <> WAIT_TIMEOUT) do begin
Application.ProcessMessages;
if Application.Terminated then Exit;
millisecs := tick - GetTickcount;
end;
finally
CloseHandle(AnEvent);
end;
end;
constructor TThreadCon.Create;
begin
inherited Create(True);
TCPClient := TIdTCPClient.Create(Nil);
TCPClient.ReadTimeout := 3*60000;
TCPClient.ConnectTimeout := 3*60000;
TCPClient.Port := StrToInt(PortaPS);
TCPClient.Host := Host;
TCPClient.IPVersion := Id_IPv4;
TCPClient.UseNagle := True;
TCPClient.ReuseSocket := rsOSDependent;
end;
procedure TThreadCon.Execute;
begin
while True do
begin
//Sleep(2500);
try
if not TCPClient.Connected then
begin
TCPClient.Connect;
if TCPClient.Connected then
begin
Attempts:= 0;
WriteLn(Format('[%s] Connected to server. [%d]', [TimeToStr(Now), Attempts]));
TCPClient.IOHandler.WriteLn('connect');
if rt = nil then rt := TReadingThread.Create(TCPClient);
end;
end
else
begin
LastPing:= GetTickCount;
try
TCPClient.IOHandler.WriteLn('Ping');
except
on E: Exception do
begin
WriteLn(Format('[%s] Error while trying send ping: %s', [TimeToStr(Now), E.Message]));
end;
end;
WriteLn(Format('[%s] Ping send, Last Ping [%d]', [TimeToStr(Now), GetTickCount-LastPing]));
end;
except
on E: Exception do
begin
Inc(Attempts);
TCPClient.Disconnect(False);
if TCPClient.IOHandler <> nil then TCPClient.IOHandler.InputBuffer.Clear;
WriteLn(Format('[%s] Failed to connect, error: %s [%d]', [TimeToStr(Now), E.Message, Attempts]));
end;
end;
DJWRZORLBS(5000);
end;
end;
下面是发生问题的控制台日志。它连接到服务器,然后当线程再次运行时,它应该发送Ping
开始出现问题,出于某种原因,在某些情况下,它总是在每次线程运行时显示为连接,就像TCPClient.Connected
没有连接一样。
这是工作正常的计算机上的正常日志:
[21:44:59] Connected to server. [0]
[21:45:04] Ping send, Last Ping [0]
[21:45:09] Ping send, Last Ping [0]
如果我关闭服务器,等待几秒钟,然后重新打开,它显示如下:
[21:45:54] Failed to connect, error: Socket Error # 10054
Connection reset by peer. [1]
[21:46:01] Failed to connect, error: Socket Error # 10061
Connection refused. [2]
[21:46:08] Failed to connect, error: Socket Error # 10061
Connection refused. [3]
[21:46:14] Connected to server. [0]
[21:46:19] Ping send, Last Ping [0]
对我来说,这是它应该如何正确地工作。
是什么原因导致的?服务器上的一些问题?但如果是在服务器上,为什么其他机器工作正常?
一些网络设置?如果是,我可以做些什么来解决它?
1条答案
按热度按时间t0ybt7op1#
在内部,
Connected
执行一个阅读操作,这在您的情况下不是一件好事,因为如果Connect()
成功,您会有另一个线程同时从同一个套接字读取,这两个线程将争夺对套接字的访问权并将数据放入它的IOHandler.InputBuffer
。在任何情况下,如果
InputBuffer
中有任何未读数据,Connected
都将返回True
,即使底层套接字失败也是如此。您的
TThreadCon
结构不是很好。我建议重新构建它,以完全消除使用Connected
(和DJWRZORLBS()
,因为TThreadCon
没有需要泵送的消息队列)的需要。更好的设计是让线程在循环中连接,直到成功,然后在循环中发送ping,然后断开连接,并根据需要重复。试试这样的方法: