C++ UDP Socket端口复用
Posted
技术标签:
【中文标题】C++ UDP Socket端口复用【英文标题】:C++ UDP Socket port multiplexing 【发布时间】:2011-04-22 03:42:33 【问题描述】:如何在 C++ 中创建客户端 UDP 套接字,以便它可以侦听另一个应用程序正在侦听的端口?换句话说,如何在 C++ 中应用端口复用?
【问题讨论】:
多路复用仅在套接字的另一端期望多路数据时才有用(除非您试图“伪造”另一端期望的数据)。 我想我必须更好地解释一下这个场景。我有一个在端口 5000 上运行的应用程序。我想在同一个端口上监听,这样我就可以接收和解析应用程序正在接收的所有数据包。我认为我可以使用 SO_REUSEADDR 选项来绑定套接字,但是在我的程序在同一端口上接收数据包之前等待原始应用程序关闭。我希望问题和期望的行为现在很清楚。感谢您的回复。 【参考方案1】:我只想监听一个端口
你可以用嗅探器做到这一点。只需忽略来自不同端口的数据包即可。
我可能需要阻止它发送一些特定的数据包,因为我的程序将发送它而不是原始应用程序
好的,这里我建议你放弃嗅探器,并使用MITM 技术。
您需要依靠 PREROUTING 防火墙规则将数据包转移到“代理”应用程序。假设 UDP、Linux、iptables 和“proxy”在同一主机上运行,“proxy”实际上需要做的事情如下:
1. 添加防火墙规则以转移数据包(如果您愿意,请手动执行):
iptables -t nat -A PREROUTING -i <iface> -p <proto> --dport <dport>
-j REDIRECT --to-port <newport>
2.绑定并监听<newport>
。
3. 中继 2 个端点(客户端和原始目的地)之间的所有流量。如果您在不同的主机上运行“代理”,请使用 getsockopt 和 SO_ORIGINAL_DST
来检索原始目标地址。
这听起来可能很棘手,但是...是的,那是因为它有点棘手 :-) 如果我的假设不同,请查阅您的防火墙文档。
【讨论】:
我想这正是我需要的。 :) 非常感谢。【参考方案2】:这只是像tcpdump
或snoop
这样的数据包嗅探,打开一个原始套接字并根据需要从电线和过滤器中拉出所有内容。您可能希望使用libpcap 让事情变得更简单。
如果没有管理员或超级用户权限,您将需要目标应用程序打开适合平台的SO_REUSEADDR
和SO_REUSEPORT
端口。需要注意的是您只能接收广播和多播数据包,单播数据包被传递到第一个打开的套接字。
【讨论】:
好的。因此,在您看来,唯一的其他选择是使用 libpcap 嗅探网络接口上的每个数据包,然后过滤掉该特定端口的数据包。我在想,由于这些是 UDP 数据包(无连接),因此在同一端口上被动/主动发送/接收数据包应该不是问题。 我试过了,Linux只投递到第一个socket,不复用单播包。出于性能原因,其他平台可能但不太可能有所不同。【参考方案3】:这不是多路复用 - 该术语保留用于在同一进程中处理多个通道上的 I/O,并且像 select(2)
和 poll(2)
这样的东西最有用。
您要的是multicast。 Here 是基本示例。
请注意,IP 为多播保留了一个特殊的地址范围(也称为组)。这些被映射到特殊的以太网地址。侦听器必须加入多播组,而发送者不必这样做,它只是照常发送。
希望这会有所帮助。
【讨论】:
我有一个在端口 5000 上运行的软件应用程序,我无法修改该应用程序以使其加入任何多播组或类似情况。我想在同一个端口上监听,以便我的代码可以解析该应用程序接收到的所有数据包。我有一个概念,这被称为“端口多路复用”,但我找不到合适的例子。 然后获取 Wireshark (wireshark.org),嗅探数据包,转储到文件中,然后尝试一下。 我正在使用wireshark离线查看数据包,但我必须编写一个C++程序来嗅探或侦听特定端口而不是所有端口,并且它不能离线。我可以使用 libpcap 库,但就像我说的我只想监听一个端口,我可能需要阻止它发送一些特定的数据包,因为我的程序将发送它而不是原始应用程序!我不确定我是否让你很困惑:) pcap 允许您过滤您收听的内容,请参阅此处tcpdump.org/pcap.htm以上是关于C++ UDP Socket端口复用的主要内容,如果未能解决你的问题,请参考以下文章