在 C++ 中检查打开的 UDP 端口

如何使用本机 C++ 检查远程 UDP 端口是否打开?由于 UDP 是无连接的,因此调用 connect() 没有帮助.我无法尝试绑定它,因为它不是本地的.nmap 也不能表示.(但是 netstat 可以找到,但我认为它会查看有关打开端口/文件的内部信息).反正有检测吗?如果我在网络级别向下一层,是否可以通过 C++ 发送 ICMP 消息来检查端口不可达状态?我的意思是,这是否会提供有关端口状态的足够信息?

How can I check if a remote UDP port is open by using native C++? Since UDP is connection-less, calling connect() is not helpful. I cannot try binding it since it is not local. nmap cannot also indicate. (however netstat can find out, but I think it looks at internal information about open ports/files). Is there anyway to detect it? If I go a layer down on network level, is it possible to send a ICMP message by C++ to check port-unreachable status? I mean, would that give enough information on port status?

平台是 Linux.

推荐答案

我假设您正在尝试确定远程计算机上的 UDP 端口是否正在通过防火墙和/或是否有应用程序在其上运行.

I assume that you are trying to determine whether or not a UDP port on a remote machine is being passed through a firewall and/or has an application running on it.

您无法可靠地确定这一点.最接近的方法是尝试向该地址和端口发送一系列小数据报,间隔约 1 秒,持续约 10 秒.

You cannot reliably determine this. The closest you can come is to try sending a series of small datagrams to that address and port, spaced about 1 second apart for about 10 seconds.

如果没有防火墙阻止端口并且没有应用程序正在运行,那么远程系统可能会发回 ICMP_UNREACH_PORT(端口不可达).如果没有阻止防火墙并且远程系统已关闭,路由器可能会发回 ICMP_UNREACH_HOSTICMP_UNREACH_NET.如果防火墙阻止了您,它可能会发回 ICMP_UNREACH_FILTER_PROHIB,但大多数防火墙不会发回任何内容.

If there are no firewalls blocking the port and no application is running, then the remote system might send back ICMP_UNREACH_PORT (port unreachable). If there are no blocking firewalls and the remote system is down, a router might send back ICMP_UNREACH_HOST or ICMP_UNREACH_NET. If a firewall is blocking you, it might send back ICMP_UNREACH_FILTER_PROHIB, but most firewalls don't send back anything.

因为大多数防火墙都会阻止这种 ICMP 反馈,因此恢复其中任何一个的可能性非常小.即使确实返回了 ICMP 消息,除非您以 root 身份运行,否则 linux 通常不会让您看到它.某些操作系统会将 ICMP 错误报告为下一个 sendto() 到同一地址/端口的失败,这就是您需要多次重复该消息的原因.但有些没有,在这种情况下,您必须打开特定的 ICMP 端口并解析任何返回消息.

The odds of getting any of those back are pretty slim because most firewalls block that sort of ICMP feedback. Even if an ICMP message does come back, linux generally does not let you see it unless you are running as root. Some operating systems will report ICMP errors as a failure of the next sendto() to the same address/port, which is why you need to repeat the message several times. But some do not, in which case you must open a specific ICMP port and parse any return messages.

即使您确实以某种方式收到 ICMP 消息,也要了解它们并不可靠.例如,您可能会得到 ICMP_UNREACH_PORT,即使应用程序不仅在侦听,而且还在主动向您发送数据.(这种情况很少见,但我见过.)

Even if you do somehow get an ICMP message, understand that they are not reliable. For example, you could get ICMP_UNREACH_PORT even though an application is not only listening, but actively sending you data. (That's rare, but I've seen it happen.)

如果一个应用程序正在给定端口上运行,并且如果您知道该应用程序是什么,并且如果您知道如何制作将导致该应用程序响应您的消息,那么这样做并获得响应是最好的指示端口是开放的.但是没有响应意味着什么:也许端口被阻塞,也许应用程序没有运行,或者它只是不喜欢你的消息.

If an application is running on the given port and if you know what that application is and if you know how to craft a message which will cause that application to respond to you, then doing so and getting a response is the best indication that the port is open. But getting no response means nothing: maybe the port is blocked, maybe the application is not running, or maybe it just didn't like your message.

底线:不,不是.

相关文章