2

Cでクライアント/サーバープログラムを使用して、サーバーからクライアントにファイルを転送しています。

しかし、クライアントはファイルの最後のバイトを受信した後でも recv を待っています。クライアントを強制終了するか、サーバーを強制終了した場合にのみ、クライアントが終了します。ただし、サーバーは他のクライアントの要求を楽しませる必要があるため、ループに入る必要があります。

サーバーで使用fork()して、各クライアントのリクエストを楽しませています。クライアントの要求が受け入れられた後、子プロセスを終了していますが、クライアントはサーバー プログラム全体が強制終了された場合にのみ終了します。

サーバーの子が終了したときにクライアントが終了しないのはなぜですか?

サーバー コードはここに、クライアント コードはここに表示されます。

4

4 に答える 4

3

すべてのデータが送信されたら、サーバー プロセスでshutdown(s, SHUT_WR) に続けて呼び出していることを確認する必要があります。close(s)

への呼び出しshutdown()は、送信するデータがこれ以上ないことを TCP 層に伝えます。

TBH、自分で呼び出しclose()てもそれが達成されない理由はよくわかりません。

編集-私は今それを理解しました-それは、コードのその時点で、親もソケットを開いたままにして、カーネルによって破棄されないためです。後にfork()追加のロジックを追加する場合:

if (p > 0) {
    close(connected);
}

その後、コードは を呼び出さずに機能しますshutdown()

昨日の質問への回答で送信したコードを使用している場合、クライアントはbytes_receivedゼロのカウントを取得してからループを終了します。

于 2009-04-23T15:41:57.717 に答える
0

次のようなものを呼び出す必要があります: shutdown(s, SD_SEND); closesocket;

ソケットを閉じるためにファイルを送信した後、サーバー上で。

于 2009-04-23T12:12:41.880 に答える
0

これは少し難しいので、詳細を教えてください。TCP/IP を使用していますか? ファイル転送について話しているので、TCPだと思います。

クライアントに接続されたソケットを所有するサーバー側でプロセスを終了している場合、接続が終了するはずです。その後、クライアントのrecv()呼び出しは終了し、-1 (または 0、100% 確実ではない) を返す必要があります。それができない場合は、メイン サーバー プロセスで明示的にソケットを閉じることを検討してください (ソケットの所有権をどのように設定したかわかりません)。

于 2009-04-23T12:13:53.533 に答える
-1

ソケットを読み取るには2つの方法があります...

  1. recv() でバイトごとに受信しますが、問題は、コンテンツにデータの途中に -1 が含まれている場合、ファイルの終わりを示します。

  2. もう 1 つの方法は、ストリームからバッファを読み取ることです。このメソッドは、ストリームから読み取ったバイト数を返します。それが 0 を返す場合は、ストリームの終わりを意味します。

于 2009-04-23T12:30:17.283 に答える