端口重用引发的惨案
时间:2011-09-09
来源:cnblogs
最近做个性能测试,需要在一台机器上启动很多客户端,连接到同一台服务器,我在一台机器上启动了六万个连接,于是,端口被占用完了。按照我的理解,因为我作用端口是作为客户端,应该不会影响到其它进程,于是我放心大胆地去做测试,结果就引发了悲剧。有服务器程序要用到5191端口,却显示端口被占用了,lsof看了下,居然只有我的进程占用了,完全颠覆我的惯性思想。服务端与客户端都有打开SO_REUSEADDR。
我们先来看看SO_REUSEADDR的说明:
SO_REUSEADDR可以用在以下四种情况下。
(摘自《Unix网络编程》卷一,即UNPv1)
1、当有一个有相同本地地址和端口的socket1处于TIME_WAIT状态时,而你启
动的程序的socket2要占用该地址和端口,你的程序就要用到该选项。
2、SO_REUSEADDR允许同一port上启动同一服务器的多个实例(多个进程)。但
每个实例绑定的IP地址是不能相同的。在有多块网卡或用IP Alias技术的机器可
以测试这种情况。
3、SO_REUSEADDR允许单个进程绑定相同的端口到多个socket上,但每个soc
ket绑定的ip地址不同。这和2很相似,区别请看UNPv1。
4、SO_REUSEADDR允许完全相同的地址和端口的重复绑定。但这只用于UDP的
多播,不用于TCP。
分析了一下,第二种情况比较相似,但第二种情况是针对同一服务器的多个实例(多个进程),很显然跟我的情况不一样。我是在客户端与服务端间争用端口。所以,我的情况根本就不适合以上任何一种情况,所以设置SO_REUSEADDR为1是无用的。
再接下来分析:
一个TCP连接需要由四元组来形成,即(src_ip,src_port,dst_ip,dst_port)。
假设有客户端建立了连接(src_ip1,src_port1,dst_ip1,dst_port1),那么,如果我们还有listen在(src_ip1,src_port1),那么当(dst_ip1,dst_port1)发送消息过来,系统应该把消息给谁?所以就说明了客户端占用了某一端口时,该端口就不能被其它进程listen了。
那么,对于有些童鞋,可能还有这样的疑问,是否一台机器就只能建立65535个连接了(端口16位限制)?非也,一个连接由四元组(src_ip,src_port,dst_ip,dst_port)形式,那么当(src_ip,src_port)一定时,变化的(dst_ip,dst_port)就可以建立更多连接了。
可能有些童鞋还有疑问,作为一个服务器监控一个端口,比如80端口,它为什么可以建立上百万个连接?首先要明白一点,当accept出来后的新socket,它所占用的本地端口依然是80端口,很多新手都以为是一个新的随机端口。由四元组就很容易分析到了,同一个(src_ip,src_port),它所对应的(dst_ip,dst_port)可以无穷变化,这样就可以建立很多个客户端的请求了。
以后遇到奇怪的问题,可以简单的采用四元组原理分析一下了。
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28