6

recvを使用してソケット経由でデータを受信すると、次のように気づきました。

文字バッファ[4];
memset(バッファ、0、4);
recv(ソケット、バッファ、4、0);

私は受け取ります

mesgx��

「mesg」は私が送信したもので、ランダムな文字が追加されています。

私が使用する場合

char * メソッド = (char *) malloc(4);
memset(バッファ、0、4);
recv(ソケット、バッファ、4、0);

代わりに、私は受け取ります

メッセージ

したがって、文字列にランダムなものが追加されることはありません。代わりに char[5] を使用しても同様に機能することがわかりましたが、その理由はよくわかりません。malloc(4) は本当に 5 バイトを割り当て、5 番目は NUL ですか?

4

4 に答える 4

16

への呼び出しは、malloc(4)実際には 4 バイトしか割り当てません。メモリ内の次のバイトがたまたま NUL であり、文字列が終了したのは偶然でした。

char buffer[4]スタックに割り当てた場合、次のバイトの'x'後に他のものが続いたので、次の NUL バイトが見つかるまで文字列が続きました。

ソケット関数はバイトのみを処理し、バイトを末尾の NUL またはその他のものを含む文字列として処理しません。あなたはまさにあなたが求めるものを手に入れます。

于 2009-07-26T22:08:11.960 に答える
6

適切に NULL で終了するには、5 文字が必要です。終端の NULL は 1 つとしてカウントされるため、N 文字が必要な場合は N+1 を割り当てます。または逆に、N の割り当ての場合、N-1 をコンテンツに使用できます。

于 2009-07-26T22:02:45.607 に答える
3

この違いは偶然だと思います。たとえば、printf() で buffer を文字列として使用すると、'\0' が見つかるまで制限を超えて読み取られます。

どちらの場合も、buffer[5] または malloc(5) を使用する必要があります。memset() は必要ありません。recv() の後に buffer[4] = '\0' を配置することをお勧めします。

于 2009-07-26T22:10:52.860 に答える
2

最大 4 バイトをバッファに配置するようにchar要求しただけなので、4 を超える s を受信した可能性はありません。recvの戻り値をチェックして、recv実際に返されたバイト数を確認する必要があります。

問題はchar、出力を生成しているルーチンから 4 秒しか出力しないように注意していないことだと思います。null ではない終端charバッファの初期内容を表示する 1 つの方法は、次のとおりです。

printf("%.4s\n", buffer);

完全なrecv呼び出しスニペットは次のようになります。

#define MAX_BUF_LEN (512)
char buffer[MAX_BUF_LEN];
ssize_t count = recv(socket, buffer, MAX_BUF_LEN, 0);

if (count > 0)
    printf("%.*s\n", count, buffer);
于 2009-07-26T22:09:09.367 に答える