读取后输入缓冲区无法可靠清除

时间:2018-04-18 05:26:01

标签: tcpclient

我正在编写一个小型串行代理,以便我可以窃听遗留应用程序与其要控制的设备之间的对话。

我的计划是:

  1. 使用将串行数据包发送到TCP端口的虚拟串行端口拦截应用程序的命令
  2. 将这些命令中继到设备
  3. 将设备的响应中继回应用程序。
  4. 到目前为止,当我只使用我的测试命令时,它可靠地工作。但是,当我使用应用程序启动通信时,它会间歇性地失败。显然,应用程序通过线路发送“唤醒ping”以验证与设备的成功连接。 'ping'是ChrW(3)的单字节值,设备响应=>(成功)。只要在我尝试读取输入缓冲区之前输入缓冲区是清除的,这种方法就可以正常工作。

    这是间歇性的部分。有时候ChrW(3)会卡在那里,有时却不会。随后的电话就在它上面。另一方面,我的测试命令总是清除。它似乎只是关于那个低阶角色的东西。

    这是我的代码,非常简单我想:

    Private Sub TcpClient()
      Dim aData As Byte()
    
      Dim _
        sLogger,
        sDevice As String
    
      Dim _
        iBytes,
        iPort As Integer
    
      sDevice = String.Empty
      iPort = 5001
    
      Using oClient As New TcpClient("localhost", iPort)
        Using oStream As NetworkStream = oClient.GetStream()
          aData = New Byte(255) {}
    
          Console.WriteLine("Waiting...")
    
          iBytes = oStream.Read(aData, 0, aData.Length)
          sLogger = Encoding.ASCII.GetString(aData, 0, iBytes)
    
          Console.WriteLine($"Logger: {sLogger}")
    
          Using oPort = New SerialPort("COM3", 9600, Parity.None)
            oPort.Open()
            oPort.WriteLine(sLogger)
    
            Do While sDevice = String.Empty
              Threading.Thread.Sleep(1000)
              sDevice = oPort.ReadExisting
            Loop
    
            Console.WriteLine($"Device: {sDevice}")
    
            oPort.Close()
          End Using
        End Using
      End Using
    End Sub
    

    如何可靠地清除输入缓冲区?我发现有几个SO帖子正在讨论它,但没有一个能够解决我的具体问题。

1 个答案:

答案 0 :(得分:1)

它现在正在工作。

事实证明,应用程序发送了其中三个ChrW(3)'在超时之前,我的代码只拿到第一个。这使得它看起来好像输入缓冲区实际上没有被清除。这也是间歇性结果的原因。

我通过颠倒我的代码和虚拟串行端口之间的关系来发现这一点,使我的代码成为服务器,端口成为客户端。 (无论如何,这是一个更稳定的模型。)

这是更新后的代码:

Private Sub TcpListener()
  Dim oIPAddress As IPAddress
  Dim oListener As TcpListener
  Dim oClient As Socket
  Dim aData As Byte()

  Dim _
    iIndex,
    iPort,
    iSize As Integer

  Console.WriteLine("Starting TCP listener...")

  iPort = 5001
  oIPAddress = IPAddress.Parse("127.0.0.1")
  oListener = New TcpListener(oIPAddress, iPort)
  oListener.Start()

  While True
    Console.WriteLine($"Server is listening on port: {iPort}")
    Console.WriteLine("Waiting for a connection...")

    oClient = oListener.AcceptSocket()

    Console.WriteLine("Connection accepted.")
    Console.WriteLine("Ready to receive data...")

    aData = New Byte(99) {}
    iSize = oClient.Receive(aData)

    Console.WriteLine($"Data recieved @ {Now}: ")

    For iIndex = 0 To iSize - 1
      Console.Write(Convert.ToChar(aData(iIndex)))
    Next

    Console.WriteLine()
    oClient.Close()
  End While

  oListener.Stop()
End Sub