IdTcpClient 的 IOHandler.ReadLn 解决方案上的连接正常关闭

问题描述 投票:0回答:1

我有一个小问题,当连接到服务器 TIdTcpClient 时,在

FConn.IOHandler.ReadLn
procedure TReadingThread.Execute;
上生成“连接正常关闭”错误,这种情况不会一直发生,只是一些,如果一次又一次尝试,则不会发生,也不会发生在服务器运行的另一个 VPS 上。但没关系。

我做了一些更改来解决该错误,如果发生错误,它基本上会断开连接,终止线程并重试。我的问题是,我所做的可能会导致一些问题或工作正常吗?在解决的测试中,它失败了 8 次,尝试 9 次后才连接。

我做了什么:

procedure TReadingThread.Execute;
var
  Recebeu   : String;
begin
  while not Terminated do
  begin
    try
      Recebeu := FConn.IOHandler.ReadLn;
    except
      on E: Exception do
      begin
        THD.Terminate;

        FConn.IOHandler.InputBuffer.Clear;
        FConn.Disconnect(False);

        if rt <> nil then rt.Terminate;

        THD := TThreadCon.Create;
        THD.Start;
      end;
    end;

    if not Recebeu.IsEmpty then
    begin

总谐波失真为

THD : TThreadCon = nil

procedure TThreadCon.Execute;
var
  Attempt : Integer;
begin
  Attempt   := 0;

  try
    while not Terminated do
    begin
      if TCPClient.IOHandler <> nil then TCPClient.IOHandler.InputBuffer.Clear;

      try
        Inc(Attempt);

        TCPClient.Connect;

        try
          TCPClient.IOHandler.WriteLn('Connect');
        except
          TCPClient.Disconnect(False);
          raise;
        end;
      except
        on E: Exception do
        begin
          if (Attempt >= 3) then
          begin
            THD.Terminate;
          end;

          if FTermEvent.WaitFor(2500) <> wrTimeout then Exit;
          Continue;
        end;
      end;

      rt := TReadingThread.Create(TCPClient);
      try
        try
          while not Terminated do
          begin
            if FTermEvent.WaitFor(5000) <> wrTimeout then Exit;
          end;
        except
        end;
      finally
        rt.Terminate;
        try
          TCPClient.Disconnect(False);
        finally
          rt.WaitFor;
          rt.Free;
        end;
      end;
    end;
  finally
    TCPClient.Free;
  end;
end;

正如我所见,由于我在执行时声明并设置尝试,它永远不会在

if (Attempt >= 3) then
上触发
on E: Exception do
,但没关系。

仅当服务器关闭连接时才会发生“连接正常关闭”错误?

tcpclient indy tcpserver
1个回答
0
投票

“连接正常关闭”意味着连接被远程对等方有意关闭,通常服务器是的,但如果客户端和服务器之间的防火墙/路由器由于不活动等原因关闭了连接,也可能会发生这种情况。

该错误在客户端是正常的,你的解决方案基本正确——关闭连接并重新连接。

尽管如此,我确实质疑为什么你要在单独的线程中调用

Connect()
ReadLn()
,为什么不在单个线程中调用呢?有一个调用
Connect()
WriteLn()
的外循环,然后是调用
ReadLn()
的内循环,例如:

procedure TThreadCon.Execute;
var
  Attempt : Integer;
  Recebeu : String;
begin
  Attempt := 0;

  try
    while (not Terminated) and (FTermEvent.WaitFor(0) = wrTimeout) do
    begin
      if TCPClient.IOHandler <> nil then
        TCPClient.IOHandler.InputBuffer.Clear;

      try
        Inc(Attempt);

        TCPClient.Connect;

        try
          TCPClient.IOHandler.WriteLn('Connect');
        except
          TCPClient.Disconnect(False);
          raise;
        end;
      except
        on E: Exception do
        begin
          if (Attempt >= 3) then Terminate;
          if FTermEvent.WaitFor(2500) = wrSignaled then Exit;
          Continue;
        end;
      end;

      try
        while (not Terminated) and (FTermEvent.WaitFor(0) = wrTimeout) do
        begin
          try
            Recebeu := TCPClient.IOHandler.ReadLn(LF, 5000);
            if (not TCPClient.IOHandler.ReadLnTimedOut) and (Recebeu <> '') then
            begin
              ...
            end;
          except
            on E: Exception do
            begin
              ...
            end;
          end;
        end;
      finally
        TCPClient.Disconnect(False);
        Attempt := 0;
      end;
    end;
  finally
    TCPClient.Free;
  end;
end;
© www.soinside.com 2019 - 2024. All rights reserved.