为什么 TCP 允许多个程序绑定同一个 IP 和端口?

2021-04-07 14:48:36 +08:00
 3dwelcome

在 Windows 上,这显然是不允许的,你可以用多个 IP 分别绑定同一个 PORT,但是不允许同一个 IP+PORT 被多次绑定。

在 Linux 上,以前也是不允许,但后来修改了内核,从 3.9 开始,TCP 变得和 UDP 一样,可以多个程序同时监听同一个 IP+端口。

这样的话,只要你有服务器 ROOT 权限,开一个和 nginx 一样的 80 端口程序,就可以开心和他抢数据了。

1029 次点击
所在节点    问与答
10 条回复
hxndg
2021-04-07 14:57:19 +08:00
为啥不允许呢? TCP 五元组啊,只要能在 TCP 上层区分开到底该交给谁,为啥不能绑定同一个端口呢?
我司复杂均衡,自己实现 2-7 层,我们自己维护 PCB,实现的时候完全可以共享端口。
当然前提是 PCB 自己维护,也就是筛选数据包给谁自己维护
3dwelcome
2021-04-07 15:16:05 +08:00
@hxndg UDP 我能理解,包是单独的,最终给谁都能直接处理。
可 TCP 是流式数据,怎么切分成小包,是底层决定的,又不是由程序决定的。
比如 HTTP 你程序负载均衡,只拿到用户 HTTP 请求中间那么一小段,也没办法处理啊。
hxndg
2021-04-07 16:12:27 +08:00
@3dwelcome
首先,负载均衡可以坐在四层也可以坐在七层
其次,你可以自己维护负载均衡,也可以让系统底层维护负载均衡。还是那句话五元组可以区分开具体该交给哪个线程了。
lwn.net 上的介绍 https://lwn.net/Articles/542629/
hxndg
2021-04-07 16:15:28 +08:00
你搞混了两个概念,一个是 TCP 的分包,一个是负载均衡。两个是完全不同的概念
直接看这个网址吧,说的够简单了 https://medium.com/uckey/so-reuseport-addr-2-2-how-packets-forwarded-to-multiple-sockets-ce4b83cd0fd2
3dwelcome
2021-04-08 01:02:49 +08:00
@hxndg "还是那句话,TCP 五元组可以区分开具体该交给哪个线程了。"
不对啊。
我百度搜了一下,五元祖就是源 IP+源端口+目标 IP+目标端口,可并不是唯一的,很容易就被中间 NAT 修改了( https://www.liangzl.com/get-article-detail-227271.html)

那么很有可能,到具体线程里,两条不同 TCP 通道,源 IP+源端口+目标 IP+目标端口是一样的。
首先 SO_REUSEPORT 会确保在多条 TCP 通道里,本机 IP 和本地绑定端口是一致的。
其次 NAT 下面多条 TCP 通道里,发起 IP 和发起的端口是有可能冲突的(端口只有双字节上限,而 NAT 下面可以扩展很多电脑,每台电脑对相同服务器端口发出请求,总有电脑总连接数超过 65535,就必然会造成 TCP 五元组冲突)
hxndg
2021-04-08 07:47:31 +08:00
算了,你说的都对,你开心就好
3dwelcome
2021-04-08 09:49:04 +08:00
@hxndg 我只是好奇讨论一下。
一般情况,一台 PC 确实只有 2 万多个客户端连接端口可用(默认 net.ipv4.ip_local_port_range = 32768 61000)。就算不用 IPV4,改用 IPV6,协议也没增加任何端口上限,还是 16bit 给写死了。
所以如果这台 PC,刚巧是 NAT 出口,就会遇到本机端口耗尽的情况。TCP 五元祖冲突应该不会,就是 TCP 连接直接失败。
julyclyde
2021-04-08 12:15:35 +08:00
能理解你的提问的人都不太多
建议你还是把“3.9 开始”那个功能的原文发上来
SmartKeyerror
2021-04-08 17:23:54 +08:00
@hxndg 我寻思着 TCP 包里面只包含源端口号+目的端口号,IP 包里面才是源 IP 地址 + 目的 IP 地址,TCP 区分接收程序难道不是通过端口号区分的? TCP 上层是个什么东西?
hxndg
2021-04-08 17:43:02 +08:00
@SmartKeyerror
四层负载均衡和七层负载均衡的区别,自定协议和非自定协议而已
而且协议栈如果自己写,想干什么干什么,为什么不能拿到五元组呢?
如果只能利用端口号区分,那么多的负载均衡公司都是在扯淡吗?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/768717

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX