2

サーバーとクライアント プログラムとの単純な TCP 接続があります。メッセージとして渡すために、サーバーとクライアントの両方で単純な構造体を作成しました。

struct {int c; char** v;} msg;

クライアントからargcとargv(端末からの入力)を送信しようとしています:

int main(int argc, char **argv){
...
msg.c = argc;
msg.v = argv;
sendto(Socket, &msg, sizeof(msg), 0, (struct sockaddr *)&input, sizeof(input));

サーバーに送信されると、msg.c を呼び出して番号を取得し、それを使用できますが、文字列の配列を使用しようとすると、セグ フォールトが発生します。

recvfrom(Socket, &msg, sizeof(msg), 0, (struct sockaddr *)&input, &sizep);
printf("%d\n", msg.c);
printf("%s\n", msg.v[2]);

これを 1 つだけ試してみましたchar *が、文字列を送信することもできませんでした。

私は何を間違っていますか?

4

2 に答える 2

4

関数はsendto()ポインターをまったく追跡しません。したがって、整数と 1 つのポインターで構成されるメッセージを反対側に送信しています。レシーバーは、何の意味もないメモリ内のランダムな場所を指すポインター値を取得します。

あなたがする必要があるのは、データをソケット経由で送信できるものにシリアライズすることです。つまり、ポインターはありません。たとえば、単一の文字列の場合、長さを送信し、その後に文字列の実際のバイト数を送信できます。複数の文字列の場合、カウントを送信し、その後に単一の文字列と同じ形式で多数の文字列を送信できます。

データを受信したら、受信側で必要な場合は、データをchar *文字列の配列にシリアル化解除する必要があります。

于 2012-08-05T00:50:55.313 に答える
2

配列を送信することはできません。あなたがしているように見えるのは、配列へのポインタを送ることです。ポインターは、送信側の RAM 内の配列の先頭を指す値です。ただし、このアドレスは 1 つのクライアントに対してローカルです。配列やクラス/構造体などの複雑なデータを送信する必要がある場合は、通常、それらをシリアル化する必要があります。あなたをサポートするライブラリが周りにあります。私は Google のProtocol Buffersを使用しましたが、気に入りました。あなたはそれを見たいと思うかもしれません。

于 2012-08-05T00:52:04.767 に答える