2

UDP でエコー サーバーを作成し、特定のファイルをパケットに分割してサーバーに転送するクライアントで作業しています。サーバーは、クライアントによって再構築されるパケットを返します。

個々のパケットの送信は問題なく機能します。ただし、UDP_CORK ソケット オプションを使用して、ファイルのできるだけ多くの部分を 1 つのパケットで転送しようとしています。私は次のコードで作業しています:

#define LINE_SIZE 80

...
// s = socket descriptor.
...

int one = 1;
int zero = 0;

setsockopt(s, IPPROTO_UDP, UDP_CORK, &one, sizeof(one));  // cork

/* Send to server, receive from server, write to new file. */

FILE *orig, *copy;
char line[LINE_SIZE];

if ((orig = fopen(input + 3, "rb")) == NULL) // original file
    print_error(input);

if ((copy = fopen(filename, "wb")) == NULL)  // copy of file
    print_error("fopen");

while (fread(line, sizeof(char), LINE_SIZE, orig) > 0) {
    if (sendto(s, line, LINE_SIZE, 0, (struct sockaddr *)&srv, len) == -1)
    print_error("sendto");
}

setsockopt(s, IPPROTO_UDP, UDP_CORK, &zero, sizeof(zero));  // uncork

if (recvfrom(s, line, LINE_SIZE, 0, (struct sockaddr *)&srv, &len) == -1)
    print_error("recvfrom");

fwrite(line, sizeof(char), LINE_SIZE, copy);

サーバーは、1 つの「通常サイズ」のパケットのみを受信して​​いることを示しており、必要なコルク パケットは受信していません。したがって、recvfrom() 呼び出しを介してクライアントによって受信された、この 1 つの通常のパケットのみが送り返されます。

UDP_CORK を正しく設定したかどうかわかりません。2 番目の引数は正しいですか? マニュアルページが完全に明確ではなかったため、2 番目のオプションが実際に何を意味するのかよくわかりません。コルクの仕組みを誤解している可能性もあります。

注意すべき点がいくつかあります。

  • 私は中級レベルのプログラマーだと思っていますが、ネットワーク プログラミングの経験はほとんどありません。
  • UDP はファイルの転送に最適ではないことを認識しています。これは最終的に、私が開発を支援している別のプロトコルに適応される予定です。

ありがとうございました!

4

1 に答える 1

1

ファイルの大きさは?UDP データグラムのサイズは 64K に制限されていることをご存知ですか? そして、1472 バイトを超えるもの (1500 バイトの使用可能なイーサネット ペイロードから最小 20 バイトの IP ヘッダーを差し引いたもの、8 バイトの UDP ヘッダーを差し引いたもの) は IP フラグメント化されます。

次に、の戻り値をチェックすることはありませんsetsockopt(2)。それが成功していることをどのように知っていますか?

次にfread(3)、読み取った量を示しますが、それでもLINE_SIZEバイトを送信しようとします。これは間違っています。

于 2012-05-24T21:36:24.210 に答える