2

私はクライアントサーバープログラムを書いています。サーバーは の読み取り準備が整うのを待っていselect()ます。準備ができている場合、サーバーはデータを収集して印刷しています。しばらくはすべて問題ありませんが、しばらくすると、ソケットが に設定されて失敗しました。ここで、これらのエラー状態を阻止するためにプログラムを書き直したいと思います。そこで、Richard Stevens による「Unix Network Programming」を調べました。この記事には、ブロックを解除するための 4 つの条件が記載されています。以下は、私の注意を引く2つの条件ですreadfd1readfd1recv()errnoETIMEDOUTselect()

A. client sent FIN, here return value of `recv()` will be `0`
B. some socket error, here return value of `recv()` will be `-1`.

私の質問は、ソケットエラーは接続を閉じますか? もしそうなら、なぜ上記の2つの条件が分離されているのですか。そうでない場合、次recv()のソケットは機能しますか?

4

2 に答える 2

3

If recv() returns 0, the other end has actively and gracefully closed the connection.

If recv() returns -1, there has (possibly) been an error on the connection, and it is no longer usable.

This means you can tell the difference between the peer closing the connection, and an error happening on the connection. The common thing to do in both cases is to close() your end of the socket.

There is 2 more points to consider though:

In the case of recv() returning -1, you should inspect errno, as it might not indicate a real error. errno can be EAGAIN/EWOULDBLOCK if you have placed the socket in non-blocking mode or it could be EINTR if the system call was interrupted by a signal. All other errno values means the connection is broken, and you should close it.

TCP can operate in half duplex. If the peer has closed only its writing end of the connection, recv() returns 0 at your end. The common thing to do is to consider the connection as finished, and close your end of the connection too, but you can continue to write to it and the other end can continue to read from it. Whether to close just the reading or writing end of a TCP connection is controlled by the shutdown() function.

于 2013-05-29T13:03:10.230 に答える
1

A socket error doesn't have to mean that the connection is closed, consider for example what happens if somehow the network cable between you and your peer is cut then you would typically get that ETIMEDOUT error. Most errors are unrecoverable, so closing your end of the connection on error is almost always advisable.

The difference between the two states when select can unblock, is because either the other end closed their connection in a nice way (the first case), or that there are some actual error (the second case).

于 2013-05-29T13:04:00.933 に答える