在选择中响应ICMP

时间:2011-12-05 09:19:25

标签: c sockets udp winsock icmp

我感兴趣的基本代码序列是(伪代码)

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。这样的行为对我来说是不可取的,因为我想在这种情况下选择以超时结束(没有数据要读取)。在Windows上,这可以通过WSAIoctl SIO_UDP_CONNRESET(http://support.microsoft.com/kb/263823)来解决。

我的问题是:

  1. 在这种情况下,SIO_UDP_CONNRESET是最佳方式吗?
  2. 是否有一些其他方法可以忽略ICMP以进行“选择”或将其过滤为recvfrom(可能忽略了Windows上的WSAECONNRESET错误,将其视为超时,是否可以在其他情况下触发此错误)?
  3. Linux和Unix(Solaris,OpenBSD)上是否存在类似的问题?

1 个答案:

答案 0 :(得分:2)

select()的{​​{1}}设置实际上只是报告套接字上的readfds不会阻止 - 它不承诺任何关于是否或者没有可供阅读的实际数据。

我不知道你要用两秒钟超时而不是只是永远沉睡才能完成什么 - 也不是为什么你不能只添加一个read()块来检查{{1来自if - 但如果它不能很好地处理这种情况,你会觉得你有一个过于复杂的设计。

许多Linux系统上的select_tut(2)联机帮助页都有一些正确使用WSAECONNRESET的准则。以下几条规则似乎最适合您的情况:

recvfrom()