如何在同一端口发送和接收UDP数据?

13

我需要在同一端口发送和接收UDP数据包。

我已经能够监听一个端口,例如5000端口,但我的发送使用的是随机高端口。我正在使用VB编写的系统并且这样做,我的需求是为调试各种协议问题编写一个UDP响应器。

我正在使用来自http://www.alhem.net(Anders Hedstrom)的开源C++套接字库,并且已经能够使用UdpSocket :: Bind()接收传入的UDP数据包,使用虚拟函数UdpSocket :: OnRawData(),但无法使UdpSocket :: Open()(调用连接)让UdpSocket :: Send()使用Bind()中选择的端口(它使用随机高数字端口)。

移动Open()函数没有帮助。我已在他们的论坛上发布了一个请求-但相信从我所读到的内容来看,应该可以做到这一点,而我可能不理解如何使用UDP。

有人有什么想法我应该尝试什么?
--谢谢--


你是在同一个UdpSocket对象上调用Bind()和Open(),还是在两个不同的对象上调用? - Heath Hunnicutt
使用相同的实例化对象,首先调用Bind()函数,然后调用Open()函数,最后调用Send()函数。 - cedgriss
2个回答

11
系统由多个节点组成,这些节点在相同端口上侦听(不同的IP地址)。系统[A]向系统[B]发送数据包。系统[B]异步响应并使用同一端口将数据包发送回[A]。即使[B]确定了[A]的端口,[A]也没有在该端口上侦听。对于那句话中的"all using the same port"我不太确定理解得是否正确。如果A向B发送一个数据包,则B将立即知道A的IP和端口(检查库文档您会发现OnRawData有一个struct sockaddr * sa参数,如果你将它转换为sockaddr_in *,你就可以提取IP:port对)。您可以使用该IP:端口将数据包发送到A,并且A将接收它们。从监听的角度来看,A并未在该端口上“侦听”(即其未在套接字上调用listen()),但是由于A拥有绑定到该端口的套接字(无论是通过调用bind()显式绑定还是由操作系统分配随机端口),因此它将接收数据。
现在,如果您希望节点之间的所有通信都通过固定端口进行,您可以这样做。您只需通过“监听”套接字发送所有数据报。如果每个节点都“侦听”同一端口,则意味着每个节点拥有绑定到该端口的套接字。如果您希望从A发送到B的数据报似乎来自于此固定端口,则必须通过该套接字发送它们。我猜这就是为什么bind()不适用于您的发送套接字的原因-A拥有一个绑定到端口X的套接字,然后您创建另一个套接字并尝试将其绑定到相同的端口X,bind()失败,因为端口已被占用(而且您没有检查错误:),然后操作系统分配随机空闲端口号大于1024。
注意1:我在任何地方都使用“监听”引号,因为在UDP套接字的上下文中概念不太清楚。一旦您创建了套接字并将其绑定到端口,无论是显式调用bind()还是发送数据并让操作系统将其绑定到端口,您都可以通过它从任何地方接收数据。不需要listen()或accept()调用。
注意2:您说UdpSocket :: Open()调用connect(),但这没有太多意义-对于UDP套接字,connect()几乎没有任何作用-它仅建立默认地址,以便您可以使用send()而不是sendto(),并且无需在每次发送时指定地址。
希望这能澄清事情。
编辑以回答OP的评论:我从未使用过此库,但根据他们的UdpSocket文档,Bind()方法有4个重载,并且每个重载都以某种方式接受端口。它们中的没有一个适合您吗?

感谢您的回复。之前的尝试表明您的笔记是正确的。更多的研究表明,我必须更改传递给低级bind()函数的低级struct sockaddr *地址的sin_port字段,将其从“0”更改为我所需的源端口(“0”表示使用可用端口作为发送源)。我正在逐步执行代码,并且尚未找到一种使用高级UpdSocket对象访问和更改此内容的方法。我还不确定我是否做对了,希望该库有一种方法来实现这一点。 - cedgriss
重新检查了UpdSocket :: Bind()函数,虽然所有版本都涉及设置传入/接收,但第四个版本使用SocketAddress&结构体,该结构体可能也具有发送端口。我会更深入地研究它,并在此方面回复您。再次感谢您的快速响应。 - cedgriss

5
一个双向通信链路总是涉及两个参与者:服务器端和客户端。
客户端期望在一个定义好的端口上与服务器进行通信,这就是为什么必须在服务器端绑定()到一个套接字。
在客户端上,必须打开一个连接到服务器的套接字:实际上选择哪个套接字并不重要(除了需要它是空闲的)。
换句话说,不要试图在客户端指定一个套接字:网络协议栈将把它分配给你的客户端。

系统由多个节点组成,这些节点在同一端口上侦听(不同的IP地址)。系统[A]向系统[B]发送数据包。系统[B]异步响应并使用相同的端口将数据包发送回[A]。即使[B]识别出[A]的端口,[A]也没有在该端口上侦听。我正在开发一个协议测试/响应器,用于诊断和测试,并且必须能够出现为从相同端口侦听和发送的子系统。我不能更改现有的系统,这些系统都是现有标准化实现的一部分。 - cedgriss
你能画个图吗?这会让事情变得更简单(至少对我来说是这样)。 - jldupont

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