これには大まかに何かがあることを私は知っています。しかし、私の脳は痛く、私はこの仕事をするために何も見つけることができません...
UNIXソケットを介して16ビットの符号なし整数を送信しようとしています。そのためには、uint16_tを2つの文字に変換する必要があります。次に、接続のもう一方の端でそれらを読み込み、いずれかに変換し直す必要があります。 unsigned intまたはuint16_t、その時点では、2バイトまたは4バイトのどちらを使用するかは問題ではありません(64ビットを実行しているため、unsignedintを使用できません:)
私はCでこれをやっています
ありがとう
マスクとシフトでバイトに分割してみませんか?
uint16_t value = 12345;
char lo = value & 0xFF;
char hi = value >> 8;
(編集)
もう一方の端では、逆に組み立てます。
uint16_t value = lo | uint16_t(hi) << 8;
頭のてっぺんから、そのキャストが必要かどうかわからない。
char* pUint16 = (char*)&u16;
つまり、uint16_tのアドレスをキャストします。
char c16[2];
uint16_t ui16 = 0xdead;
memcpy( c16, ui16, 2 );
c16には、u16の2バイトが含まれるようになりました。遠端では、単にプロセスを逆にすることができます。
char* pC16 = /*blah*/
uint16_t ui16;
memcpy( &ui16, pC16, 2 );
興味深いことに、memcpyの呼び出しがありますが、サイズが固定されているため、ほぼすべてのコンパイラがそれを最適化します。
Steven sudtが指摘しているように、ビッグエンディアンに問題が発生する可能性があります。これを回避するには、htons(Host-to-network short)関数を使用できます。
uint16_t ui16correct = htons( 0xdead );
遠端ではntohs(ネットワークからホストへのショート)を使用します
uint16_t ui16correct = ntohs( ui16 );
リトルエンディアンのマシンでは、これによりショートがビッグエンディアンに変換され、遠端でビッグエンディアンから変換されます。ビッグエンディアンマシンでは、2つの機能は何もしません。
もちろん、ネットワーク上の両方のマシンのアーキテクチャが同じエンディアンを使用していることをknowしている場合は、この手順を回避できます。
32ビット整数を処理するためにntohlとhtonlを検索します。ほとんどのプラットフォームは、64ビットのntohllとhtonllもサポートしています。
ビットマスクおよびシフト演算子 を使用する必要があるようです。
16ビットの数値を2つの8ビットの数値に分割するには:
次に、これら2つの文字を接続を介して送信するときは、逆の操作を行います。以前は上位8ビットであったものを8ビット左にシフトし、ビット単位のORを使用して結合します。他の8ビットで。
基本的に、ソケットを介して2バイトを送信します。エンディアン、符号などに関係なく、ソケットが知る必要があるのはそれだけです... uint16を2バイトに分解し、ソケットを介して送信します。
char byte0 = u16 & 0xFF;
char byte1 = u16 >> 8;
もう一方の端では、反対の方法で変換を行います