我如何判断我是否向一个开放的端口发送了UDP数据包?

5
我正在编写一个C程序,需要检查目标计算机上打开的UDP端口。由于UDP是无连接的,我不能像TCP一样检查connect()的返回值。 send()sendto()的返回值也没有帮助。手册页面说明:
   No  indication  of failure to deliver is implicit in a send().  Locally
   detected errors are indicated by a return value of -1.

我如何确定我是否向目标主机的一个开放端口发送了一个UDP数据包?

2个回答

6

一般情况下是不可能做到的。

原则上,一个关闭端口的主机应该会发送一个ICMP端口不可达消息。但它们经常不这样做;同样,一个关机或无法访问的主机也不会发送这样的消息。此外,一些防火墙会阻止该消息。

检索错误也很棘手。Linux有明确定义但令人困惑的套接字错误检索语义(请参见各种man页面,socket(7),ip(7)和udp(7)以获取一些信息)。例如,当您执行不相关的sendto()时,有时会看到先前报告的错误。其他操作系统具有稍微不同的机制来检索特定的套接字错误。

如果可以保证在另一个端口上使用特定协议,则可以发送一个数据包,该数据包应引发特定响应(如果它是您自己的协议,则可以添加“你在那里”的消息类型),然后您可以使用该响应。但是一般来说,是否生成响应取决于应用程序,您无法区分没有任何侦听的端口和决定不向您响应的某个侦听端口。


1
抱歉问这个问题,但我该如何查看是否发送了ICMP端口不可达消息?谢谢。 - Marian
@Marian:你能再提一个问题吗?我也很想知道。 - Matt Joiner
我认为检测ICMP端口不可达并不值得麻烦,因为它可能不会到达。这尤其适用于安装了“个人防火墙”产品的计算机,这些产品往往出于(大多数)误导性安全原因而阻止这些有用的东西。 - MarkR

2

由于UDP是无连接的,你需要在应用程序代码中检查端口状态。例如,向该端口发送数据包并等待响应。如果在特定的应用程序时间内没有收到响应,则该端口不可用。

当然,你需要将此设计到发送和接收两端。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接