簡體   English   中英

通過互聯網發送布爾值(Windows和Linux)

[英]Sending booleans over the internet (Windows & Linux)

我正在從我的服務器向客戶端發送信息,然后使用打包的結構再次返回(顯然結構中有更多的數據)

#pragma pack(push, 1)

struct other_data_struct
{
int hp;
int wp;
char movetype;
}

struct PlayerStats
{
int playerID;
other_data_struct data;
bool friendly;    //<-this one messes up how the others are going to be packed on the 2 systems
}
#pragma pack(pop)

這適用於所有固定大小的變量,整數和字符甚至其他結構。

雖然使用gcc for Linux編譯服務器並且客戶端使用MSVC for windows編譯時布爾值不能正常工作...

我曾想過制作某種容器(即帶有8個布爾get / set函數或類似函數的unsigned char),但它看起來像古怪的那樣古怪。

有沒有辦法在Windows和Linux上'包裝'包含布爾變量的結構完全相同,或者我應該咬酸蘋果並為每個布爾值使用char?

您可以使用Google Protocol Buffers而不是您自己的打包結構。 或者你可以避免bool以避免不兼容。

如果我真的必須從你所在的位置開始並使它工作,我會用它中的結構制作一個小程序並開始嘗試其他填充字段,直到我想出兩個系統上看起來完全相同的東西。

無論何時在不同系統之間傳輸數據,都不應該依賴這些系統如何表示內存中的數據,因為內存表示可能因處理器體系結構,編譯器選項和許多其他因素而異。 您應該使用一些庫進行序列化,因為該庫的作者已經將許多想法放入了您可能不感興趣的各種問題中。

在一般情況下,你不應該對endianess,字段大小,結構包裝等做出假設。對於一般應用或庫開發,做這種事情是不好的做法。

也就是說,我在嵌入式系統上經常做這種事情,其中​​1)內存(RAM和可執行ROM)是一種寶貴的資源,因此需要避免不必要的庫2)我知道我的代碼只針對一個平台,3)不想打包/拆包的性能。 即便如此,它可能不是一個“最佳”的做法。

如果你意識到以這種方式做事的風險,我想你自己回答了這個問題。 如果您想100%確定,請為布爾值定義自己的類型。 也提防的尺寸long的32位和64位平台之間不同。 我通常堅持使用每個數字原語的“stdint.h”類型,這樣你就知道你正在處理的是什么大小。

你為什么不在調用ntohl,htonl,ntohs,htons等時進行序列化。這樣可以很好地轉換endian-ness,它比你正在做的更安全一些。 如果你使用結構,那么你需要更多地擔心編譯器相關的東西,而不是你使用已知大小的核心類型。

這些函數以網絡字節順序放置數據,這是通信設備之間網絡傳輸的標准。 其他網絡程序員也會更好地理解您的代碼以便維護:)

您可以嘗試使用bitfields ,這樣您的壓縮結構包含'int',但您的代碼使用更節省空間的表示。

我相信位域有一些可怕的性能特征,所以如果你更關心訪問時間而不是空間使用,它們可能不是你要走的路。

我不清楚問題會是什么。 Windows和Linux都將bool定義為單字節對象。

Windows 確實BOOL定義為int ,所以如果你把BOOL放在線上並將其作為bool讀取(或者將bool放在線上並將其作為BOOL讀取)那么你就會遇到麻煩。 這相對容易修復。

可能是Windows和Linux為falsetrue定義了不同的值(更可能的是,他們同意false0 ,但不同意true的值;即使在網絡編程之外,也可能有bool變量不是truefalse ,見下文)。 標准要求bool至少為一個字節,並且一個字節具有遠遠超過兩個可能的值。

是的,你的轉換bool s到unsigned char S和發送超過該線將正常工作。


注意 :“ bool變量不是truefalse ”:

// obviously this code won't show up in anybody's code base
char a = 'a';
bool b = *reinterpret_cast<bool*>(&a);
switch (b) {
    case true:
       std::printf("true\n");
       break;
    case false:
       std::printf("false\n");
       break;
    default:
       std::printf("huh?\n");
       break;
 }

暫無
暫無

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

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