百科问答小站 logo
百科问答小站 font logo



一台主机上只能保持最多 65535 个 TCP 连接吗? 第1页

  

user avatar   sun-yiming-71-34 网友的相关建议: 
      

答案,不是的,下面讲个故事。


我是一个 Linux 服务器上的进程,名叫小进。老是有人说我最多只能创建 65535 个 TCP 连接。我不信这个邪,今天我要亲自去实践一下。我走到操作系统老大的跟前,说:"老操,我要建立一个 TCP 连接!"老操不慌不忙,拿出一个表格递给我,"小进,先填表吧"

我一看这个表,这不就是经典的socket 四元组嘛。我只有一块网卡,其 IP 地址是123.126.45.68,我想要与110.242.68.3的 80 端口建立一个 TCP 连接,我将这些信息填写在了表中。

源端口号填什么呢?我记得端口号是 16 位的,可以有 0 ~ 65535 这个范围的数字,那我随便选一个吧!正当我犹豫到底选什么数字的时候,老操一把抢过我的表格。"你墨迹个啥呢小进?源端口号不用你填,我会给你分配一个可用的数字。源IP也不用你填,我知道都有哪些网卡,并且会帮你选个合适的。真是个新手,回去等消息吧。""哦"老操带着我的表格,走了。过了很长时间,老操终于回来了,并且带着一个纸条。

"小进,你把这个收好了。"我问道,"这是啥呀?"老操不耐烦地说道,"刚刚说你是新手你还不服,这个 5 表示文件描述符,linux 下一切皆文件,你待会和你那个目标 IP 进行 TCP 通信的时候,就对着这个文件描述符读写就好啦。""这么方便!好的,谢谢老操。"我拿着这个文件描述符,把它放到属于我的内存中裱起来了,反正我只是想看看最多能创建多少 TCP 连接,又不是去真的用它,嘻嘻。

端口号

过了一分钟,我又去找老操了。"老操,我要建立一个 TCP 连接!"老操不慌不忙,拿出一个表格递给我,"小进,先填表吧"

这回我熟悉了,只把目标IP和目标端口填好。

老操办好事之后,又带着一个纸条回来,上面写着数字"6"。就这样,我每隔一分钟都去找老操建立一个新的 TCP 连接,目标 IP 都是110.242.68.3,目标端口都是 80。老操也很奇怪,不知道我在这折腾啥,他虽然权力大,但无权拒绝我的指令,每次都兢兢业业地把事情办好,并给我一张一张写着文件描述符的纸条。直到有一次,我收到的纸条有些不同。

我带着些许责怪的语气问,"老操,这是怎么回事呀?"老操也没好气地说,"这表示端口号不够用啦!早就觉得你小子不对劲了,一个劲地对着同一个 IP 和端口创建 TCP 连接,之前没办法必须执行你给的指令,现在不行了,端口号不够用了,源端口那里我没法给你填了。"我也不是那么好骗的,质疑道。"老操,你也别欺负我这个新手,我可是知道端口号是 16 位的,范围是 1~65535,一共可以创建 65535 个 TCP 连接,我现在才创建了 63977 个,怎么就不够了!"老操鄙视地看了我一眼,"你小子可真是闲的蛋疼啊,还真一个个数,来我告诉你吧,Linux 对可使用的端口范围是有具体限制的,具体可以用如下命令查看。"

       [root]# cat /proc/sys/net/ipv4/ip_local_port_range  1024 65000     

"看到没,当前的限制是1024~65000,所以你就只能有63977个端口号可以使用。"

我赶紧像老操道歉,"哎哟真是抱歉,还是我见识太少,那这个数可以修改么?"老操也没跟我一般见识,还是耐心地回答我,"可以的,具体可以 vim /etc/sysctl.conf 这个文件进行修改,我们在这个文件里添加一行记录"

       net.ipv4.ip_local_port_range = 60000 60009     

"保存好后执行 sysctl -p /etc/sysctl.conf 使其生效。这样你就只有 10 个端口号可以用了,就会更快报出端口号不够用的错误""原来如此,谢谢老操又给我上了一课。"哎不对,建立一个 TCP 连接,需要将通信两端的套接字(socket)进行绑定,如下:源 IP 地址:源端口号 <----> 目标 IP 地址:目标端口号只要这套绑定关系构成的四元组不重复即可,刚刚端口号不够用了,是因为我一直对同一个目标IP和端口建立连接,那我换一个目标端口号试试。

我又把这个表交给老操,老操一眼就看破了我的小心思,可是也没办法,马上去给我建立了一个新的TCP连接,并且成功返回给我一个新的文件描述符纸条。看来成功了,只要源端口号不用够用了,就不断变换目标 IP 和目标端口号,保证四元组不重复,我就能创建好多好多 TCP 连接啦!这也证明了有人说最多只能创建 65535 个TCP连接是多么荒唐。

文件描述符

找到了突破端口号限制的办法,我不断找老操建立TCP连接,老操也拿我没有办法。直到有一次,我又收到了一张特殊的纸条,上面写的不是文件描述符。

我又没好气地问老操,"这又是咋回事?"老操幸灾乐祸地告诉我,"呵呵,你小子以为突破端口号限制就无法无天了?现在文件描述符不够用啦!""怎么啥啥都有限制啊?你们操作系统给我们的限制也太多了吧?""废话,你看看你都建了多少个TCP连接了!每建立一个TCP连接,我就得分配给你一个文件描述符,linux 对可打开的文件描述符的数量分别作了三个方面的限制。"

系统级:当前系统可打开的最大数量,通过 cat /proc/sys/fs/file-max 查看

用户级:指定用户可打开的最大数量,通过 cat /etc/security/limits.conf 查看

进程级:单个进程可打开的最大数量,通过 cat /proc/sys/fs/nr_open 查看



天呢,真是人在屋檐下呀,我赶紧看了看这些具体的限制。

       [root ~]# cat /proc/sys/fs/file-max 100000 [root ~]# cat /proc/sys/fs/nr_open 100000 [root ~]# cat /etc/security/limits.conf ... * soft nproc 100000 * hard nproc 100000     

原来如此,我记得刚刚收到的最后一张纸条是。

再之后就收到文件描述符不够的错误了。我又请教老操,"老操,那这个限制可以修改么?"老操仍然耐心地告诉我,"当然可以,比如你想修改单个进程可打开的最大文件描述符限制为100,可以这样。"

       echo 100 > /proc/sys/fs/nr_open     

"原来如此,我这就去把各种文件描述符限制都改大一点,也不多,就在后面加个0吧""额,早知道不告诉你小子了。"老操再次用鄙视的眼睛看着我。

线程

突破了文件描述符限制,我又开始肆无忌惮地创建起了TCP连接。但我发现,老操的办事效率越来越慢,建立一个TCP连接花的时间越来越久。有一次,我忍不住责问老操,"你是不是在偷懒啊?之前找你建一个TCP连接就花不到一分钟时间,你看看最近我哪次不是等一个多小时你才搞好?"老操也忍不住了,"小进啊你还好意思说我,你知不知道你每建一个TCP连接都需要消耗一个线程来为你服务?现在我和CPU老大那里都忙得不可开交了,一直在为你这好几十万个线程不停地进行上下文切换,我们精力有限啊,自然就没法像以前那么快为你服务了。"

听完老操的抱怨,我想起了之前似乎有人跟我说过C10K问题,就是当服务器连接数达到 1 万且每个连接都需要消耗一个线程资源时,操作系统就会不停地忙于线程的上下文切换,最终导致系统崩溃,这可不是闹着玩的。我赶紧像操作系统老大请教,"老操,实在不好意思,一直以为你强大无比,没想到也有忙得不可开交的时候呀,那我们现在应该怎么办呀?"老操无奈地说,"我劝你还是别再继续玩了,没什么意义,不过我想你也不会听我的,那我跟你说两句吧。"你现在这种每建一个TCP连接就创建一个线程的方式,是最传统的多线程并发模型,早期的操作系统也只支持这种方式。但现在我进化了,我还支持 IO 多路复用的方式,简单说就是一个线程可以管理多个 TCP 连接的资源,这样你就可以用少量的线程来管理大量的 TCP 连接了。

我一脸疑惑,"啥是 IO 多路复用啊?"。老操一脸鄙视,"你这... 你去看看闪客的《你管这破玩意叫 IO 多路复用》,就明白了。"这次真是大开眼界了,我赶紧把代码改成了这种 IO 多路复用的模型,将原来的 TCP 连接销毁掉,改成同一个线程管理多个 TCP 连接,很快,操作系统老大就恢复了以往的办事效率,同时我的 TCP 连接数又多了起来。

内存

突破了端口号、文件描述符、线程数等重重限制的我,再次肆无忌惮地创建起了TCP连接。直到有一次,我又收到了一张红牌。

嗨,又是啥东西限制了呀,改了不就完了。我不耐烦地问老操,"这回又是啥毛病?"老操说道。"这个错误叫内存溢出,每个TCP连接本身,以及这个连接所用到的缓冲区,都是需要占用一定内存的,现在内存已经被你占满了,不够用了,所以报了这个错。"

我看这次老操特别耐心,也没多说什么,但想着被内存限制住了,有点不太开心,于是我让老操帮我最后一个忙。"老操呀,帮小进我最后一个忙吧,你权利大,你看看把那些特别占内存的进程给杀掉,给我腾出点地方,我今天要完成我的梦想,看看TCP连接数到底能创建多少个!"老操见我真的是够拼的,便答应了我,杀死了好多进程,我很是感动。

CPU

有了老操为我争取的内存资源,我又开始日以继日地创建TCP连接。老操也不再说什么,同样日以继日地执行着我的指令。有一次,老操语重心长地对我说,"差不多了,我劝你就此收手吧,现在 CPU 的占用率已经快到 100% 了。"

我觉得老操这人真的可笑,经过这几次的小挫折,我明白了只要思想不滑坡,方法总比苦难多,老操这人就是太谨慎了,我岂能半途而废,不管他。我仍然继续创建着 TCP 连接。直到有一天,老操把我请到一个小饭馆,一块吃了顿饭,吃好后说道。"咱哥俩也算是配合了很久啦,今天我是来跟你道个别的。"我很不解地问,"怎么了老操,发生什么事了?。"老操说,"由于你的 TCP 连接,CPU 占用率已经很长时间维持在 100%,我们的使用者,也就是我们的上帝,几乎什么事情都做不了了,连鼠标动一下都要等好久,所以他给我下达了一个重启的指令,我执行这个指令后,你,以及像你一样的所有进程,包括我这个操作系统本身,一切都就消失了。"我大惊失色,"啊,这么突然么?这条指令什么时候执行?"老操缓缓起身,"就现在了,刚刚这条指令还没得到 CPU 运行的机会,不过现在到了。"突然,我眼前一黑,一切都没了。

总结

资源 一台Linux服务器的资源 一个TCP连接占用的资源 占满了会发生什么
CPU 看你花多少钱买的 看你用它干嘛 电脑卡死
内存 看你花多少钱买的 取决于缓冲区大小 OOM
临时端口号 ip_local_port_range 1 cannot assign requested address
文件描述符 fs.file-max 1 too many open files
进程线程数 ulimit -n 看IO模型 系统崩溃

------------------------------------------ 追更 ----------------------------------------------

想不到突然获得这么多赞,其实我写的原文中还有后记部分,被我删了,因为有几个动图总是动不起来,大家感兴趣的话可以再看看原文哈。

最多能创建多少个 TCP 连接?


user avatar   netwarm007 网友的相关建议: 
      

感谢

@sxc

邀请。非常非常感谢。

为了防止邀请我的sxc老师撤销邀请,我不得不截图。


@朱峰女士,你的答案,为了防止你进行修改,我已经截图了。没错,如你问题当中所说,礼貌是不是软弱?

当然不是。

我自问是一个普通人,在知乎得到关注多,也只是因为我勤勤恳恳,一个字一个字写得多,仅此而已。

我去咕咚网之前,当过记者,做过公关,我也不是什么名校毕业,但是我深深知道,原创是品德,是节操。做记者,报道要如实,要客观,要中立,要还原事情的本来面目。

我为什么要在微信群“红包体育”里面和你抬杠,为什么要质问你,想必你已经不记得了,然而我记得清清楚楚。


我不关注你的微信号,那是有非常重要的原因的。朱峰女士,你说你没做过亏心事,那么想必在你看来,未经他人许可引用、转载他人原创的内容,不算是亏心事了。


你不记得的事情,我一点一点帮你回忆起来吧。事情当然没有这么简单。

当你加入“红包体育”的时候,我对群主说了一句话。【我很高兴,我有不删除任何聊天软件当中聊天记录的好习惯。】


这里截图当中的日期是一直就存在的。至今我的iPhone 4S也一直在用呢,不可能改掉。


你为什么和我说抱歉,你忘了?2015年3月3日你所说的,是真的都不记得了?


当时我的反应,算是很克制的了,毕竟当着“红包体育”群里这么多人的面。

为什么我过了这么久,才再次在“红包体育”群里质问你,我想你应该明白。我知道每个人做自媒体不容易,想靠着才华变现,更加不容易,当时你肯道歉,说你会改,那么我也就得过且过了。


问题的关键在于,你改了吗?如果你改了,你就不会不经过

@式微

同意,转载她的答案,而且还将她列为“第二作者”。

你的所谓声明,夹杂在你的正文内容当中,而不是正式开辟一个子栏目道歉,被诸多的信息噪声遮盖着,这就是你的诚意?

上述三张截图,是2015年6月17日早上8:43时截的。我现在还很怕诸多水军说我图片造假呢。下面两张图,是2015年3月3日晚上20:49时截的。那个时候,你的微信ID还没有“太阳表情”。

这个总不能说我作假了吧?



而你在面对我的质疑的时候,说了些什么话,你还记得吗?这就是我为什么要截图的原因。

二次编辑加了些东西,就可以等同于你自己的原创,是吗?


事实证明我当初心一软得过且过,才是真的错误。


你说了“最初开时,格式内容混乱,但转载内容标明了作者”——我还是那句话:用了我的东西,问过我吗?

你说了“微信对于转载格式有了新要求后,我们也跟着学习,把之前来源不明的全部删除。之后再也没有出现不合规的转载“——来源不明?请看看截图,你自己说过的话,怎么就这么快忘了呢?”是从虎扑、知乎、直播吧很多来源的文章“,这还算是来源不明?

你说了“暴力行为冠以道德名义,缺又恰恰选择了一个认真做事的自媒体下手,无论是出于要稿费,还是炒作涨粉,都不会实现的”——暴力冠以道德的名义?我质问你,就是暴力,你不告而拿,拿了我的答案,也拿了知乎上别人的答案,这种偷窃行为,就是道德的?


另外,请弄清楚,到底谁在炒作?我只是把原文作者式微老师带到了“体育红包”群,让她自己和你说清楚,这就是炒作?式微维护自己正当权益没有成功,自己写了篇专栏,以正视听,这叫炒作?

你说了“另外。。。您在背后诽谤我的许多聊天截图我已经给了律师。我们没做亏心事,我们礼貌但不软弱,真的,用法律途径解决,只对我们单方面有利啊。但您若真的要这样苦苦相逼,请也不吝给我一个您的地址,给您去一封律师函”。


我在背后诽谤你?请把截图放出来,让知乎用户都看看,我到底怎么诽谤你了。


你没做亏心事?没做亏心事我会质问你为什么不经过我允许转载了我的内容?


说我苦苦相逼?到底谁逼谁?“咕咚-李旸”是我在“红包体育”群里的ID,那是因为之前说过要标清楚所在的企业、媒体和姓名,所以我这样写。


我再说一次:质问你,是因为你在知乎未经我许可,擅自转载和引用了我的内容;我质问你,是因为你在知乎未经式微老师的许可,擅自转载和引用了式微老师的内容。


知乎上的回答问题,是我业余时间所为,工作忙的时候我只能下班回答问题,晚上写公众号内容,或者把知乎的答案放到我自己的公众号上去。关于足球篮球的内容,和咕咚网没有一点关系,全部是我自己的业余创作。


而你,直接找到了咕咚创始人、CEO申波先生,也就是我的最高领导,去质问我的行为是代表咕咚,还是代表个人。


我在知乎的ID和个人说明写得清清楚楚,没有和咕咚有任何的关联。你没有经过我个人的允许,转载引用我在知乎的内容,被我质疑你转载了别人的内容,居然好意思说是“法律层面的诽谤”?居然还去和我供职的企业对质?


到底是谁苦苦相逼?


所谓认真做事的自媒体,是把知乎用户的文字答案,变成自己的声音和话语,放到视频当中去,是吗?


所谓认真做事的自媒体,是未经他人许可,擅自转载、引用他人在知乎的原创答案,是吗?



最后我很想问一句:你既然深知自媒体人的成长有多么不易,为什么你还要去做“未经许可,擅自转载和引用其他自媒体人的内容”这样的事情?


最后,是我放出的所有截图的具体信息。



我在这里声明:我是知乎用户李暘,在知乎的每一个答案,在知乎的每一篇专栏文章,不敢保证完美无缺,逻辑严密,没有错别字,但全部是我自己的原创内容,任何人未经我许可,转载、引用、抄袭我的答案,即为侵权行为。




  

相关话题

  tcp 的可靠性到底指的是什么? 
  三次握手和http协议有什么关系吗? 
  保存在百度网盘(百度云)里的资料(视频,照片等),百度工作人员是怎么审查的,会不会泄露隐私?? 
  如今只使用TCP协议开发 实时多人在线网络游戏 可行吗? 
  现有的技术能否在同一个局域网内让一台电脑上正在进行的工作转移到另一台设备? 
  我想学网络信息安全,需要怎么做? 
  jpeg图片在网页中引用时为什么只能写成jpg? 
  从技术层面看,从客观现实出发,12306 逢节必瘫情有可原吗? 
  如何看待 HTTP/3 ? 
  socket套接字在多线程发送数据时要加锁吗? 

前一个讨论
如何看待女子醉酒倒地,遭老汉“捡尸”带回家性侵?如果是你遇到女性醉酒倒地昏睡,你会怎么做?
下一个讨论
河北一邮政公司职工因对工作不满,持刀杀害 3 名同事致死,具体发生了什么?嫌疑人将承担怎样的责任?





© 2024-12-26 - tinynew.org. All Rights Reserved.
© 2024-12-26 - tinynew.org. 保留所有权利