簡體   English   中英

通過UDP winsock連接發送結構,結構的大小?

[英]Sending structs over a UDP winsock connection, size of struct?

我會盡量保持這個簡短。 所以我正在制作一個網絡界面,其本身將用於創建簡單的視頻游戲。 我最初開始在TCP中設計它,但我發現它太慢,所以我切換到UDP。

我目前的想法是:我想發送結構,每個結構對應一個特定的消息。 當然,我需要知道服務器或客戶端收到它時的結構大小。 我通過首先發送一個標准化的結構來解決這個問題,該結構包含下一個結構的類型,然后相應地處理它。 所以我會在客戶端和服務器之間有類似共享的頭文件,如下所示:

enum data_type { PLAYER_MESSAGE, PLAYER_LOCATION};

struct enum_type {
int nClientID;
data_type data_identifier;
};

struct player_message {
char message[128];
};

struct player_location {
int x, y;
};

然后,在接收其他客戶端發送的數據的函數中,我會做這樣的事情:

enum_type enum_check;
recvfrom(socket, (char*)&enum_check, sizeof(enum_type), 0, (struct sockaddr*)&client, &client_length);

switch(enum_check.data_identifier)
{

    case: PLAYER_MESSAGE
    player_message temp_message;
    recvfrom(socket, (char*)&temp_message, sizeof(player_message), 0, (struct sockaddr*)&client, client_length);
    //Print message
    break;

    case: PLAYER_LOCATION
    player_location temp_location;
    recvfrom(socket, (char*)&temp_location, sizeof(player_location), 0, (struct sockaddr*)&client, &client_length);
    //move player
    break;
}

該系統可以很好地處理所有類型的消息,並且在(某些)壓力下表現得相當不錯。 問題當然是每個客戶端都會使用相同的recvfrom來首先檢查消息類型然后相應地處理它。 簡而言之,我不相信這個系統,因為它做了太多的假設。 它假設給出消息類型的接收始終跟隨正確的消息。 使用UDP,你永遠無法保證這種情況,這讓我感到難過。 (我也意識到使用這種方法的字節序和計算機體系結構的問題,但我現在正在為此做好准備。)

我認為快速簡單的方法是只有一種類型的結構,包括客戶端ID,如何使用其數據(枚舉),大約10個數字的空間以及一些文本。 這樣我就不必做出假設,但當然會不斷地發送大量不必要的數據(如果帶寬不是真正的問題,這不會是一個問題,但它似乎是一個非常愚蠢的解決方案)。

這里有什么建議? 我打算只使用像ENET這樣的網絡庫(那么再次,我不會在嘗試發送結構時遇到同樣的問題嗎?)但這似乎是一種失敗。 畢竟我只是這樣學習。

你已經接到UDP的好東西有時會以任意方式重新排序消息。

總是發送包含所有可能信息的相同結構的解決方案幾乎是正確的:

定義自己的基本消息,例如:

struct msg_common{uint8_t sender, receiver; uint16_t message_id;};
// Take note that I used fixed-width types here!

並使所有特定消息以此開頭,為每個消息保留公共前綴的非重疊范圍。

您無法驗證消息是否有效,這意味着:

  • 它完整​​,又名。 UDP數據包包含整個消息。
  • 它應該現在處理,也就是說。 之前沒有必須先處理的消息。
    • 要么包括重建先前未確認消息所需的所有數據。
    • 或者接受丟棄任意數量的消息。
    • 或者允許請求重新發送。
  • 它不違反游戲的其他語義限制。

為什么不使用結構的聯合,第一個成員給出結構的類型,並且對於聯合中的所有結構是通用的。 您的快速簡便方法並不遙遠,因為如果您只擁有10個數字,那么數據包的標頭無論如何都會主導您的帶寬使用。 你真的不希望一個數據包檢查下一個類型 - 這就是在UDP中要求麻煩,不能保證數據包按照它們發送的順序到達。

我最初開始在TCP中設計它,但我發現它太慢,所以我切換到UDP。

我建議你在得出這樣的結論之前先閱讀這篇文章: udp-vs-tcp- how-much-fast-is-it 在大多數情況下,TCP相當不錯。 我的基於TCP的服務器在入門級別的ie i7上使用雙網卡運行乒乓測試,並且延遲非常快,我每秒獲得400K數據包。

你需要多快?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM