-2

小さな (非常に小さな) ftp クライアントとサーバーを開発しました。
これらのプログラムはどちらも、同じアーキテクチャを使用する場合にのみ、適切にコンパイルおよび実行されます。

  1. クライアントがUbuntu amd64でサーバーがUbuntu i386の場合、segfaultが発生しました(ポインターの問題だと思います)
  2. クライアントが Ubuntu amd64 でサーバーが Ubuntu amd64 の場合はすべて問題ありません
  3. クライアントが Ubuntu i386 でサーバーが Ubuntu i386 の場合はすべて問題ありません

これら 2 つのプログラムを異なるアーチで動作させるにはどうすればよいですか?
コードの問題ですか?もしそうなら、私は何をしなければなりませんか?
前もって感謝します!

4

1 に答える 1

5

おそらく、さまざまなタイプのサイズの違いであり、ネットワークを介してそれらを送受信しています。サイズが一致しないため、プロトコルは非同期になります。

Linux はx86_64にLP64 データ モデルintを使用するため、まだ 32 ビットですが、long64 ビットです。x86longでは 32 ビットです。

幸いなことに、C 標準では、stdint.hヘッダー ファイルでいくつかの固定幅整数型が定義されています。これを含めると、n が 8、16、32、または 64 の符号なしタイプと符号付きタイプを使用できます。ネットワークプロトコルで考慮すべきもう 1 つのことは、バイト オーダーです。POSIX は、32 ビット整数と 16 ビット整数をホスト順序からネットワーク順序に、またはその逆にそれぞれ変換する関数、、、およびを提供します。uintn_tintn_thtonlhtonsntohlntohs

編集:

Variable Length Coder が指摘しているように、構造体全体の送信も移植性がありません (x86 と x86_64 の間ですが)。ネットワーク経由で構造体を送信する場合は、一度に 1 つずつ送信し、受信側の適切なフィールドに割り当てる必要があります。

編集2:

size_tまた、移植可能なデータ型ではありません。プロトコルに適した明示的なサイズの型を選択する必要があります。おそらくuint32_t良い選択です。

また、 のすべてのサイズ修飾子は標準の/ /型printfに基づいているため、マクロを使用してフォーマット文字列を作成する必要があります。例えば:shortintlong<inttypes.h>

#include <inttypes.h>

/* ... */

int32_t signed32;
uint16_t unsigned16;

printf("Signed 32 is %"PRIu32" and unsigned 16 is %"PRId16"\n", signed32, unsigned16);

あなたのシステムはこれらのヘッダファイルに man ページを持っているかもしれません (私の fedora システムは持っています) ので、コマンドプロンプトで使用できます

man stdint.h

man inttypes.h

これらのヘッダーで定義されているタイプ、マクロ、および関数に関する詳細情報を取得するには。

于 2012-07-03T20:26:31.437 に答える