2009-04-23 7 views
2

私はCからクライアント/サーバプログラムを持っています。これを介してサーバからクライアントにファイルを転送しています。ソケット:最後のバイトを受信して​​もクライアントが待っています

しかし、クライアントはファイルの最後のバイトを受信した後でも、recvを待っています。クライアントは私がそれを殺すかサーバーが私によって殺された場合にのみ終了します。しかし、サーバーは他のクライアントの要求を受け入れなければならないため、ループしていなければなりません。

私はサーバー内でfork()を使用して各クライアントの要求を受け入れています。クライアントのリクエストが受け付けられたあと、子プロセスから抜け出していますが、サーバープログラム全体が終了したときにのみクライアントが終了しています。

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

サーバーコードhereとクライアントコードhereが表示されます。

+2

あなたの質問がありますか? – JRL

+0

@JRL有効な質問の理由なしで-1を与えることは非常に悪いです。質問は正しいです。 –

+0

@Akash:あなたが言っていることは分かりません。私が-1を与えたと言っているなら、あなたは間違っている、私はしなかった。私はちょうど彼の質問が何だったのか尋ねるコメントをした。 – JRL

答えて

3

あなたはshutdown(s, SHUT_WRを呼び出すことを確認する必要があります)一度すべてのデータのが送信されたサーバプロセスにclose(s)が続きます。

shutdown()を呼び出すと、送信するデータがもうないことがTCPレイヤに通知されます。

TBH、私は確かになぜclose()を呼び出すのはそれを達成できないのかよく分かりません。

EDIT - あなたのコードのその時点で、親がまだソケットを開いているので、カーネルによって分解されないためです。 fork()後にあなたには、いくつかの余分なロジックを追加する場合:

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

は、あなたのコードはshutdown()への呼び出しなしで動作します。

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

+0

あなたの返信ありがとう! は、親と子の両方が共有するファイルではありません。 ところで、一度クライアントが0バイトを受信すると、それはループから抜け出し、最終的に終了します。しかし、それは起こっていません。子はall.i hvを受け取った後でも何かを待っています。それはサーバーが殺されるまで何も表示されていません! – mawia

+0

いいえ、ファイルは共有されますが、ファイル記述子は別です。子で閉じても、親にはまだ開いたままです。ファイルがまだ開かれているため、サーバーはストリーム終わりのための長さゼロのインジケーターを送信しません。上記のコードをサーバープログラムに追加したところ、すべて正常に機能しました。 – Alnitak

0

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

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

0

これはちょっと難しいですが、詳細がうまくいきます。 TCP/IPを使用していますか?あなたがファイル転送について話しているので、私はそれがTCPだと仮定します。

クライアントに接続されたソケットを所有するサーバー側でプロセスを終了すると、接続が終了することがあります。クライアントのrecv()コールは終了し、-1(または100%確実ではない0)を返します。それに失敗した場合は、メインサーバプロセスのソケットを明示的に閉じる(ソケットの所有権をどのように設定したかはわかりません)。読み取りソケットの2つの方法があります

-1

...

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

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

+0

-1完全に偽の点のためにファイルの真ん中に約-1である – Alnitak

+0

1バイトあたり1つの関数呼び出しが本当に吸う!あなたはそれよりもうまくいく必要があります。 –

関連する問題