【问题标题】:TCP/IP Message FramingTCP/IP 消息成帧
【发布时间】:2012-08-14 09:49:21
【问题描述】:

我制作了一个 TCP/IP 服务器/客户端,它是异步的,但它连接了消息。如何正确地在开头添加标头,然后在结尾使用字符串生成器来取消连接完整的消息。

服务器读取消息:

  Private Sub ReadCallback(ByVal result As IAsyncResult)
    Try
        allDone.Set()
        Dim success As Boolean = result.AsyncWaitHandle.WaitOne(500, True)
        If success Then
            Dim client As ServerClient = TryCast(result.AsyncState, ServerClient)
            If client Is Nothing Then
                Return
            End If
            Dim networkStream As NetworkStream = client.NetworkStream
            Dim read As Integer = networkStream.EndRead(result)
            If read = 0 Then
                SyncLock Me.Clients
                    Me.Clients.Remove(client.ClientID)
                    Return
                End SyncLock
            End If
            If client.NetworkStream.CanRead Then

                dataString.Append(Me.Encoding.GetString(client.buffer, 0, read))

                networkStream.BeginRead(client.buffer, 0, client.buffer.Length, AddressOf ReadCallback, client)
                allDone.WaitOne(500, True)
            End If
        End If
    Catch ex As IO.IOException
        Dim client As ServerClient = TryCast(result.AsyncState, ServerClient)
        SyncLock Me.Clients
            Me.Clients.Remove(client.ClientID)
            Return
        End SyncLock
    Catch ex As Exception
        If Not Me.tcpListener.Server.Connected Then
            Return
        End If
    End Try
End Sub

客户端写消息:

    Public Function Write(value As String, encoding As Encoding) As Guid
    Dim buffer As Byte() = encoding.GetBytes(value)
    Return Me.Write(buffer)
End Function

Public Function Write(buffer As Byte()) As Guid
    Dim guid__1 As Guid = Guid.NewGuid()
    Dim networkStream As NetworkStream = Me.client.GetStream()
    Dim result As IAsyncResult = networkStream.BeginWrite(buffer, 0, buffer.Length, Nothing, guid__1)


    result.AsyncWaitHandle.WaitOne()
    networkStream.EndWrite(result)
    Return guid__1
End Function

【问题讨论】:

  • 在当前代码中需要注意的一点是:不能保证(除非你使用 ASCII/代码页)你得到了一个完整的字符......你可以有一半的字符。
  • 好吧,我解决这个问题的一种方法是在消息的末尾使用一个特殊字符,以便读者(服务器/客户端)可以继续阅读,直到他得到那个字符。可以在将字节转换为字符串的位置检查此字符是否存在。

标签: c# vb.net sockets networking tcp


【解决方案1】:

您需要在 TCP/IP 之上定义一个(可能很简单)协议,以便让您知道一条消息在哪里开始和结束。 TCP/IP 可以并且将会对您发送的消息进行分段,以便接收者可以获得消息的一部分、整个消息或多条消息。一个简单的方法是写一个消息长度,然后是消息。然后接收者读入一个字节缓冲区,一旦接收到适当数量的字节(基于发送的长度),就可以提取消息并将其编码成一个字符串。

【讨论】:

猜你喜欢
  • 2015-03-28
  • 2012-10-09
  • 2016-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多