2024-06-04
分类:开发笔记
阅读(77) 评论(0)
引言
上一篇研究了,一台电脑最多可以开启多少个客户端进程?这一篇研究 一个服务器程序,最大支持的TCP连接数是多少?
如何确定一个TCP连接?
首先我们要知道TCP连接的本质在内核里面是一个socket对象。
查找linux内核源码net目录下
```
C
struct socket {
....
//INET域专用的一个socket表示, 提供了INET域专有的一些属性,比如 IP地址,端口等
struct sock *sk;
//TCP连接的状态:SYN_SENT、SYN_RECV、ESTABLISHED.....
short type;
....
};
struct inet_sock {
...
__u32 daddr; //IPv4的目标地址。
__u16 dport; //目标端口。
__u32 saddr; //源地址。
__u16 sport; //源端口。
...
};
```
我们发现socket对象本质上也是一个数据结构,里面包含了TCP四元组信息:源IP、源端口、目标IP、目标端口。 \|
![](https://img1.51tbox.com/static/2024-06-04/col/381b3afe652e8e75c5255d0cd498d61b/a65b2859eea147d0b1885e6f15494770.jpg)
所以一个TCP连接是由 【源IP、源端口、目标IP、目标端口】这四个信息确定的,有了这4个信息就能在系统内核当中找到这个socket对象。
服务器程序的IP和端口
一个服务器程序通常是监听一个端口号(也有监听多个端口的情况,我们这里只考虑监听一个端口),比如你开发的游戏程序,对外提供一个端口30188,客户端访问这个端口就可以进行登陆游戏操作。
![](https://img1.51tbox.com/static/2024-06-04/col/381b3afe652e8e75c5255d0cd498d61b/43c028a5ee034fa3a11f02ce2bed0792.jpg)
可以看到这个程序在30188端口进行监听,与此同时也能看到绑定了 0.0.0.0 IP地址。
所以一个服务器程序,它的IP地址和端口号是固定的(0.0.0.0:30188)
0.0.0.0 IP地址表示啥?为什么很多服务器程序绑定 0.0.0.0?
0.0.0.0 IP地址在互联网协议(IP)中是一个特殊的地址。它通常用于表示"本网络中的这个主机",即本地主机。在不同的上下文中,0.0.0.0有不同的含义:
服务器绑定:当服务器程序绑定到0.0.0.0地址时,它实际上是在告诉操作系统监听所有可用的网络接口上的入站连接。这意味着无论数据从哪个网络接口进入(比如以太网接口、Wi-Fi接口等),服务器都能接受这些连接。这样做可以让服务器接受来自任何网络接口的连接,从而确保不会因为绑定到特定的接口而错过任何连接请求。
路由:在路由环境中,0.0.0.0可能表示一个默认路由或者是一个无效的目的地址。默认路由指的是当路由表中没有匹配特定目的地址的路由条目时,数据包应该被发送到的路由器。
客户端配置:在某些客户端配置中,0.0.0.0可能用作一个占位符,表示没有有效的IP地址配置,或者表示客户端应该使用自动IP地址分配(比如DHCP)来获取IP地址。
安全:在安全设置中,0.0.0.0有时被用来表示不应该监听任何网络接口,或者不应该允许任何来自外部的连接。
当服务器程序绑定到0.0.0.0时,它能够更加灵活地服务于多个网络接口,这对于希望接受来自任何网络源的连接的服务器来说是非常有用的。同时,它也简化了服务器配置,因为不需要为每个网络接口单独配置监听端口。
一个服务器程序的理论最大TCP连接数
通过上面的内容我们可以知道:当客户端与服务端建立一条 TCP 连接的时候,这个 TCP 连接的四元组信息中服务端的 IP地址和端口号是固定的,能产生变化的就是客户端的 IP 地址和端口号了。
因此,一个服务器程序最大能支持的TCP连接个数应该是:
![](https://img1.51tbox.com/static/2024-06-04/col/381b3afe652e8e75c5255d0cd498d61b/6ae2f1c69d874b5ba54b0483a8114b64.jpg)
对于IPV4,客户端IP数最多为2的32次方,客户端端口数最多为2的16次方。
那么一个服务器程序的理论最大连接数为2的48次方,约等于两百万亿!
一个服务器程序的实际TCP连接数
实际上,一个服务器程序实际最大能支持的TCP连接数远不能达到理论值,还会受到文件描述符、内存等硬件方面的影响。
文件描述符限制
每个 TCP 连接都是一个文件,如果文件描述符被占满了,会发生 Too many open files。Linux 对可打开的文件描述符的数量分别做了三个方面的限制
系统级:当前系统可打开的最大数量,通过 cat /proc/sys/fs/file-max 查看;
用户级:指定用户可打开的最大数量,通过 cat /etc/security/limits.conf 查看;
进程级:单个进程可打开的最大数量,通过 cat /proc/sys/fs/nr_open 查看;
内存限制
每个 TCP 连接都要占用一定内存,操作系统的内存是有限的,如果内存资源被占满后,会发生 OOM
一条处于 ESTABLISH 状态的 空闲TCP 连接具体占用多大内存?
一个 TCP 对象占用的大小,等于它所包含的一些数据结构占用大小的总和,也就是把上面这些数据结构的大小累加起来,就是一个 TCP 连接占用的大小了。计算下来一天处于ESTABLISH状态的初始空闲的TCP连接占用的大小大概是3.44KB。
创建⼀个socket 需要消耗 densty、flip、sock_inode_cache、TCP 四个内核对象。这些对象加起来总共需消耗⼤约 3 KB 多⼀点的内存。如果连接上有数据收发的话,还需要消耗发送、接收缓存区。这两个缓存区占⽤内存影响因素⽐较多,既受收发数据的⼤⼩,也受 tcp_rmem、tcp_wmem 等内核参数,还取决于服务器进程能否 及时接收(及时接收的话缓存区就能回收)
![](https://img1.51tbox.com/static/2024-06-04/col/381b3afe652e8e75c5255d0cd498d61b/4784fd0607e546f2a92b187426314015.jpg)
8G内存实际支持的最大TCP连接数
每条空闲的TCP连接大约占3.44K的内存
那么8GB内存的服务器,最大支持的TCP连接数 = 8GB/3.44KB 约等于240万
但是实际生产环境,TCP连接很多都是活的,很难达到百万级别。
总结
\|------------------------\|
\| 一个服务器程序最大支持的TCP连接数是多少? \|
在不考虑服务器的内存和文件描述符的情况下,理论上一个服务端进程最多能支持约为 2 的 48 次方(2\^32 (ip数) \* 2\^16 (端口数),约等于两百多万亿!
在实际中很难达到理论值甚至相差甚远,每个 TCP 连接都是一个文件,会占用文件句柄资源,也会占用一定的内存空间。
题外话:
推荐候捷老师全套课程
![](https://img1.51tbox.com/static/2024-06-04/col/381b3afe652e8e75c5255d0cd498d61b/0fa91c1243254bfb9905ec3227eff302.jpg) **扫描下面二维码获取441F**
![](https://img1.51tbox.com/static/2024-06-04/col/381b3afe652e8e75c5255d0cd498d61b/3c6dd66e378c4132bd56b259b6acff5a.jpg)
众生皆苦,唯有自渡!