1

データ転送に unix scoket を使用しています (SOCK_STREAM モード)

10 万文字を超える文字列を送信する必要があります。まず、文字列の長さを送信します。これは sizeof(int) バイトです。

length = strlen(s)
send(sd, length, sizeof(int))

次に、文字列全体を送信します

bytesSend = send(sd, s, length)

しかし、驚いたことに、「bytesSend」は「長さ」よりも小さいです。

それほど大きな文字列を送信しない場合、これはうまく機能することに注意してください。私が見逃していたシステムコール「send」にいくつかの制限が存在する可能性があります...

4

2 に答える 2

11

sendシステムコールはfastであると想定されています。これは、プログラムが他の便利な処理を行う可能性があるためです。確かに、データが送信され、他のコンピューターが応答を送信するのを待ちたくありません。これは、ひどいスループットにつながります。

したがって、send実際に行うことは、送信するデータをキューに入れ、制御をプログラムに戻すことだけです。カーネルはメッセージ全体をカーネル メモリにコピーできますが、これは多くのカーネル メモリを消費します (良くありません)。

代わりに、カーネルは妥当な範囲のメッセージのみをキューに入れます。残りのデータの送信を再試行するのは、プログラムの責任です。

あなたの場合、ループを使用して、最初に送信されなかったデータを送信します。

while(length > 0) {
    bytesSent = send(sd, s, length);
    if (bytesSent == 0)
        break; //socket probably closed
    else if (bytesSent < 0)
        break; //handle errors appropriately
    s += bytesSent;
    length -= bytesSent;
}

受信側でも、おそらく同じことを行う必要があります。

于 2009-10-16T12:50:05.410 に答える
1

最初のsend()呼び出しが間違っています。データのアドレスを send() に渡す必要があります。

bytesSend = send(sd, &length, sizeof(int))

また、これは、エンディアン、intさまざまなプラットフォームでのサイズなど、いくつかの古典的なリスクに遭遇します。

于 2009-10-16T12:49:08.667 に答える