首先,在同一台服务器上同时使用UDP和TCP有什么问题吗?
其次,我可以使用相同的端口号吗?
是的,您可以对 TCP 和 UDP 使用相同的端口号。许多协议已经这样做了,例如 DNS 在 udp/53 和 tcp/53 上工作。
从技术上讲,每个协议的端口池是完全独立的,但对于可以使用 TCP 或 UDP 的更高级别协议,约定它们默认使用相同的端口number。
编写服务器时,请记住 TCP 套接字的事件顺序比 UDP 套接字要困难得多,因为除了正常的
socket
和 bind
调用之外,您还必须 listen
和 accept
。
此外,
accept
调用将返回一个新的套接字,然后您还必须轮询该套接字以接收事件。您的服务器应该准备好继续在原始套接字上建立连接,同时为多个客户端提供服务,每个客户端将在自己的套接字上触发接收事件。
首先,在服务器上使用tcp和udp都没有问题。
快速
在 Ubuntu 23.10 上进行了测试,
nc
来自 netcat-openbsd 软件包,基于我的其他答案:https://stackoverflow.com/a/52351480/895245我们可以启动一个简单的服务器,永远在 TCP 端口 8000 上侦听与:
nc
从 nc -kdl 8000
我们知道
man nc
标志使用 UDP 而不是 TCP,让我们尝试从另一个 shell 中使用
-u
同时启动另一个侦听器:-u
现在,我们可以将消息发送到 TCP 或 UDP,并且正确的侦听器将始终收到消息,对于 TCP:
nc -kdlu 8000
对于 UDP:
echo asdf | nc localhost 8000
然后相应的侦听器将
echo asdf | nc -u localhost 8000
打印到标准输出。
检查两者是否实际上在同一端口号但在不同域上侦听的另一种方法是:
asdf
给出:
sudo netstat -tupan | grep 8000
然而,如果我们在有或没有
tcp 0 0 0.0.0.0:8000 0.0.0.0:* LISTEN 214312/nc
udp 0 0 0.0.0.0:8000 0.0.0.0:* 227612/nc
的情况下启动另外两个侦听器,我只是在编写此答案时才了解到一个复杂的因素:
-u
nc -kdl 8000
nc -kdlu 8000
不会抱怨。这是因为我们可以看到
nc
,
strace
是用 bind
完成的,相关线程:
netcat如何从两个不同的终端监听同一主机上的同一端口?SO_REUSEPORT
nc
给出:
netstat
当我们发送请求时,TCP 和 UDP 请求会随机路由到相应类型的两个侦听器之一。