2012-08-14 57 views
3

我已經做了一個TCP/IP服務器/客戶端,它的異步,但它連接消息。如何正確地開始在開始處添加標題,然後在末尾使用字符串生成器來解除完整消息的連接。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 
+1

在當前代碼中要注意一件特別的事情:沒有保證(除非你使用ASCII /代碼頁),你得到了一個完整的角色......你可以擁有一半角色。 – 2012-08-14 10:00:19

+0

好吧,我解決這個問題的一個方法是在郵件末尾使用特殊字符,以便讀者(服務器/客戶端)可以繼續閱讀,直到他獲得該字符。該字符存在可以檢查將字節轉換爲字符串的位置。 – ray 2012-08-14 10:26:57

回答

5

您需要定義在TCP/IP之上的(可能是薄和簡單的)協議,以允許你知道一條消息從哪裏開始和結束。 TCP/IP可以並將分段您發送的消息,以便接收者可以獲得消息的一部分,整個消息或多條消息。一個簡單的方法是寫一個消息長度,然後是消息。然後接收器讀入一個字節緩衝區,一旦接收到適當數量的字節(基於發送的長度),消息就可以被拉出並編碼成一個字符串。

+0

很好的答案。一些更多的信息在這裏:http://www.codeproject.com/Articles/37496/TCP-IP-Protocol-Design-Message-Framing – plang 2012-11-08 09:48:41