代码之家  ›  专栏  ›  技术社区  ›  Tarnschaf

为什么我在Indy Sockets 9 IdTcpServer ServerExecute中遇到访问冲突?

  •  0
  • Tarnschaf  · 技术社区  · 15 年前

    第一个问题:

    以下例程是否是Indy 9 IdTcpServer.OneExecute例程的正确实现?

    procedure TMyConnServer.ServerExecute(AContext: TIdPeerThread);
    var
      buffSize: integer;
      str:      string;
    begin
      AContext.Connection.ReadFromStack(True, 600, False);
      buffSize := AContext.Connection.InputBuffer.Size;
      if (buffSize > 0) then
        { Extract input buffer as string }
        str := AContext.Connection.ReadString(buffSize);
    
        { Notify connection object of received data }
        if (AContext.Data <> nil) then
        begin
          TConnectionHandler(AContext.Data).Read(str);
        end;
      end;
    end;
    

    第二个(实际上更重要)问题:

    现在偶尔会出现访问冲突(从地址000000读取)。显然是这样的:

      AContext.Connection.ReadFromStack(True, 600, False);
    

    调用之后(以及引发异常之后),IOHandler为nil。

    我们正在使用RAD Studio/Delphi 2007。

    3 回复  |  直到 15 年前
        1
  •  0
  •   Roddy    15 年前

    嗯,我有一个最简单的执行处理器是这样的。(借口C++代替Delphi,但你会明白这个想法。

    void __fastcall MyPanel::DoTCPExecute(TIdPeerThread * AThread)
    {
      AnsiString text =AThread->Connection->ReadLn();
      // now do something with text
    }
    

    你需要用其他方式来“划界”你的字符串。Readln使用换行符作为终止符-另一种方法是在每个数据块前面加上长度字段。读取长度,然后读取剩余数据。

        2
  •  0
  •   Tarnschaf    15 年前

    代码是这样工作的,但我认为它不是一个干净的选项:

      if (AContext.Connection.Connected) then
      begin
        try
          AContext.Connection.ReadFromStack(false, 1, false);
        except on E: EAccessViolation do
          // ignore
        end;
      end; 
      buffSize := AContext.Connection.InputBuffer.Size;
    
        3
  •  0
  •   Remy Lebeau    15 年前

    IOHandler变为nil的唯一方法是,如果应用程序中的另一个线程在连接上调用Disconnect(),而您的工作线程仍在运行。