.NET TcpClient / TcpListener只接收第一条消息

时间:2014-06-10 18:26:44

标签: .net vb.net tcpclient tcplistener

我有一个使用TCP发送/接收消息的简单程序。由于某种原因,它收到第一条消息,但除非我关闭并重新连接客户端,否则服务器不会从该客户端收到第一条消息。我正在提供下面代码的精简版本(所以请原谅缺乏异常处理)。

Private TCPWriter As TcpClient
Private TCPListener As TcpListener

Private Sub Send(sender As Object, e As RoutedEventArgs)
    Connect()
    WriteTextToServer(MessageBox.Text)
End Sub

Private Sub Connect()
    If TCPWriter Is Nothing Then
        TCPWriter = New TcpClient
    End If

    If Not TCPWriter.Connected Then
        TCPWriter.Connect(System.Net.IPAddress.Parse(IPBox.Text), PortBox.Text)
        TCPWriter.NoDelay = True
    End If
End Sub

Private Sub WriteTextToServer(inMsg As String)
    Dim data() As Byte = Encoding.ASCII.GetBytes(inMsg + vbCrLf)
    Dim ns As NetworkStream = TCPWriter.GetStream()

    If ns.CanWrite Then
        ns.Write(inMsg, 0, inMsg.Length - 1)
    End If
End Sub

Private Sub ReadNewDataFromClient(ByVal inStatus As IAsyncResult)
    Dim clientSocket As TcpClient
    Dim datalen As Integer
    Dim buf() As Byte
    Dim message As String

    clientSocket = CType(inStatus.AsyncState, TcpListener).EndAcceptTcpClient(inStatus)
    clientSocket.ReceiveTimeout = 5000

    datalen = clientSocket.Available
    If datalen > 0 Then
        'get all data at once ...
        buf = New Byte(datalen - 1) {}
        clientSocket.GetStream().Read(buf, 0, buf.Length)

        message = Encoding.ASCII.GetString(buf, 0, buf.Count - 2)
        Me.Dispatcher.Invoke(Sub() ReadNewDataFromClients.Add(ReadNewDataFromClients.Count.ToString + ": " + message))
    End If

    TCPListener.BeginAcceptTcpClient(New AsyncCallback(AddressOf ReadNewDataFromClient), Nothing)
End Sub

如果我将Connect()方法更改为以下代码,它将起作用,但似乎不是正确的方法。

Private Sub Connect()
    If TCPWriter IsNot Nothing Then
        TCPWriter.close
        TCPWriter = nothing
        Threading.Thread.Sleep(1000)
    End If

    TCPWriter = New TcpClient

    If Not TCPWriter.Connected Then
        TCPWriter.Connect(System.Net.IPAddress.Parse(IPBox.Text), PortBox.Text)
        TCPWriter.NoDelay = True
    End If
End Sub

我做错了什么?

1 个答案:

答案 0 :(得分:0)

您正在使用BeginAcceptTcpClient接收下一个“消息”,这用于接受新连接(这就是为什么当您断开/重新连接每条消息时它的工作原理)。您应该使用Read / BeginRead来阅读下一条消息。

话虽如此,您还需要了解TCP是一个协议,因此,它没有“消息”的概念,也许最重要的是,它之间没有可靠的对应关系。发送方对Write的呼叫次数以及接收方读取所发送数据所需的Read呼叫次数。

如果要将TCP用于离散消息,则需要发送数据,以便将其拆分回接收端的各个消息中。这通常是通过在消息前面加上固定大小的长度指示符(例如4个字节)来“成帧”消息来完成的。

您还需要确保观察Read方法的返回值,该方法将指示实际读入缓冲区的字节数。