1

したがって、ここではバイト配列に基づいてshorts / longsを作成しており、memcpyバイトを独自の変数にコピーして、その変数をsockaddr_inオブジェクトに割り当てることは避けたかったのです。

short次のステートメントでを抽出するためのより良い方法はありますか?:

((sockaddr_in*)from)->sin_port = (*((unsigned short*)&buf[4]));

私のロジックが正しければ、(unsigned short)buf[4]キャストだけを実行すると1バイトしか変換されないため、ポインター/逆参照のすべてを実行しました。両方ではありません。

編集:エンディアンは問題ありません。を使用する以外に、buf[4]とbuf[5]を1つの短い方法で簡単にまとめたいだけですmemcpy

4

3 に答える 3

2

あなたの質問のコード:

(*((unsigned short*)&buf[4]))

次の問題により、機能しない場合があります。

memcpyエンディアンに自信がある場合は安全です(そうでない場合は、ntohsまたはと組み合わせる必要がありますntohl)。まともなコンパイラもそれを最適化する必要があります。

本当に避けたい場合はmemcpy、プラットフォームに依存しない安全な方法は次のようになります(buf標準のネットワークバイトオーダーを使用して、元々外部ソースから入力されたと仮定します)。

((buf[n] << 8) | buf[n+1])

もちろん、それを関数(または必要に応じてマクロ)でラップする必要があります。

于 2012-05-16T23:43:29.687 に答える
1

ntohs適切な解決策は、すべての状況で、 and htons(for longuse ntohland )などの関数を使用することだと思いますhtonl

((sockaddr_in*)from)->sin_port = htons(*((unsigned short*)&buf[4]));

また、バイト配列のソースによっては、追加のエンディアンの問題が発生する可能性があることにも注意してください。

一部のアーキテクチャ(HP-RISC、SPARC)では、アライメントが別の問題になる可能性があります。機能memcpymemmove通常これらの問題はありません。そして、時期尚早に最適化するべきではありません!

于 2012-05-16T23:47:46.680 に答える
0

ntohsマクロを使用してエンディアン変換を処理できます。htonsはホストからネットワークへの順序を意味します

((sockaddr_in*)from)->sin_port = htons(*((uint16_t*)&buf[4]));

ただし、一部のアーキテクチャでは非整列アクセスが許可されていないため、整列されていることを確認する必要があります。そうでない場合は、整列されたバイトを一時変数にフェッチし、それに応じてビットをシャッフルする必要があります。

于 2012-05-16T23:52:47.350 に答える