2012-08-01 49 views
0

即時通訊新的套接字,我在網上創建一個tictactoe,我知道如何建立與客戶端和服務器的連接,但我也會聊天。C#最好的方式來區分套接字消息

然後我這樣做,當用戶聊天時,我發送帶有前綴「CHAT:HELLO WORLD」 的消息,並且當用戶發起移動時,我發送消息時不帶前綴...這是最好的方式嗎?

THX !!!

+1

你總是可以使用兩個套接字。 – Littlegator 2012-08-01 19:19:33

回答

2

在通過像TCP的基於流的協議限定了線協議,則有用於構造消息的幾個選項:

  • 固定長度
    • 所有消息都是相同的長度;每個x字節的序列代表一個新的消息。
  • 長度前綴(可變長度)
    • 消息的第一個字節(一個或多個)表示有效負載跟隨的長度。
  • 字符串終止(可變長度)
    • 閱讀來自該流的字節,直到出現一個表示消息的結束的特定字節串,即換行符\n

如果你打算在改變協議(普羅蒂普:你會的,即使你不認爲你會),這是至關重要的,你包括協議版本每封郵件中的標識符使用協議的舊版迭代來處理客戶時防止出現問題。顯然,這是在解密剩餘有效負載之前首先必須確定的,因此這應該是消息的第一個字節(在任何長度前綴之後) - 如果我們不這樣做,我們如何確定版本知道我們收到的每條消息的位置在

1

需要定義一個協議。請記住爲更多功能提供空間:-)。

例如,使用過完整線(端與選定行終止子)的正則表達式:

  • 匹配^:[a-c][1-3]::是移動(結腸,位置,結腸用戶名)。
  • 匹配^!.*?::是一個聊天消息(感嘆號,名稱,冒號,文字)。

和其他任何東西(在V1中)是錯誤的。

記住:

  • 數據在數據包中發送,您可能需要從套接字多次讀取,以獲得完整的信息。
  • 避免含糊不清:解決它可能是x或y很難。
  • 指定文本編碼(例如UTF-8)。
3

通常,您將使用包含數據包長度,類型和有效負載的格式。

在你的情況你可以用字節(類型),Int16(長度),字節[](有效載荷)去。

該類型可以用代碼表示爲enum。長度將僅表示有效負載的長度。

public enum Byte PacketType { 
    PlayerMove = 1, 
    PlayerChat = 2 
} 
0

我假設你使用的是TCP?

您需要確保將兩個消息「框起來」,以便您可以識別它們並避免潛在的阻塞問題(如果客戶端在您仍然期望讀取CHAT時停止發送或您定義的任何內容)。使用TCP,你的字節順序是有保證的,但是讀取並不能保證一個完整的'數據包',所以你需要實現一些建立緩衝區和識別你的'消息'完成的方式。

這樣做的一個合理簡單的方法是確保每個'消息'有一個指定類型和大小的頭。

EG:

枚舉您的消息類型(移動,目前聊天),所以說「聊天」爲0x01,你的消息是1020個字節。你可以用0x0103FC作爲你的'消息'的前綴,這樣服務器就知道有多少字節可以預期,並且使用異步套接字調用來建立一個緩衝區,直到讀取1020字節(或者你隨意決定客戶端不再發送)

相關問題