0

ソケットプログラミングを使用して通信する2つのプログラムがあります。最初に番号を指定します。相互にメッセージを交換する必要がある回数に関するホップ数。メッセージを受信するたびに、その ID が追加されます。したがって、文字列は毎回サイズが大きくなります。私のプログラムは 8000 ホップまで正常に動作していますが、8000 ホップを超えた後、プログラム p1 は長さ 16388 の文字列を送信しますが、p2 は、ソケットに 16385 しか読み取れないことを識別します。ioctl() を使用して、ソケットで recv() の準備ができている文字の量を決定し、それを char * 変数で recv します...

p1 の send() と p2 の recv() に遅延があるため、 p2 は socket で 16385 文字しか識別しないのでしょうか?

例: P1 が長さ (16388) を送信する場合

P2 は次の長さ (16385) のみを受け取ります

4

2 に答える 2

6

あなたに8個のカボチャを送ろうとしているとしましょう. テーブルの上に6つ並べました。あなたは、「6 ではなく 8 のカボチャを期待しています。彼が最後の 2 つをテーブルに置くまで待ちます」と考えます。私は、「一度に多くのカボチャを「飛行中」にしたくない. 最後の2つをテーブルに置く前に、彼がこれらの6つのうち2つを取るまで待ちます. 立ち往生しています。私たちはお互いを待っています。私たちは永遠に待ちます。

すでに受信したバイトを受け入れる前に、次のバイトを受信するまで待機することはできません。その理由は単純です。ネットワーク プロトコルでは、それぞれの側が相手を待つことができないからです。TCP は送信側がこのコンテキストで待機することを許可するため、受信側も待機することを許可できません。

そのため、受信したバイトを受け入れます。それらのいずれかを受け入れる前に、相手側がそれらすべてを送信するのを待たないでください。それ以外の場合、相手側が最初のメッセージを受け入れるのを待ってから、それ以上送信しない場合はどうなりますか?

于 2011-10-28T22:26:59.047 に答える
0

カーネル バッファの制限に達している可能性があります。おそらく受信側で SO_RCVBUF を増やすことができ、期待どおりに動作します。SIOCINQ は最終的に未読データのフルサイズを返します。

しかし、適切な機能を確保するためにそれを行うべきではありません。バッファをいじるのは、パフォーマンスを微調整したい場合にのみ行う必要があります。

カーネルに使用可能なバイト数を問い合わせる必要がないように、コードを再構築する必要があります。妥当な制限 (4096 など) まで読み取り、1 つのアプリケーション レベルのメッセージが複数の部分に分割されていることを処理します。メッセージの長さ/境界が必要な場合は、TCP の上に自分で実装する必要があります。

長さヘッダーを持つメッセージを読み取るためのばかげたコードを次に示します。

int ret, len = 0, have_read;
have_read = 0;
while (have_read < sizeof(len)) {
    // This will likely always return sizeof(len) the first time.
    ret = read(fd, ((char*)&len) + have_read, sizeof(len) - have_read);
    if (ret <= 0) {
        // Handle error.
    }
    have_read += ret;
}
char* buf = malloc(len);
if (!buf) {
    // Handle error.
}
have_read = 0;
while (have_read < len) {
    ret = read(fd, buf + have_read, len - have_read);
    if (ret <= 0) {
        // Handle error.
    }
    have_read += ret;
}
// Handle message in buf.
于 2011-10-28T23:09:05.120 に答える