3

私が興味を持っている基本的なコード シーケンスは (疑似コード) です。

sendto(some host); // host may be unreachable for now which is normal
...
if(select(readfs, timeout)) // there are some data to read
  recvfrom();

Win2000以降、到達不能なポートにUDPデータグラムを送信した後に返されるICMPパケットがselectをトリガーし、その後recvfromがWSAECONNRESETで失敗します。この場合、 select をタイムアウトで終了させたい (読み取るデータがない) ため、このような動作は望ましくありません。Windows では、これは WSAIoctl SIO_UDP_CONNRESET ( http://support.microsoft.com/kb/263823 ) で解決できます。

私の質問は次のとおりです。

  1. この状況では SIO_UDP_CONNRESET が最善の方法ですか?
  2. 「select」で ICMP を無視したり、recvfrom でフィルタリングしたりする他の方法はありますか (おそらく、タイムアウトのように処理する Windows で WSAECONNRESET エラーを無視すると、このエラーは他のケースで発生する可能性があります)。
  3. Linux と Unix (Solaris、OpenBSD) で同様の問題はありますか?
4

1 に答える 1

2

select()のset は、ソケット上のaがブロックされないreadfdsことを報告するだけです。読み取り可能な実際のデータがあるかどうかについては何も約束しません。read()

永遠に眠るのではなく、2秒のタイムアウトで具体的に何を達成しようとしているのか、また、ifチェックするブロックを追加できない理由WSAECONNRESETはわかりませんrecvfrom()が、このケースを適切に処理しないと、過度に複雑な設計になります。

select_tut(2)多くの Linux システムのマンページには、 を適切に使用するためのガイドラインがいくつかありますselect()。あなたの状況に最も適していると思われるいくつかのルールを次に示します。

   1.  You should always try to use select() without a timeout.
       Your program should have nothing to do if there is no
       data available.  Code that depends on timeouts is not
       usually portable and is difficult to debug.

   ...

   3.  No file descriptor must be added to any set if you do not
       intend to check its result after the select() call, and
       respond appropriately.  See next rule.

   4.  After select() returns, all file descriptors in all sets
       should be checked to see if they are ready.
于 2011-12-05T09:33:53.170 に答える