我需要能够在同一端口上发送和接收UDP数据包。
我可以监听5000端口,但是我的发送使用了随机的高端口。
我正在用VB编写的系统可以做到这一点,我需要编写UDP响应程序来调试各种协议(protocol)问题。
我正在使用http://www.alhem.net(Anders Hedstrom)的开源C++套接字库,并且能够使用虚拟函数UdpSocket::OnRawData()使用UdpSocket::Bind()接收传入的UDP数据包,但无法导致UdpSocket::Open()(调用connect)以使UdpSocket::Send()使用Bind()中选择的端口(它改用随机的高数字端口)。
移动Open()函数无济于事。我已经在他们的论坛上发布了一个请求-但我认为从阅读的内容中可以做到这一点,而且我可能不了解如何使用UDP。
有人对我应该尝试的方法有任何想法吗?
- 谢谢 -
最佳答案
我不确定我是否理解该句子中的“全部使用同一端口”一词。如果A向B发送数据报,则B会立即知道A的IP和端口(对库文档的快速检查显示OnRawData具有struct sockaddr *sa
参数,如果将其转换为sockaddr_in*
,则可以提取IP:端口对)。您可以使用该IP:port将数据报发送到,然后A会接收它们。 A并未在套接字上未调用listen()的意义上在该端口上“监听”,而是因为A拥有绑定(bind)到该端口的套接字(无论是通过显式调用bind()还是通过以下方式分配了随机端口):操作系统)它将接收数据。
现在,如果您希望节点之间的所有通信都通过固定端口,则可以执行此操作。您只需要通过“监听”套接字发送所有数据报即可。如果每个节点都“监听”同一端口,则意味着每个节点都拥有一个绑定(bind)到该端口的套接字。如果要使从A到B的数据报显示为来自此固定端口,则必须通过该套接字发送它们。我猜这就是为什么bind()对您的发送套接字不起作用的原因-A将一个套接字绑定(bind)到端口X,然后您创建另一个套接字并尝试将其绑定(bind)到相同的端口X,bind()失败,因为该端口已被占用(并且您不检查错误:),然后操作系统会分配1024以上的随机空闲端口。
注1:我在所有引号中都使用“监听”,因为在UDP套接字的上下文中这个概念不是很清楚。创建套接字并将其绑定(bind)到端口后,无论是通过显式调用bind()还是通过发送数据并让操作系统将其绑定(bind)到端口,您都可以通过它从任何地方接收数据。不需要listen()或accept()调用。
注意2:您说过UdpSocket::Open()调用connect(),但这没有多大意义-connect()对UDP套接字的作用很小-它仅建立一个默认地址,因此您可以使用send()代替sendto()的值,而不是在每次发送时都指定地址。
希望这能说明问题。
编辑以解决OP的评论:我从未使用过此库,但根据其UdpSocket documentation,有4个Bind()方法重载,并且每个重载都以某种方式接受端口。他们都不适合您吗?