同一台计算机上的套接字客户端和服务器能否绑定到同一端口



在我的情况下,我需要在同一台计算机上运行套接字客户端和服务器。

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

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

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

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端口来绑定)

不,这是套接字API的限制,并且会削弱基于TCP的对等应用程序的编写。

在对等应用程序中,自然的做法是对传出和传入连接都使用一个端口。虽然TCP协议支持此模型,但套接字API不支持此模型-如果套接字正在侦听端口p,则将活动套接字绑定到端口

p显而易见的解决方法是为传出连接使用临时端口(而不是在活动套接字上使用bind)。在某些情况下,这会导致其他问题,需要解决这些问题——例如,请参阅BEP-10中BitTorrent扩展握手中的p参数。

你在用什么?语言、框架、库。。。

通常,服务器在本地端口上侦听。客户端通常连接到它们,不会"阻止"它们。所以,从我的角度来看,不应该有什么问题。

来自man nc:

CLIENT/SERVER MODEL
It is quite simple to build a very basic client/server model using nc.  On
one console, start nc listening on a specific port for a connection.  For
example:
$ nc -l 1234
nc is now listening on port 1234 for a connection.  On a second console (or a
second machine), connect to the machine and port being listened on:
$ nc 127.0.0.1 1234

客户端和服务器肯定不能绑定到同一地址。bind()函数将返回-1,perlor()函数会打印"地址已在使用"错误消息。但为什么需要客户端和服务器绑定到同一个端口呢?通常客户端会选择一个随机端口与服务器通信,或者您可以绑定到服务器的不同端口。

最新更新