深入解析Linux TCP更大包长度及其对网络性能的影响 (linux tcp 更大包长度)

在计算机网络中,TCP协议是一个非常重要的协议,它负责传输应用程序之间的数据,并保证数据的正确性和可靠性。TCP协议在数据传输时采用了分段算法,将大块数据分成若干个小块,然后将每个小块封装成一个单独的TCP报文段进行传输。其中,每个报文段都需要包含TCP首部和数据部分。在Linux系统中,TCP报文段的更大长度由MTU和MSS两个参数决定。本文将。

一、MTU和MSS的概念

MTU是网络中数据包能通过的更大长度,它包括数据链路层的头和尾等信息。MSS则是TCP协议中,TCP报文段能通过的更大长度,它通常为MTU减去IP和TCP首部之后的长度。MTU的大小通常取决于网络环境,例如以太网的MTU为1500字节,而在一些WAN网络中MTU要小于这个值。

二、TCP更大包长度的影响因素

在TCP协议中,传输的数据通常会被分割成若干个TCP报文段进行传输。TCP报文段的长度对网络性能有着重要的影响。如果一个TCP报文段的长度过大,就会造成以下几种影响:

1. 资源浪费:当TCP报文段的长度超过MTU时,就需要对其进行分片处理。这会增加网络通信的负担和网络传输的开销,使得传输效率变低。

2. 网络拥塞:当网络流量过大时,TCP包可能会被丢失、延迟或乱序到达。如果一个TCP报文段的长度过大,就会使得这些问题更加严重,增加网络拥塞的可能性,导致网络性能下降。

3. TCP滑动窗口问题:TCP报文段的长度还会影响TCP滑动窗口的大小。当TCP报文段的长度过大时,滑动窗口就会变得更小,从而会对网络传输的速率产生限制。

三、如何优化TCP报文段的长度

针对以上几种问题,我们可以通过以下几种方法来优化TCP报文段的长度:

1. 调整MTU值:在不同的网络环境中,MTU值可能有所不同。如果我们能够合理地调整MTU值,就能够减少网络通信的负担,提高网络传输的速率。

2. 调整MSS值:TCP报文段的长度通常由MTU和MSS两个参数决定。如果我们调整MSS的大小,就能够有效地限制TCP报文段的更大长度,从而降低网络拥塞的可能性。

3. 采用分片重组算法:如果一个TCP报文段的长度超过MTU的大小,就需要对其进行分片处理。为了提高网络传输的速率,我们可以采用分片重组算法,将分散的数据包重组成一个完整的TCP报文段。

四、小结

在计算机网络中,TCP协议是一个非常重要的协议,它负责传输应用程序之间的数据,而TCP报文段的长度对网络传输的速率和稳定性有着重要的影响。在Linux系统中,TCP报文段的更大长度由MTU和MSS等参数决定,我们可以通过调整这些参数的大小,并采用分片重组算法等方法来优化TCP传输的效率和稳定性,从而提高网络性能。

相关问题拓展阅读:

java TCP传输数据有没有大小限制,有,是多少,没有,为什么?

学习下

MTU更大传输单元,这个更大传输单枯则元实际上和链路层协议有着密切的关系,EthernetII帧的结构DMAC+AC+Type+Data+CRC由于以太网传输电气方面的限制,每个以太网帧都有最小的大小64bytes更大不能超过1518bytes,对于小于或者大于这个限制的以太网帧我们都可以视之为错误的数据帧,一般的以太网转发设备会丢弃这些数据帧。

由于以太网EthernetII更大的数据帧是1518Bytes这样,刨去以太网帧的帧头(DMAC目的MAC地址48bit=6Bytes+AC源MAC地址48bit=6Bytes+Type域2bytes)14Bytes和帧尾CRC校验部分4Bytes那么剩下承载上层协议的地方也就是Data域更大就只能有1500Bytes这个值我们就把它称之为MTU。

PPPoE所谓PPPoE就是在以太网上面跑PPP协议,有人奇怪了,PPP协议和Ethernet不都是链路层协议吗?怎么一个链路层跑到另外一个链路层上面去了,难道升级成网络层协议了不成。其实这是个误区:就是某层协议只能承载更上一层协议。

为什么会产生这种奇怪的需求呢?这是因为随着宽带接入(这种宽带接入一般为Cable Modem或者xDSL或者以太网的接入),因为以太网缺乏认证计费机制而传统运营商是通过PPP协议来对拨号等接入服务进行认证计费的.

PPPoE带来了好处,也带来了一些坏处,比如:二次封装耗费资源,降低了传输效能等等,这些坏处俺也不多说了,更大的坏处就是PPPoE导致MTU变小了以太网的MTU是1500,再减去PPP的包头包尾的开销(8Bytes),就变成1492。

UDP 包的大小就应该是IP头(20) – UDP头(8) = 1464(BYTES)

TCP 包的大小就应该是IP头(20) – TCP头(20) = 1452(BYTES)

目前大多数的路由设备的MTU都为1500

我对上面的理解是:如果我们定义的TCP和UDP包小于1452,1464,那么我们的包在IP层就不用分包了,这样传输过程中就避免了在IP层组包发生的错误。如果使用UDP协议,如果IP层组包发生错误,那么包就会被丢弃,UDP不保证可靠传输。但是TCP发生没含棚组包错误时,该包会被重传老段,保证可靠传输。所以,我们在用Socket编程时,包的大小设定不一定非要小于1400,UDP协议要求包小于64K,TCP没有限定

有速度限制,没有大小限制,在linux里可以配置限速。

一般优化linux的内核,需要优化什么参数

首先要知道一点所有的TCP/IP的参数修改是临时的,因为它们都位于/PROC/SYS/NET目录下,如果想使参数长期保存,可以通过编辑/ETC/SYSCTL.CONF文件来实现,这里不做详细说明,只针对Linux的TCPIP内核参数优化列举相关参数:

1、为自动调优定义socket使用的内存

2、默认的TCP数据接收窗口大小(字节)

3、更大的TCP数据接收窗口

4、默认的TCP发送窗口大小

5、更大的TCP数据发送窗口

6、在每个网络接口接收数据包的速率比内核处理这些包速率快时,允许送到队列的数据包更大数目

7、定义了系统中每一个端口更大的监听队列长度

8、探测消息未获得相应时,重发该消息的间隔时间

9、在认定tcp连接失效之前,最多发送多少个keepalive探测消息等。

相关优化参数代码:

sh#  net.core.wmem_default 发送缓存区预留内存默认大小 默认值 16k

#  net.core.rmem_default 接受缓存区预留内存默认大小 默认值 16k

#  net.core.wmem_max 发送缓存区预留内存更大值 默认值 128k

#  net.core.rmem_max 接受缓存区预留内存更大值 默认值 128k

#  net.unix.max_dgram_qlen 进程间通信发送数据, 默认10

#  net.ipv4.tcp_syncookies

#  net.ipv4.syn_retries

#  net.ipv4.tcp_fin_timeout 如果socket连接由本端关闭,则保持在FIN-WAIT-2状态的时间

#  net.ipv4.tcp_keepalive_time 当keepalive起作用的时候,tcp发送keepalive消息的频度,默认2小时

#  net.ipv4.route_max_size 路由缓存更大值

首先要知道一点所有的TCP/IP的参数修改是临时的,因为它们都位于/PROC/SYS/NET目录下,如果想使参数长期保存,可以通过编辑/ETC/SYSCTL.CONF文件来实现,这里不做详细说明,只针对Linux的TCPIP内核参数优化列举相关参数:

1、为自动调优定义socket使用的内存

2、默认的TCP数据接收窗口大小(字节)

3、更大的TCP数据接收窗口

4、默认的TCP发送窗口大小

5、更大的TCP数据发送窗口

6、在每个网络接口接收数据包的速率比内核处理这些包速率快时,允许送到队列的数据包更大数目

7、定义了系统中每一个端口更大的监听队列长度

8、探测消息未获得相应时,重发该消息的间隔时间

9、在认定tcp连接失效之前,最多发送多少个keepalive探测消息等。

相关优化参数代码:

sh#  net.core.wmem_default 发送缓存区预留内存默认大小 默认值 16k

#  net.core.rmem_default 接受缓存区预留内存默认大小 默认值 16k

#  net.core.wmem_max 发送缓存区预留内存更大值 默认值 128k

#  net.core.rmem_max 接受缓存区预留内存更大值 默认值 128k

#  net.unix.max_dgram_qlen 进程间通信发送数据, 默认10

#  net.ipv4.tcp_syncookies

#  net.ipv4.syn_retries

#  net.ipv4.tcp_fin_timeout 如果socket连接由本端关闭,则保持在FIN-WAIT-2状态的时间

#  net.ipv4.tcp_keepalive_time 当keepalive起作用的时候,tcp发送keepalive消息的频度,默认2小时

#  net.ipv4.route_max_size 路由缓存更大值

方法只对拥有大量TIME_WAIT状态的连接导致系统资源消耗有效,如果不是这种情况下,效果可能不明显。可以使用netstat命令去查TIME_WAIT状态的连接状态,输入下面的组合命令,查看当前TCP连接的状态和对应的连接数量:

#netstat -n | awk ‘/^tcp/ {++S} END {for(a in S) print a, S}’

这个命令会输出类似下面的结果:

LAST_ACK 16

SYN_RECV 348

ESTABLISHED 70

FIN_WAIT1 229

FIN_WAIT2 30

CLOSING 33

TIME_WAIT 18098

我们只用关心TIME_WAIT的个数,在这里可以看到,有18000多个TIME_WAIT,这样就占用了18000多个端口。要知道端口的数量只有65535个,占用一个少一个,会严重的影响到后继的新连接。这种情况下,我们就有必要调整下Linux的TCP内核参数,让系统更快的释放TIME_WAIT连接。

用vim打开配置文件:#vim /etc/sysctl.conf

在这个文件中,加入下面的几行内容:

net.ipv4.tcp_syncookies = 1

net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_tw_recycle = 1

net.ipv4.tcp_fin_timeout = 30

输入下面的命令,让内核参数生效:#sysctl -p

简单的说明上面的参数的含义:

net.ipv4.tcp_syncookies = 1

#表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;

net.ipv4.tcp_tw_reuse = 1

#表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;

net.ipv4.tcp_tw_recycle = 1

#表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭;

net.ipv4.tcp_fin_timeout

#修改系统默认的 TIMEOUT 时间。

在经过这样的调整之后,除了会进一步提升服务器的负载能力之外,还能够防御小流量程度的DoS、CC和SYN攻击。

此外,如果你的连接数本身就很多,我们可以再优化一下TCP的可使用端口范围,进一步提升服务器的并发能力。依然是往上面的参数文件中,加入下面这些配置:

net.ipv4.tcp_keepalive_time = 1200

net.ipv4.ip_local_port_range =

net.ipv4.tcp_max_syn_backlog = 8192

net.ipv4.tcp_max_tw_buckets = 5000

#这几个参数,建议只在流量非常大的服务器上开启,会有显著的效果。一般的流量小的服务器上,没有必要去设置这几个参数。

net.ipv4.tcp_keepalive_time = 1200

#表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。

net.ipv4.ip_local_port_range =

#表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为10000到65000。(注意:这里不要将更低值设的太低,否则可能会占用掉正常的端口!)

net.ipv4.tcp_max_syn_backlog = 8192

#表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。

net.ipv4.tcp_max_tw_buckets = 6000

#表示系统同时保持TIME_WAIT的更大数量,如果超过这个数字,TIME_WAIT将立刻被清除并打印警告信息。默 认为180000,改为6000。对于Apache、Nginx等服务器,上几行的参数可以很好地减少TIME_WAIT套接字数量,但是对于Squid,效果却不大。此项参数可以控制TIME_WAIT的更大数量,避免Squid服务器被大量的TIME_WAIT拖死。

内核其他TCP参数说明:

net.ipv4.tcp_max_syn_backlog = 65536

#记录的那些尚未收到客户端确认信息的连接请求的更大值。对于有128M内存的系统而言,缺省值是1024,小内存的系统则是128。

net.core.netdev_max_backlog = 32768

#每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的更大数目。

net.core.somaxconn = 32768

#web应用中listen函数的backlog默认会给我们内核参数的net.core.somaxconn限制到128,而nginx定义的NGX_LISTEN_BACKLOG默认为511,所以有必要调整这个值。

net.core.wmem_default =

net.core.rmem_default =

net.core.rmem_max = #更大socket读buffer,可参考的优化值:873200

net.core.wmem_max = #更大socket写buffer,可参考的优化值:873200

net.ipv4.tcp_timestps = 0

#时间戳可以避免序列号的卷绕。一个1Gbps的链路肯定会遇到以前用过的序列号。时间戳能够让内核接受这种“异常”的数据包。这里需要将其关掉。

net.ipv4.tcp_synack_retries = 2

#为了打开对端的连接,内核需要发送一个SYN并附带一个回应前面一个SYN的ACK。也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送SYN+ACK包的数量。

net.ipv4.tcp_syn_retries = 2

#在内核放弃建立连接之前发送SYN包的数量。

#net.ipv4.tcp_tw_len = 1

net.ipv4.tcp_tw_reuse = 1

# 开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接。

net.ipv4.tcp_wmem =73200

# TCP写buffer,可参考的优化值:73200

net.ipv4.tcp_rmem =873200

# TCP读buffer,可参考的优化值:873200

net.ipv4.tcp_mem =

# 同样有3个值,意思是:

net.ipv4.tcp_mem:低于此值,TCP没有内存压力。

net.ipv4.tcp_mem:在此值下,进入内存压力阶段。

net.ipv4.tcp_mem:高于此值,TCP拒绝分配socket。

上述内存单位是页,而不是字节。可参考的优化值是:

net.ipv4.tcp_max_orphans =

#系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。

如果超过这个数字,连接将即刻被复位并打印出警告信息。

这个限制仅仅是为了防止简单的DoS攻击,不能过分依靠它或者人为地减小这个值,

更应该增加这个值(如果增加了内存之后)。

net.ipv4.tcp_fin_timeout = 30

关于linux tcp 更大包长度的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。


数据运维技术 » 深入解析Linux TCP更大包长度及其对网络性能的影响 (linux tcp 更大包长度)