私はソケットを介してUDPパケットのメインフレームからデータを受け取るCプログラムを持っています。 CプログラムのホストがUnix(ビッグエンディアン)からLinux(リトルエンディアン)に変更されており、プログラムはもはや機能しません。現在、メインフレームクライアントプログラムを変更するオプションはありません。リトルエンディアンシステムでビッグエンディアンシステムによって送信された構造体データの非直列化
プログラムはrecvfrom
を実行し、char配列にデータを受け取ります。以前は、このバッファをMFから渡されたものと一致する構造にキャストするだけで、すべてが完璧に機能しました。バイトアライメントが異なるため、構造へのマッピングが失敗します。ここに構造といくつかのコードがあります。
struct CCClntPkt
{
unsigned short packet_type;
unsigned short reply_socket;
unsigned long msg_ID;
unsigned short msg_length;
unsigned char client_string[250];
};
以前にこの構造体に、受信データバッファをキャストするために使用されるコードは次のようになります。
char BCpacket_in[MAX_PACKET];
struct CCClntPkt *pClntPkt;
<snip>
rcv_cnt = recvfrom(BCServerSocket, BCpacket_in,
sizeof(BCpacket_in),0x0,(struct sockaddr *)&from,
&fromlen);
if (rcv_cnt > 0)
{
pClntPkt = (struct CCClntPkt *) &BCpacket_in;
}
私はntohs
が、文字フィールドを使用してpacket_typeとreply_socketの正しい値を取得することができましたclient_stringはマングリングされています。私も構造の後にpragma pack(1)
とpragma pack(0)
を入れてみましたが、依然として位置合わせの問題があるようです。
また、ビットシフト値をBCpacket_in
から試して、packet_typeとreply_socketの正しい値を取得することができましたが、ulong msg_IDを引き出す方法がわかりません。そのコードは次のとおりです:
packet_type = BCpacket_in[0] << 8;
packet_type |= BCpacket_in[1];
reply_to_socket = BCpacket_in[2] << 8;
reply_to_socket |= BCpacket_in[3];
/*
msg_ID = BCpacket_in[4] << 24;
msg_ID |= BCpacket_in[5] << 16;
msg_ID |= BCpacket_in[6] << 8;
msg_ID |= BCpacket_in[7];
*/
私はこの時点で非常に困っていますので、何か助けに感謝します。私はこのプログラムの元の著者ではなく、私の知識はかなり限られています。私は仕事をしても構いませんので、関連する参考文献も提供されていることを感謝します。ありがとう!
あなたがコメントアウトしたコードは、それが32ビットマシンであると仮定して、そのトリックを行うべきです。 char << intは整数昇格後の結果の型intを返します。 16ビットマシンでは、intは16ビットであり、コードは機能しません。 – Lundin