【问题标题】:How can I listening "controller board" with indy 10 tcpip?如何使用 indy 10 tcpip 收听“控制器板”?
【发布时间】:2020-01-29 05:14:26
【问题描述】:

我在 Visual Basic 中有一个代码,它有一个计时器并监听一个 tcpip 流。我正在尝试在 deplhi 中对其进行编码,但我遇到了问题。

我通过 tcpip 在板上连接成功,如下所示:IdTCPClient1.Connect;

板子tcpip是192.168.0.180,端口2000,我的服务器是192.168.0.30。

我正在尝试这段代码:

procedure TForm1.Button8Click(Sender: TObject);
var StrStream: TMemoryStream;
begin

  if IdTCPClient1.Connected then
    begin
      StrStream := TMemoryStream.Create;
      if IdTCPClient1.IOHandler.Connected then
        IdTCPClient1.IOHandler.ReadStream(StrStream,-1,false);

      Memo1.Lines.Add('hello');
    end;

end;

问题是,在行 IdTCPClient1.IOHandler.ReadStream(StrStream,-1,false);应用程序停止,没有错误,没有消息,我不明白。

VB 代码

    Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick

        Try

            If tcp1.Available > 1 Then
                Dim leitura As NetworkStream = tcp1.GetStream
                Dim bytes(tcp1.ReceiveBufferSize) As Byte
                leitura.Read(bytes, 0, CInt(tcp1.ReceiveBufferSize))
                returndata = Encoding.ASCII.GetString(bytes)
                txtSerial1.AppendText(returndata)

            End If

            If tcp2.Available > 1 Then
                Dim leitura As NetworkStream = tcp2.GetStream
                Dim bytes(tcp2.ReceiveBufferSize) As Byte
                leitura.Read(bytes, 0, CInt(tcp2.ReceiveBufferSize))
                returndata = Encoding.ASCII.GetString(bytes)
                txtSerial2.AppendText(returndata)
            End If


        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Sub

【问题讨论】:

    标签: tcp indy10 delphi-10.1-berlin


    【解决方案1】:

    当调用 IOHandler 的 ReadStream() 方法时,设置 AByteCount=-1AReadUntilDisconnect=False 告诉 ReadStream() 期望传入的数据前面有一个多字节整数(4 或 8 字节,具体取决于IOHandler 的LargeStream 属性),它指定数据中后续字节的数量,然后它等待那么多字节实际到达。服务器的数据实际上是这样的吗?我对此表示怀疑,因为这不是您的 VB 代码所期望的。

    将 IOHandler 的 ReadBytes() 方法与 AByteCount=-1 一起使用将比使用 ReadStream() 方法更接近于您的 VB 代码,例如:

    procedure TForm1.Button8Click(Sender: TObject);
    var
      Bytes: TIdBytes;
    begin
      if IdTCPClient1.Connected then
      begin
        IdTCPClient1.IOHandler.ReadBytes(Bytes, -1);
        // use Bytes as needed...
        Memo1.Lines.Add('hello');
      end;
    end;
    

    另外,请记住 Indy 默认使用阻塞套接字 I/O。你真的不应该在主 UI 线程中执行阻塞操作。您应该将阅读逻辑移至单独的工作线程。或者,至少,确保在TIdTCPClient 上设置一个小的ReadTimeout,这样ReadBytes() 就不会长时间阻塞用户界面。

    【讨论】:

      猜你喜欢
      • 2016-09-12
      • 1970-01-01
      • 1970-01-01
      • 2020-01-19
      • 1970-01-01
      • 1970-01-01
      • 2021-03-02
      • 2014-07-14
      • 1970-01-01
      相关资源
      最近更新 更多