单机如何实现百万并发TCP连接

单机如何实现百万并发TCP连接,第1张

一开始我无法理解,单机怎么可能实现百万并发连接,因为系统可用端口数只有:65535 - 1024 = 64511,每个TCP连接需要占用一个独立的端口,那最多也只能做到6W多并发连接。然而我忽视了一个很基本的问题,端口号在同一个IP下不能重复,但我们可以给一个网卡绑定多个IP地址,如果单机要主动发起100万并发连接,我们最少需要使用17个IP地址。

TCP服务器监听在指定端口接收客户端连接后,创建一个新的socket用于同客户端进行读写数据,但该socket并不需要也不会绑定一个新的端口,所以对于TCP服务器来说,不存在端口不够用的情况,TCP服务器能够保持多少个并发连接取决于服务器性能、内存大小、带宽大小以及服务器端设置(例如:进程能打开的文件数等)。以100W连接数为例,所需要总内存大小大约为:1,000,000 20K = 20G, 广播一个1KB的消息需要占用的带宽:1,000,000 1K = 1000M,所需打开文件描述符1,000,000个。

对于TCP服务器连接数压力测试来说,瓶颈在客户端,因为每个客户端要连接到TCP服务端需要使用一个本地端口,而对于一个IP地址来说,端口范围就是:0-65536,其中还要一些端口被系统或其他程序使用。所以从一台主机单个IP上发起同TCP服务器的连接数理论最大值为65535,当然我们可以给该主机绑定N个IP地址,同时从多个IP发起连接,所以理论上客户端可以发起的连接数为:IP数*65535,这时客户端的CPU、内存和带宽以及文件句柄资源就是限制。

线程是相对独立的执行单位,是计算机系统进行调度的最小单位,其切换由操作系统控制,称之为短作业调度。换句话说您没有任何必要去手动调度线程。如果您想要实现的是连接分配的话,请参考您的操作系统的进程间通信和同步文档,一般底层编程都是通过共享存储区,消息队列等方式实现的。如果是高层次的库实现网络通信,请参考库文档,比如C#和Java都提供了足够的接口实现此类功能。

大家都知道各类网络服务器程序的编写步骤,并且都知道网络服务器就两大类:循环服务和并发服务。这里附上源代码来个小结吧。

一、 循环服务

循环网络服务器编程实现的步骤是这样的:

建立socket(这里用到socket()函数及函数setsockopt())

|

|

\|/

把socket和IP地址及端口绑定(这里用到bind函数)

|

|

\|/

开始监听(这里用到listen()函数)

|

|

/\

/\

\ / \

----------------------- | 有连接|

| / \ /

| \ /

| \ /

| |

| 接受新的连接(这里用到accept()函数)

| | /___________________________________________________

| | \|

| \|/ |

| 从连接里读取数据(这里用到recv()系统函数,当然也可以是read()函数) |

|||

| ||

| \|/ |

| 返回信息给连接(这里用到send()系统函数,当然也可以是write()函数)|

| ||

| ||

| /\ |

| /\ |

| / \ |

| | 还有数据 |-Y-------------------------------------------------------

| \ /

| \ /

| \ /

|_______________________________|

这种服务器模型是典型循环服务,如果不加上多进程/线程技术,此种服务吞吐量有限,大家都可以看到,如果前一个连接服务数据没有收发完毕后面的连接没办法处理。所以一般有多进程技术,对一个新连接启用一个新进程去处理,而监听socket继续监听。

/


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/281662.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-21
下一篇2023-04-21

发表评论

登录后才能评论

评论列表(0条)

    保存