导航:首页 > 操作系统 > linuxtcp长连接

linuxtcp长连接

发布时间:2023-09-03 20:52:57

㈠ 请问linux怎么增大socket连接上限

1、修改用户进程可打开文件数限制
在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,
最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统
为每个TCP连接都要创建一个socket句柄,每个socket句柄同时也是一个文件句柄)。
可使用ulimit命令查看系统允许当前用户进程打开的文件数限制:
[speng@as4 ~]$ ulimit -n
1024
这表示当前用户的每个进程最多允许同时打开1024个文件,这1024个文件中还得除去
每个进程必然打开的标准输入,标准输出,标准错误,服务器监听 socket,
进程间通讯的unix域socket等文件,那么剩下的可用于客户端socket连接的文件数就
只有大概1024-10=1014个左右。也就是说缺省情况下,基于Linux的通讯程序最多允许
同时1014个TCP并发连接。
对于想支持更高数量的TCP并发连接的通讯处理程序,就必须修改Linux对当前用户的
进程同时打开的文件数量的软限制(soft limit)和硬限制(hardlimit)。其中软限制
是指Linux在当前系统能够承受的范围内进一步限制用户同时打开的文件数;硬限制
则是根据系统硬件资源状况(主要是系统内存)计算出来的系统最多可同时打开的文件数量。
通常软限制小于或等于硬限制。

修改上述限制的最简单的办法就是使用ulimit命令:
[speng@as4 ~]$ ulimit -n
上述命令中,在中指定要设置的单一进程允许打开的最大文件数。如果系统回显
类似于“Operation notpermitted”之类的话,说明上述限制修改失败,实际上是
因为在中指定的数值超过了Linux系统对该用户打开文件数的软限制或硬限制。
因此,就需要修改Linux系统对用户的关于打开文件数的软限制和硬限制。

第一步,修改/etc/security/limits.conf文件,在文件中添加如下行:
speng soft nofile 10240
speng hard nofile 10240
其中speng指定了要修改哪个用户的打开文件数限制,可用’*'号表示修改所有用户的限制;
soft或hard指定要修改软限制还是硬限制;10240则指定了想要修改的新的限制值,
即最大打开文件数(请注意软限制值要小于或等于硬限制)。修改完后保存文件。

第二步,修改/etc/pam.d/login文件,在文件中添加如下行:
session required /lib/security/pam_limits.so
这是告诉Linux在用户完成系统登录后,应该调用pam_limits.so模块来设置系统对
该用户可使用的各种资源数量的最大限制(包括用户可打开的最大文件数限制),
而pam_limits.so模块就会从/etc/security/limits.conf文件中读取配置来设置这些限制值。
修改完后保存此文件。

第三步,查看Linux系统级的最大打开文件数限制,使用如下命令:
[speng@as4 ~]$ cat /proc/sys/fs/file-max
12158
这表明这台Linux系统最多允许同时打开(即包含所有用户打开文件数总和)12158个文件,
是Linux系统级硬限制,所有用户级的打开文件数限制都不应超过这个数值。通常这个系统级
硬限制是Linux系统在启动时根据系统硬件资源状况计算出来的最佳的最大同时打开文件数限制,
如果没有特殊需要,不应该修改此限制,除非想为用户级打开文件数限制设置超过此限制的值。

修改此硬限制的方法是修改/etc/rc.local脚本,在脚本中添加如下行:
echo 22158 > /proc/sys/fs/file-max
这是让Linux在启动完成后强行将系统级打开文件数硬限制设置为22158。修改完后保存此文件。

完成上述步骤后重启系统,一般情况下就可以将Linux系统对指定用户的单一进程允许同时
打开的最大文件数限制设为指定的数值。如果重启后用 ulimit-n命令查看用户可打开文件数限制
仍然低于上述步骤中设置的最大值,这可能是因为在用户登录脚本/etc/profile中使用ulimit -n命令
已经将用户可同时打开的文件数做了限制。由于通过ulimit-n修改系统对用户可同时打开文件的
最大数限制时,新修改的值只能小于或等于上次 ulimit-n设置的值,因此想用此命令增大这个
限制值是不可能的。
所以,如果有上述问题存在,就只能去打开/etc/profile脚本文件,
在文件中查找是否使用了ulimit-n限制了用户可同时打开的最大文件数量,如果找到,
则删除这行命令,或者将其设置的值改为合适的值,然后保存文件,用户退出并重新登录系统即可。
通过上述步骤,就为支持高并发TCP连接处理的通讯处理程序解除关于打开文件数量方面的系统限制。
2、修改网络内核对TCP连接的有关限制
在Linux上编写支持高并发TCP连接的客户端通讯处理程序时,有时会发现尽管已经解除了系统
对用户同时打开文件数的限制,但仍会出现并发TCP连接数增加到一定数量时,再也无法成功
建立新的TCP连接的现象。出现这种现在的原因有多种。

第一种原因可能是因为Linux网络内核对本地端口号范围有限制。此时,进一步分析为什么无法
建立TCP连接,会发现问题出在connect()调用返回失败,查看系统错误提示消息是“Can’t assign requestedaddress”。同时,如果在此时用tcpmp工具监视网络,会发现根本没有TCP连接时客户端
发SYN包的网络流量。这些情况说明问题在于本地Linux系统内核中有限制。
其实,问题的根本原因
在于Linux内核的TCP/IP协议实现模块对系统中所有的客户端TCP连接对应的本地端口号的范围
进行了限制(例如,内核限制本地端口号的范围为1024~32768之间)。当系统中某一时刻同时
存在太多的TCP客户端连接时,由于每个TCP客户端连接都要占用一个唯一的本地端口号
(此端口号在系统的本地端口号范围限制中),如果现有的TCP客户端连接已将所有的本地端口号占满,
则此时就无法为新的TCP客户端连接分配一个本地端口号了,因此系统会在这种情况下在connect()
调用中返回失败,并将错误提示消息设为“Can’t assignrequested address”。
有关这些控制
逻辑可以查看Linux内核源代码,以linux2.6内核为例,可以查看tcp_ipv4.c文件中如下函数:
static int tcp_v4_hash_connect(struct sock *sk)
请注意上述函数中对变量sysctl_local_port_range的访问控制。变量sysctl_local_port_range
的初始化则是在tcp.c文件中的如下函数中设置:
void __init tcp_init(void)
内核编译时默认设置的本地端口号范围可能太小,因此需要修改此本地端口范围限制。
第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:
net.ipv4.ip_local_port_range = 1024 65000
这表明将系统对本地端口范围限制设置为1024~65000之间。请注意,本地端口范围的最小值
必须大于或等于1024;而端口范围的最大值则应小于或等于65535。修改完后保存此文件。
第二步,执行sysctl命令:
[speng@as4 ~]$ sysctl -p
如果系统没有错误提示,就表明新的本地端口范围设置成功。如果按上述端口范围进行设置,
则理论上单独一个进程最多可以同时建立60000多个TCP客户端连接。

第二种无法建立TCP连接的原因可能是因为Linux网络内核的IP_TABLE防火墙对最大跟踪的TCP
连接数有限制。此时程序会表现为在 connect()调用中阻塞,如同死机,如果用tcpmp工具监视网络,
也会发现根本没有TCP连接时客户端发SYN包的网络流量。由于 IP_TABLE防火墙在内核中会对
每个TCP连接的状态进行跟踪,跟踪信息将会放在位于内核内存中的conntrackdatabase中,
这个数据库的大小有限,当系统中存在过多的TCP连接时,数据库容量不足,IP_TABLE无法为
新的TCP连接建立跟踪信息,于是表现为在connect()调用中阻塞。此时就必须修改内核对最大跟踪
的TCP连接数的限制,方法同修改内核对本地端口号范围的限制是类似的:

第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:
net.ipv4.ip_conntrack_max = 10240
这表明将系统对最大跟踪的TCP连接数限制设置为10240。请注意,此限制值要尽量小,
以节省对内核内存的占用。

第二步,执行sysctl命令:
[speng@as4 ~]$ sysctl -p
如果系统没有错误提示,就表明系统对新的最大跟踪的TCP连接数限制修改成功。
如果按上述参数进行设置,则理论上单独一个进程最多可以同时建立10000多个TCP客户端连接。

3、使用支持高并发网络I/O的编程技术
在Linux上编写高并发TCP连接应用程序时,必须使用合适的网络I/O技术和I/O事件分派机制。
可用的I/O技术有同步I/O,非阻塞式同步I/O(也称反应式I/O),以及异步I/O。在高TCP并发的情形下,
如果使用同步I/O,这会严重阻塞程序的运转,除非为每个TCP连接的I/O创建一个线程。

但是,过多的线程又会因系统对线程的调度造成巨大开销。因此,在高TCP并发的情形下使用
同步 I/O是不可取的,这时可以考虑使用非阻塞式同步I/O或异步I/O。非阻塞式同步I/O的技术包括使用select(),poll(),epoll等机制。异步I/O的技术就是使用AIO。

从I/O事件分派机制来看,使用select()是不合适的,因为它所支持的并发连接数有限(通常在1024个以内)。
如果考虑性能,poll()也是不合适的,尽管它可以支持的较高的TCP并发数,但是由于其采用
“轮询”机制,当并发数较高时,其运行效率相当低,并可能存在I/O事件分派不均,导致部分TCP
连接上的I/O出现“饥饿”现象。而如果使用epoll或AIO,则没有上述问题(早期Linux内核的AIO技术
实现是通过在内核中为每个 I/O请求创建一个线程来实现的,这种实现机制在高并发TCP连接的情形下
使用其实也有严重的性能问题。但在最新的Linux内核中,AIO的实现已经得到改进)。

综上所述,在开发支持高并发TCP连接的Linux应用程序时,应尽量使用epoll或AIO技术来实现并发的
TCP连接上的I/O控制,这将为提升程序对高并发TCP连接的支持提供有效的I/O保证。

内核参数sysctl.conf的优化

/etc/sysctl.conf 是用来控制linux网络的配置文件,对于依赖网络的程序(如web服务器和cache服务器)
非常重要,RHEL默认提供的最好调整。

推荐配置(把原/etc/sysctl.conf内容清掉,把下面内容复制进去):
net.ipv4.ip_local_port_range = 1024 65536
net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.ipv4.tcp_rmem=4096 87380 16777216
net.ipv4.tcp_wmem=4096 65536 16777216
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_window_scaling = 0
net.ipv4.tcp_sack = 0
net.core.netdev_max_backlog = 30000
net.ipv4.tcp_no_metrics_save=1
net.core.somaxconn = 262144
net.ipv4.tcp_syncookies = 0
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2

这个配置参考于cache服务器varnish的推荐配置和SunOne 服务器系统优化的推荐配置。

varnish调优推荐配置的地址为:http://varnish.projects.linpro.no/wiki/Performance

不过varnish推荐的配置是有问题的,实际运行表明“net.ipv4.tcp_fin_timeout = 3”的配置
会导致页面经常打不开;并且当网友使用的是IE6浏览器时,访问网站一段时间后,所有网页都会
打不开,重启浏览器后正常。可能是国外的网速快吧,我们国情决定需要
调整“net.ipv4.tcp_fin_timeout = 10”,在10s的情况下,一切正常(实际运行结论)。

修改完毕后,执行:
/sbin/sysctl -p /etc/sysctl.conf
/sbin/sysctl -w net.ipv4.route.flush=1

命令生效。为了保险起见,也可以reboot系统。

调整文件数:
linux系统优化完网络必须调高系统允许打开的文件数才能支持大的并发,默认1024是远远不够的。

执行命令:
Shell代码
echo ulimit -HSn 65536 >> /etc/rc.local
echo ulimit -HSn 65536 >>/root/.bash_profile
ulimit -HSn 65536

㈡ linux查看tcp连接数

linux怎么查看tcp连接数?我们一起来了解一下吧。
1、打开linux系统,在linux的桌面的空白处右击。

2、在弹出的下拉选项里,点击打开终端。

3、输入netstat-n|awk'/^tcp/{++S[$NF]}END{for(ainS)printa,S[a]}'可以查看tcp的各个数据。
本文章基于ThinkpadE15品牌、centos7系统撰写的。

㈢ linux服务器tcp连接数过大怎么办

不管是什么系统的服务器,客户连接到服务器的最明显的看出来就是TCP的显示。
一般分为两种情况:
1.CC攻击的表现情况
CC攻击会造成访问量增大,带宽图上的代表TCP访问量(红色)会忽然不正常的增高。CPU的占用量增大,然后造成打开慢或者卡死的情况。
所以看到如果是TCP,突然增大的话,证明你的服务器在遭受CC攻击,可以联系服务器商,让机房做下防御策略。
2.如果TCP的连接量一直在一个区域一直很大的话,那检查服务器的资源,可能无法支撑访问量,需要更大的资源,更高的配置支持。

㈣ Linux系统支持的最大TCP连接是多少

1.首先,客户端和服务器建立的每个TCP连接都会占用服务器内存,所以最大TCP连接数和内存成正比。简单估算为最大内存除以单TCP连接占用的最小内存
2.Linux操作系统中,一切都是文件。所以每个TCP连接,都会打开一个文件。为此Linux操作系统限制了每个用户能打开的文件数量,通过ulimit -n 查看。修改方式:
vi /etc/security/limits.conf文件,在文件中添加如下行(限制修改为10240):
speng soft nofile 10240
speng hard nofile 10240
3.Linux操作系统中,TCP连接数量还受到端口数量限制,由于端口号只有1-65535,所以最大TCP连接数也只有65535个(包括系统端口1-1024)
4.Linux操作系统对所有用户最大能打开文件的限制:cat /proc/sys/fs/file-max。
5.网络核心模块对tcp连接的限制(最大不能超过65535):
vi /etc/sysctl.conf
net.ipv4.ip_local_port_range = 1024 65000
6.防火墙对tcp连接的限制
综上,在Linux操作系统中,首先对TCP连接数量的限制依次有:端口数量限制,网络核心限制,最大文件数量限制(因为每建立一个连接就要打开一个文件),防火墙限制,用户打开文件限制
都是传智播客出版的书上的知识,他们官网也都有。可以去官网多看看视频学学。

㈤ 有人说linux的TCP连接数量最大不能超过65535个吗,是真的吗

linux的TCP连接数量最大不能超过65535个,这种说法是错误的。

基于以上的原因,在Linux操作系统中,对TCP连接数量的限制依次有:端口数量限制,网络核心限制,最大文件数量限制(因为每建立一个连接就要打开一个文件),防火墙限制,用户打开文件限制。但并不存在65535这个数量限制。

㈥ 畅谈linux下TCP(上)

tcp 协议 是互联网中最常用的协议 , 开发人员基本上天天和它打交道,对它进行深入了解。 可以帮助我们排查定位bug和进行程序优化。下面我将就TCP几个点做深入的探讨

客户端:收到 ack 后 分配连接资源。 发送数据
服务器 : 收到 syn 后立即 分配连接资源

客户端:收到ACK, 立即分配资源
服务器:收到ACK, 立即分配资源

既然三次握手也不是100%可靠, 那四次,五次,六次。。。呢? 其实都一样,不管多少次都有丢包问题。

client 只发送一个 SYN, server 分配一个tcb, 放入syn队列中。 这时候连接叫 半连接 状态;如果server 收不到 client 的ACK, 会不停重试 发送 ACK-SYN 给client 。重试间隔 为 2 的 N 次方 叠加(2^0 , 2^1, 2^2 ....);直至超时才释放syn队列中的这个 TCB;
在半连接状态下, 一方面会占用队列配额资源,另一方面占用内存资源。我们应该让半连接状态存在时间尽可能的小

当client 向一个未打开的端口发起连接请求时,会收到一个RST回复包

当listen 的 backlog 和 somaxconn 都设置了得时候, 取两者min值

Recv-Q 是accept 队列当前个数, Send-Q 设置最大值

这种SYN洪水攻击是一种常见攻击方式,就是利用半连接队列特性,占满syn 队列的 资源,导致 client无法连接上。
解决方案:

为什么不像握手那样合并成三次挥手? 因为和刚开始连接情况,连接是大家都从0开始, 关闭时有历史包袱的。server(被动关闭方) 收到 client(主动关闭方) 的关闭请求FIN包。 这时候可能还有未发送完的数据,不能丢弃。 所以需要分开。事实可能是这样

当然,在没有待发数据,并且允许 Delay ACK 情况下, FIN-ACK合并还是非常常见的事情,这是三次挥手是可以的。

同上

CLOSE_WAIT 是被动关闭方才有的状态

被动关闭方 [收到 FIN 包 发送 ACK 应答] 到 [发送FIN, 收到ACK ] 期间的状态为 CLOSE_WAIT, 这个状态仍然能发送数据。 我们叫做 半关闭 , 下面用个例子来分析:

这个是我实际生产环境碰到的一个问题,长连接会话场景,server端收到client的rpc call 请求1,处理发现请求包有问题,就强制关闭结束这次会话, 但是 因为client 发送 第二次请求之前,并没有去调用recv,所以并不知道 这个连接被server关闭, 继续发送 请求2 , 此时是半连接,能够成功发送到对端机器,但是recv结果后,遇到连接已经关闭错误。

如果 client 和 server 恰好同时发起关闭连接。这种情况下,两边都是主动连接,都会进入 TIME_WAIT状态

1、 被动关闭方在LAST_ACK状态(已经发送FIN),等待主动关闭方的ACK应答,但是 ACK丢掉, 主动方并不知道,以为成功关闭。因为没有TIME_WAIT等待时间,可以立即创建新的连接, 新的连接发送SYN到前面那个未关闭的被动方,被动方认为是收到错误指令,会发送RST。导致创建连接失败。

2、 主动关闭方断开连接,如果没有TIME_WAIT等待时间,可以马上建立一个新的连接,但是前一个已经断开连接的,延迟到达的数据包。 被新建的连接接收,如果刚好seq 和 ack字段 都正确, seq在滑动窗口范围内(只能说机率非常小,但是还是有可能会发生),会被当成正确数据包接收,导致数据串包。 如果不在window范围内,则没有影响( 发送一个确认报文(ack 字段为期望ack的序列号,seq为当前发送序列号),状态变保持原样)

TIME_WAIT 问题比较比较常见,特别是CGI机器,并发量高,大量连接后段服务的tcp短连接。因此也衍生出了多种手段解决。虽然每种方法解决不是那么完美,但是带来的好处一般多于坏处。还是在日常工作中会使用。
1、改短TIME_WAIT 等待时间

这个是第一个想到的解决办法,既然等待时间太长,就改成时间短,快速回收端口。但是实际情况往往不乐观,对于并发的机器,你改多短才能保证回收速度呢,有时候几秒钟就几万个连接。太短的话,就会有前面两种问题小概率发生。

2、禁止Socket lingering

这种情况下关闭连接,会直接抛弃缓冲区中待发送的数据,会发送一个RST给对端,相当于直接抛弃TIME_WAIT, 进入CLOSE状态。同样因为取消了 TIME_WAIT 状态,会有前面两种问题小概率发生。

3、tcp_tw_reuse
net.ipv4.tcp_tw_reuse选项是 从 TIME_WAIT 状态的队列中,选取条件:1、remote 的 ip 和端口相同, 2、选取一个时间戳小于当前时间戳; 用来解决端口不足的尴尬。

现在端口可以复用了,看看如何面对前面TIME_WAIT 那两种问题。 我们仔细回顾用一下前面两种问题。 都是在新建连接中收到老连接的包导致的问题 , 那么如果我能在新连接中识别出此包为非法包,是不是就可以丢掉这些无用包,解决问题呢。

需要实现这些功能,需要扩展一下tcp 包头。 增加 时间戳字段。 发送者 在每次发送的时候。 在tcp包头里面带上发送时候的时间戳。 当接收者接收的时候,在ACK应答中除了TCP包头中带自己此时发送的时间戳,并且把收到的时间戳附加在后面。也就是说ACK包中有两个时间戳字段。结构如下:

那我们接下来一个个分析tcp_tw_reuse是如何解决TIME_WAIT的两个问题的

4、tcp_tw_recycle

tcp_tw_recycle 也是借助 timestamp机制。顾名思义, tcp_tw_reuse 是复用 端口,并不会减少 TIME-WAIT 数量。你去查询机器上TIME-WAIT 数量,还是 几千几万个,这点对有强迫症的同学感觉很不舒服。tcp_tw_recycle 是 提前 回收 TIME-WAIT资源。会减少 机器上 TIME-WAIT 数量。

tcp_tw_recycle 工作原理是。

阅读全文

与linuxtcp长连接相关的资料

热点内容
华为云服务器登录密码和账号 浏览:154
中世纪java程序员 浏览:786
什么开发引擎使用python 浏览:176
sh脚本运行命令 浏览:316
广联达加密锁怎么看到期 浏览:172
cad轨迹命令 浏览:979
同事刷到女程序员自媒体视频 浏览:571
校验算法的缺点是什么 浏览:717
PHP商品分类功能实现 浏览:330
php取字符串中间 浏览:432
程序员经常用工具 浏览:837
降服主力指标源码主图 浏览:502
python实用库 浏览:693
电脑默认7个文件夹 浏览:13
新唐单片机安装c51后编译错误 浏览:532
红包源码引流神器 浏览:235
学生初中毕业撕书解压 浏览:748
命令方块刷铜点教学 浏览:691
php邮件订阅系统 浏览:999
柱梁底加密箍间距 浏览:31