首页 > 解决方案 > 同一台计算机上的套接字客户端和服务器可以绑定到同一个端口吗?

问题描述

就我而言,我需要在同一台计算机上运行套接字客户端和服务器。

udp socket客户端需要将本地端口绑定到1234,并与远程的socker服务器通信。而同一台计算机中的 udp 套接字服务器也需要将本地端口绑定到 1234,并且还将与远程端的套接字客户端进行通信。

可行吗?任何潜在的问题或通知?谢谢!

标签: linuxsockets

解决方案


如果您正在使用多播或广播 UDP 通信,那么将多个程序绑定到同一个 UDP 端口通常是有意义的,如果您在调用它setsockopt()之前使用适当的参数进行调用bind(),则可以这样做:

  const int trueValue = 1;
  setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &trueValue, sizeof(trueValue));
#ifdef __APPLE__
  setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &trueValue, sizeof(trueValue));
#endif

在这种情况下,在端口上接收到的每个多播/广播 UDP 数据包的副本将被传递到绑定到该端口的每个套接字(如果每个程序在单独的机器上运行,这与您将获得的行为大致相同,并且因此通常是你想要的)

OTOH,如果您只发送单播 UDP 数据包(即旨在发送给单个接收者的数据包),那么将多个程序绑定到同一个端口通常没有用,因为您发送的每个 UDP 数据包都将被一个接收者接收程序和多个程序监听同一个端口,哪个程序将是未指定/不可预测的。例如,在您的情况下,您的客户端程序可能会发送一个数据包而服务器不会收到它,因为该数据包已排队进入客户端的套接字缓冲区。因此,对于这种情况,您最好让客户端和服务器绑定到不同的端口。(请记住,任何接收 UDP 数据包的程序都可以通过调用轻松找出数据包的发送方绑定到的端口recvfrom()接收数据包并在之后查看address参数的内容;因此,即使客户端每次运行时都使用完全随机/任意的 UDP 端口,服务器也应该直接回复客户端发送给它的数据包。如果你告诉你的客户端到端bind()口 0,网络堆栈会选择一个当前可用的 UDP 端口来绑定)


推荐阅读