2017-08-13 3 views
0

私はワイヤを通して送信しようとしているバッファにuint32_tを書き込むように設定しようとしていますが、正しく行う方法がわかりません。当初、私はoperator<<が正しく処理し、4バイトをバッファに書き込むと仮定しました(前にhtonlを使用したと仮定して)。代わりに、私は意味をなさない値を取得し始めました。ストリームに1つのintを書き込むと、バッファのサイズが期待される4バイトの代わりに最大10バイト増加することがありました。私は簡単なテストを書いて、それが実際にバッファにasciiで整数をダンプしていることに気付きました。私はそれの周りの道を考え出したと思うが、それはハッキーだから、私はより良い方法を探していますか、または私がやっていることが実際に正しい理由について正当性を探しています。uin32_tをasio :: streambufに書き込む

Here'ssomeのサンプルコード:

boost::asio::streambuf buffer; 
    std::ostream os(&buffer); 

    uint32_t value = 0x12345678; 
    os << value; // Gives ascii 305419896 

    os.write((const char *) &value, sizeof(value)); // fives 0x12345678 

はコードの私の最後の行よりも、これを行うには良い方法はありますか?何をやっている

+1

intは、ローカルマシンのネイティブエンディアン(リトル/ビッグ)を使用してパックされますことを、あまりにも忘れないでください...それは確実にするために最善であるかもしれません将来の互換性を確保するために、 'htonl'と' ntohl'などのネットワークエンディアンを使用してください。とにかくこれを実行する最善の方法はAFAIKです。より多くのフィールドがある場合は、パックされた構造体を作成し、構造体全体を一度にストリームに書き込むことが最善の方法です。 – Geoffrey

+0

私はhtonlを使っていたと言いました。これは特に私がパック構造体を使用することはできませんが、私はすぐに将来使用することを知っている良い考えです。 – Braaedy

+0

申し訳ありませんが、私はその部分を逃しました。考慮する必要があるもう一つの点は、帯域幅を節約するためにランレングス符号化を行うことです。要件に応じて異なります。 – Geoffrey

答えて

1

は大丈夫ですが、それは直接ストリームバッファへの書き込みすることも可能である

buffer.commit(boost::asio::buffer_copy(
    buffer.prepare(sizeof(value)), 
    boost::asio::buffer(&value, sizeof(value)))); 
0

これはそれを行うための通常の方法です。間に小さなコードを追加すると、時間とコードを節約できます。

template<class T> void append(T value) 
{ 
    static_assert(std::is_fundamental<T>::value, __FUNCTION__); 
    //Convert here to correct endian 
    append(reinterpret_cast<const char*>(&value), sizeof(value)); 
} 

template<class T> void append(const T *app, std::size_t size) 
{ 
    return append(reinterpret_cast<const char*>(app), size); 
} 

void append(const char *s, std::size_t length) 
{ 
    //append to buffer 
} 

データを受け取った時点で正しいエンディアンに変換することを忘れないでください。リモートマシンが何を期待しているかを知っていれば、正しい形式で直接送信してください。

また、あなたは、このようなエンディアンのためチェックできます

static bool IsBigEndian(void) 
{ 
    union 
    { 
     uint32_t i; 
     char c[4]; 
    } endi = { 0x01020304 }; 
    return endi.c[0] == 1; 
} 
+0

コンパイル時にすでに知っているので、実行時にエンディアンをチェックするのは冗長です。 –

+0

私はこれを知っています。これは、あなたが答えから読むことができるように、示唆です。 – Blacktempel