2012-09-04 2 views
7

TCPソケットを介してクライアントとサーバー間の通信をテストしています。私はCでサーバーを書いています。私はLinuxマシンでそれを実行しています。私はncをテスト用のクライアントとして使用しています。クローズドソケットの2回目の送信時にのみ壊れたパイプ

サーバは、クライアントとの最初のメッセージ交換後に、何も応答せずにクライアントに定期的にメッセージを送信します( )。私は、クライアントを殺す場合

、私は、サーバーによって行わ最初send()EPIPEエラーで失敗しますが、これが唯一のクライアントが去った後に、第2 send()で判明していることを期待して! 最初のsend()は、クライアントを殺した後、1100バイトを(私が閉じたと仮定して)正常に送信することができます。次のsend()操作は、ex3ct21として、EPIPEで終了します。

私にこの現象を説明できる人がいますか? TCP/IPスタックに書き込んで、できるだけ配信できるようにするためには、スタックの最大数は ですか? もしそうなら、どのように接続状態を確認できますか?ピアがまだそこにいることを確認する。

答えて

4

通常のTCP接続は、4ウェイハンドシェイクです。

http://en.wikipedia.org/wiki/Transmission_Control_Protocol

あなたはFINセグメントは、サーバおよびサーバプロトコルスタックにクライアント側から送信されたクライアントを殺しているACK送信します。

ここでサーバーがデータを読み取ろうとすると、読み取り呼び出しでは値0が返されるため、サーバープログラムはピアが終了したことを理解し、その後通常は接続ソケットを閉じます。これにより、クライアント側から最後のACKの受信後に、サーバ側からFINが送信され、通常の4ウェイハンドシェイクが完了することが可能になります。

(PLは、Q http://www.faqs.org/faqs/unix-faq/socket/の2.1を読んで)しかし、ここでは、サーバーからデータを書いているので、サーバはデータのみを送信した後に、クライアントからRESETを得ています。したがって、2回目の送信時の最初の送信操作後にエラーが発生しています。

だから、pl。 lingerオプションとtimeoutを0に設定して、クライアント側からの接続を突然終了させて​​みてください。これにより、send onの最初の呼び出しでエラー(EPIPEと異なる場合があります)が発生する可能性がありますサーバ側。(これはrecommnended練習ではなく、唯一のこの特定のケースでは、あなたの理解のために)

Try the following option of nc, nc -L 0 to set the linger option and timeout to 0 

(私はPL、NCのは、このオプションを試していない。このリンクで詳細をご確認http://docs.oracle.com/cd/E23824_01/html/821-1461/nc-1.html

上記サイトからのncの例、

Connect to TCP port, send some data and terminate the connection with 
TCP RST segment 
(instead of classic TCP closing handshake) by setting the linger option and 
timeout to 0: 

$ echo "foo" | nc -L 0 host.example.com 22 
+0

あなたの答えを、ありがとう、ありがとう、ありがとう。残念ながら私のLinuxマシン上のコマンドはそれをサポートしていないので、あなたが私に提案したncオプションをテストすることはできません。ところで、あなたが私に指摘した文書とあなたが私に与えた説明は、明確かつ有用です。ありがとう! – Igor

関連する問題