delphi 在IdTcpClient上的IOlog.ReadLn解决方案上正常关闭连接

p5fdfcr1  于 9个月前  发布在  其他
关注(0)|答案(1)|浏览(126)

我有一个小问题,当连接到服务器TIdTcpClient生成“连接优雅地关闭”错误procedure TReadingThread.Execute;FConn.IOHandler.ReadLn,这不会发生所有的时间,只是一些,如果尝试一次又一次,它不会发生,也不会发生在另一个VPS服务器运行。
我做了一些改变谁的工作arount错误,如果错误发生它基本上断开连接,终止线程,再试一次。我的问题是,我做了什么可以导致一些问题或工程罚款?在测试解决,它失败了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为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;


正如我所看到的,由于我声明并设置执行尝试,它永远不会在on E: Exception do上触发if (Attempt >= 3) then,但这是可以的。
仅当服务器关闭连接时才会发生Connection Closed Gracefully错误?

ru9i0ody

ru9i0ody1#

“Connection Closed Gracefully”意味着连接被远程对等端故意关闭,* 通常 * 是服务器,但也可能发生在客户端和服务器之间的防火墙/路由器由于不活动而关闭连接等情况下。
错误在客户端是正常的,您的解决方案基本正确-关闭连接并重新连接。
虽然,我确实质疑为什么你在单独的线程中调用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;

字符串

相关问题