详解Linux下TCP连接,未写完

一、服务器端最大TCP连接数

       在tcp应用中,server端事先在某个固定端口监听,client端主动发起连接,经过三次握手后建立tcp连接。那么对于单个服务器,可接受的最大TCP连接是多少?

如何标识一个TCP连接,由四元组标识{目标IP,目标端口,源IP,源端口}。在server端,IP与端口是固定的,因此从理论上,可以有2^32 * 2^16个不同标识。ipv4是32位,port是16位。

上面所说是一个server端监听一个端口,理论上可以有的标识,但是,在实际环境中,受到计算资源(CPU)、操作系统(文件描述符、缓存、连接队列等)等的限制,肯定是达不到这个理论值。

一、文件句柄的限制

在Linux下,所有的东西都是文件,一个socket连接也是一个文件,因此也会占用一个文件描述符,需要明白操作系统对文件描述符的限制。

  • 单个进程限制

        对于一个进程而言最多只能打开1024个文件,所以你要采用此默认配置最多也就可以并发上千个TCP连接。但是可以进行修改

  • 全局限制

在 /proc/sys/fs/file-nr 可以看到系统的配置,我的机器上显示的是:1024 0 198652。

分别为:1.已经分配的文件句柄数,2.已经分配但没有使用的文件句柄数,3.最大文件句柄数。在kernel 2.6版本中第二项的值总为0,这并不是一个错误,它实际上意味着已经分配的文件描述符无一浪费的都已经被使用了。

我们可以把最大句柄数值改大些,用 root权限修改 /etc/sysctl.conf

经过上面的修改,不去考虑内存等,server端可以接受TCP连接可以提高到百万级别。

二、发送与接受缓冲区

在 /proc/sys/net/ipv4/下面,可以查到单个socket需要的缓冲区,默认最小是4k,有时候实际值会比其小一些。

怎么知道当前内存是否紧张或充分呢?这是通过 tcp_mem 配置完成的:

cat /proc/sys/net/ipv4/tcp_mem

22566    30090    45132
上⾯三个数字单位不是字节,而是页面大小,是4kb,大于第 3 个值时,内核不再为 TCP 分配新内存,此时新连接是无法建立的; 45132*4kb/4k = 45132,即socket的缓存区在最小区域时候,可以有4w多的连接。依旧,调大 tcp_mem 的上限可以让 TCP 连接使⽤更多的系统内存,也可以增大连接数量。

如果业务再多一点的话,对于CPU的消耗也是很需要考虑的。

三、全连接队列,半连接队列

在 TCP 三次握⼿的时候,Linux 内核会维护两个队列,

分别是: 半连接队列,也称 SYN 队列; 全连接队列,也称 accepet 队列;

服务端收到客户端发起的 SYN 请求后,内核会把该连接存储到半连接队列,并向客户端响应 SYN+ACK,接着客 户端会返回 ACK,

服务端收到第三次握⼿的 ACK 后,内核会把连接从半连接队列移除,然后创建新的完全的连 接,并将其添加到 accept 队列,等待进程调⽤ accept 函数时把连接取出来。

当服务端并发处理⼤量请求时,如果 TCP 全连接队列过⼩,就容易溢出。发⽣ TCP 全连接队溢出的时候,后续的请求就会被丢弃,这样就会出现服务端请求数量上不去的现象。

可以自己测试,全连接队列最大值,半连接最大值都可以修改。

TCP 全连接队列最⼤值默认为 128,三万次连接请求,会有很多次溢出,就会造成连接上不去的情况。

增⼤到 5000 后,服务端抗住了 3 万连接并发请求,也没有发⽣全连接队列溢 出的现象了。

四、总结

因此,在单机server端上,只监听一个端口,通过修改最大文件描述符个数,修改缓存区可用大小,修改全连接半连接队列,并且socket不进行复杂的交流,保持空连接,我们是可以达到百万级别的并发数的。

二、客户端可以发起的连接数。

同server端一样,TCP也是需要四元组进行标识。我们所考虑的是,去连接同一个server端,也就是目标IP是固定的。这样的话,理论上不同的标识有 2^16 * 2^16个。限制和server端一样,有文件描述符个数、缓冲区等的限制,同时,还需要考虑端口的限制。

一、端口号范围限制

操作系统上端口号1024以下是系统保留的,从1024-65535是用户使用的。由于每个TCP连接都要占一个端口号,所以我们最多可以有60000多个并发连接。

在Linux中,ip_local_port_range,默认只是32768-65000,修改这个值,因此不修改这个的话,并发连接只有3w,修改后可以达到6w。

二、允许客户端用多个IP,

如果客户端有多个IP,那么在socket链接时候,就可以扩大多倍,因为socket连接是四元组标识

三、允许server端用多个端口,

同二,也可以扩大多倍,因为一个socket连接是用四元组标识的,所以改变其中一个,就可以分辨是不同的连接。举个例子:

原先  IP1 port1 IP2 port2  改变对方端口  IP1 port1 IP2 port 3,客户端端口复用

四、总结

经过上面的分析,在socket空连接的时候,也是可以达到百万级别。

三、TCP连接时,滑动窗口问题

四、TCP三次握手、四次挥手

五、TCP与UDP的区别

你可能感兴趣的:(随手看到的记录,计算机网络,tcp/ip,linux,服务器)