在UDP层面上:"通常只允许每个套接字地址的一次使用"。

3

我的情景是:

有两台不同机器上运行着两个软件,一个作为服务器,一个作为客户端。它们都使用相同的UDP端口进行通信。(由于客户端硬件的限制,无法将通信设置在TCP层面上(内存受限))。这种情况已经持续了15年。

现在我想为这个客户端制作一个仿真器,这样我就不必每次需要调试和故障排除时都要重新配置客户端。而且它不在我所在的位置。

我做的事情是,在虚拟网络卡上创建了一个具有监听端口和发送端口(与服务器相同)的简单客户端应用程序(使用devcon实用工具创建)。

现在当我运行客户端时,我会得到一个SocketException:“通常只允许每个套接字地址(协议/网络地址/端口)使用一次”。(这是启动客户端时发生的第一件事)

这发生在我创建监听器的那一行:UdpClient listener = new UdpClient(listenPort);

在OSI模型中,首先是网络层(IP地址),然后是端口号(使用TCP/UDP层)。

7   Application     Process Application     
6   Presentation
5   Session
4   Transport       Host to host          TCP, UDP  Packets
3   Network         Internet              IP, ICMP  Frames
2   Data Link       Network Access        ARP       Bits
1   Physical 

客户端没有在与服务器相同的网络卡上进行监听(但它们都在同一台计算机上运行)。我不明白的是为什么会出现这种消息?也许不能在同一台计算机上创建虚拟网络卡并使用相同的端口吗?(因为我想在同一台计算机上运行客户端和服务器)。
[编辑] 设置情景图 [/编辑]
我只是想知道,可能的原因之一是它正在为所有网络卡使用一个端口列表,因此已经被使用。那么我的问题是:“如何创建第二个要监听的端口列表(因为它是同一台计算机上的不同网络卡)?”这几乎与VirtualBox或VirtualPC创建新的虚拟网络卡相同。当它们被创建时,可以在同一端口上进行监听(尽管它是虚拟机),但仍然是同一硬件。那么问题是他们是如何做到的?

你是否正确地将本地套接字绑定到正确的网络卡上?你的服务器绑定到主要的网络卡上,测试客户端绑定到虚拟卡上了吗? - Matthew Kennedy
1
@MatthewKennedy 我正在使用的代码行是 UdpClient listener = new UdpClient(listenPort); IPEndPoint groupEP = new IPEndPoint(IPAddress.Parse("192.168.0.3"), listenPort);。但是它在第一行就已经出现了错误。我尝试了另一种方式,但仍然在第二行出错。 - DForce
你尝试过为客户端使用另一个端口吗?据我所知,在客户端上使用的端口号对于服务器来说并不是一个真正的问题。 - lboshuizen
@lboshuizen 是的,那样做可以,但是我就无法获得所需的连接了 ;) 我画了一个小框图,说明情况需要如下:Image - DForce
@lboshuizen:我知道发送端使用哪个端口并不重要,只要它能到达监听端口即可。我认为,在打开新的UdpClient(在同一台计算机上)时,有一个列表存储了该计算机上所有网络适配器的已打开端口,而不是每个网络适配器都有一个列表。这可能是无法在同一台计算机上设置相同端口的原因吗? - DForce
显示剩余3条评论
3个回答

0
  1. 你可以在虚拟机内运行/调试。
  2. 你可以购买一个便宜的()

至于添加第二个虚拟网络适配器,我从未见过伪造计算机上另一个网卡的程序。


创建虚拟机是最后的选择,因为我不希望为每个客户都安装一个虚拟机(比如全球范围内的所有客户),它只需要是一个在同一客户端上与服务器一起运行的程序。因此,我的问题仍然存在:“是否可以通过虚拟网络卡在同一台计算机上打开相同的UDP级别端口?” - DForce
啊,所以你需要在每个生产实例上进行仿真,而不是在你的开发机器上。 - Matthew Kennedy
是的,为了深入了解情况:“客户现场有一个连接到电脑的机器人,控制软件在电脑上,由于我不想重新配置那台电脑,我只想设置机器人监听模拟器,在那里我可以轻松调整值并进行调试,而无需触碰客户的计算机(因为重新配置可能是一项繁琐的任务(就在你问之前:"不,不可能创建备份 - 捣鼓配置 - 并将备份复制回去 ;) ))。” - DForce

0
在创建新的UdpClient()时,将端口号指定为0。
var clt = new UdpClient(0);

根据 MSDN 文档,底层提供程序会分配一个不冲突的空闲端口号。
你的软件是用来测试机器人的仿真器。对我来说,并不需要遵循客户端硬件的规格。

实际上是有的,因为RoboSoftware正在发送到端口2053,并且需要在同一端口接收回复(请参见上面帖子中的附图)。而且这两个软件都在同一台计算机上。这就是让我困扰的地方。 - DForce

0
我已经解决了我的问题!我上面的想法的理论是正确的。
我发现我的前任在当前计算机上设置了一个UdpPortListener,用于监听所有可用的网络卡。
 IPEndPoint(IPAddress.Any, receivePort);

我已经设置了要监听的网络卡,它可以工作!结论是,永远不要对某人实现代码的方式(即使在纸上如何说)做出假设,并始终尝试进行一些“逆向工程”,以了解事物实际上是如何处理的!

感谢大家在这里帮助我!


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