windows host 端口_TCP随机端口真的不能复用?

TCP的随机端口为什么不能像服务端口一样复用? 比如客户端发起一个HTTP请求。源端口是36000.目的IP是B 端口80。为什么这个源端口不能再继续复用给连接IP A的端口80的服务? 而服务端的服务端口则可以同时复用给N个连接上。服务端口到进程的对应貌似是有个重映射转接的动作,所以看起来可以复用。源端口为什么不行?   首先说结论,至少在Windows平台下,这个问题是错误的! 源端口一样可以复用端口,只是需要特殊的配置而已。为了证明这种可行性,特意用编了一段小代码。 主机在IP =“127.0.0.1”两个服务器进程,分别监听TCP 20001,20002端口,如下图所示: 685f0a63dbefa847565c6b8bedecdd81.png 然后,分 别启动两个客户端进程,两个客户端进程都使用指定TCP 端口号 = 50001,第一个客户端进程成功运行: 719c4ce5268d831bd105a8b4cd459a71.png 为何这里有两个“ESTABLISHED”连接状态?因为客户端与服务器跑在同一台主机上。 当运行第二个客户端进程时,遇到了麻烦,出错信息如下: builtins.OSError:[WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。 这个出错信息是预料之中,让我们修改一下以下代码。将两个客户端进程在绑定bind()“Socket”与“IP + 端口”之前调用一行代码,将“SO_REUSEADDR”从默认的0修改成1。 import socket LOCAL_HOST = '127.0.0.1' LOCAL_PORT = 50001 HOST = '127.0.0.1'     PORT = 20002         with socket.socket(socket.AF_INET,socket.SOCK_STREAM) as s: s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)  s.bind((LOCAL_HOST, LOCAL_PORT)) 然后重新运行两个客户端,看到了我们想要的结果: 1a75ed2d688700ff5ff302278cf5e5fe.png 两个客户端复用127.0.0.1的50001端口,分别连接127.0.0.1:20001,127.0.0.1:20002。 客户端运行在Windows 10操作系统,所以通过这一个小实验,证明题主的问题并不存在! 我们修改的参数是“SO_REUSEADDR”,是“Socket Option _Reuse Address”的缩写形式。翻译成中文,应该是重用IP地址的意思,可是我们不仅重用了IP地址,同时还重用了端口。这一切到底是怎么回事呢? 天下所有操作系统的Socket的源头都来自BSD(Berkeley SoftwareDistribution),而BSD是由大名鼎鼎的加州大学伯克利分校开发和发布的。 Windows操作系统在早期复制了BSD代码,代码中只包含“SO_REUSEADDR”而没有“SO_REUSEPORT”。 后来BSD又在代码里引入了“SO_REUSEPORT”选项,所以后期复制了BSD代码的FreeBSD/OpenBSD/NetBSD操作系统都支持“SO_REUSEPORT”选项。 后来Windows在自己的软件分支上做了代码升级,将其“SO_REUSEADDR”实现的功能与BSD分支上的“SO_REUSEPORT”雷同。所以在Windows平台上没有“SO_REUSEPORT”选项,但是“SO_REUSEADDR”的功能和“SO_REUSEPORT”的功能一致。 我们通 过浏览器上网时,通常并不使用bind()硬性指定浏览器使用的端口,而是由操作系统在空闲的(Available)的端口里挑选一个临时端口使用。 所谓空闲,是指该临时端口没有被其它TCP连接使用,也没有处于Time_Wait状态。 这样做的好处很多,就是永远都不会造成TCP四元组的冲突,毕竟四元组的其中一项:本地端口是唯一的(Unique)!所以四元组也会是唯一的! 而如果不这样做,而是使用端口重用技术,会遭遇四元组冲突的状况而出错。比如打开知乎主页会看到以下三个连接: a1aab4b06b20bce4089727b40acceeb8.png 其中第一、第二个连接的服务器IP = 118.89.204.190,端口 = 443是完全相同的。而本机的IP = 10.0.0.3也是相同的,剩下本地端口是唯一可以提供差别化的一个参数。幸运的是,第一个使用7180,第二个使用7183。这样这两个四元组就不会产生冲突。 如果这里重复使用端口7180,很显然第二个TCP连接会报错,然后用户会看到出错的页面,这肯定不是一个很好的选择! 一个主机理论上有65535个端口,有那么多选择,为何一定要复用7180端口? 最后一个问题,既然操作系统允许端口重用,这种功能一般用在什么场合?这是留给读者们的思考题!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值