tcp知识总结

TCP报文格式

http://www.ywnds.com/?p=1273

TCP三次握手

TCP协议中,主动发起请求的一端称为『客户端』,被动连接的一 端称为『服务端』。不管是客户端还是服务端,TCP连接建立完后都能发送和接收数据。
起初,服务器和客户端都为CLOSED状态。在通信开始前,双方都得创建各自的传输控制块(TCB)。 服务器创建完TCB后便进入LISTEN状态,此时准备接收客户端发来的连接请求。
这里写图片描述

第一次握手

客户端向服务端发送连接请求报文段。该报文段的头部中
SYN=1,ACK=0, seq=x
请求发送后,客户端便进入SYN-SENT状态。
SYN=1,ACK=0表示该报文段为连接请求报文。
x为本次TCP通信的字节流的初始序号。
TCP规定:SYN=1的报文段不能有数据部分,但要消耗掉一个序号。

第二次握手

服务端收到连接请求报文段后,如果同意连接,则会发送一个应答:
SYN=1,ACK=1,seq=y,ack=x+1。
该应答发送完成后便进入SYN-RCVD状态。
SYN=1,ACK=1表示该报文段为连接同意的应答报文。
seq=y表示服务端作为发送者时,发送字节流的初始序号。
ack=x+1表示服务端希望下一个数据报发送序号从x+1开 始的字节。

第三次握手

当客户端收到连接同意的应答后,还要向服务端发送一个确认报文段,
表示:服务端发来的连接同意应答已经成功收到。
该报文段的头部为:ACK=1,seq=x+1,ack=y+1
客户端发完这个报文段后便进入ESTABLISHED状态,服务端收到这个应答后 也进入ESTABLISHED状态,此时连接的建立完成!

四次挥手

这里写图片描述

TCP连接的释放一共需要四步,因此称为『四次挥手』。 我们知道,TCP连接是双向的,因此在四次挥手中,前两次挥手用于断开一个方向的连接,后两次挥手用于断开另一方向的连接。

第一次挥手

若A认为数据发送完成,则它需要向B发送连接释放请求。该请求只有报文头,头中携带的主要参数为:
FIN=1,seq=u
此时,A将进入FIN-WAIT-1状态。
FIN=1表示该报文段是一个连接释放请求。
seq=u,u-1是A向B发送的后一个字节的序号。

第二次挥手

B收到连接释放请求后,会通知相应的应用程序,告诉它A向B这个方向的连接已经释放。
此时B进入CLOSE-WAIT状态,并向A发送连接释放的应答,其报文头包含:
ACK=1,seq=v,ack=u+1
ACK=1:除TCP连接请求报文段以外,TCP通信过程中所有数据报的ACK都为1,表示应答。
seq=v,v-1是B向A发送的后一个字节的序号。
ack=u+1,表示希望收到从第u+1个字节开始的报文段, 并且已经成功接收了前u个字节。
A收到该应答,进入FIN-WAIT-2状态,等待B发送连接释放请求。第二次挥手完成后,A到B方向的连接已经释放,B不会再接收数据,A也不会再发送数据。但B到A方向的连接仍然存在,B可以继续向A发送数据。

第三次挥手

当B向A发完所有数据后,向A发送连接释放请求,请求头:
FIN=1,ACK=1, seq=w,ack=u+1。
B便进入LAST-ACK状态。

第四次挥手

A收到释放请求后,向B发送确认应答,此时A进入TIME-WAIT状态。该状态会持续2MSL时间,若该时间段内没有B的重发请求的话,就进入CLOSED状 态,撤销TCB。当B收到确认应答后,也便进入CLOSED状态,撤销TCB。

为什么A要先进入TIME-WAIT状态,等待2MSL时间后才进入CLOSED 状态?

为了保证B能收到A的确认应答。 若A发完确认应答后直接进入CLOSED状态,那么如果该应答丢失,B等待超时后就会重新发送连接释放请求,但此时A已经关闭了,不会作出任何响应, 因此B永远无法正常关闭。

tcp的四个计时器

重传计时器(Retransmission Timer):

目的:为了控制丢失的报文段或者丢弃的报文段。这段时间为对报文段的等待确认时间。
创建时间:在TCP发送报文段时(ACK / send)会创建对次特定报文段的重传计时器。

在截止时间(通常为60秒)到之前,已经收到了对此特定报文段的确认,则撤销计时器;
在截止时间到了,但未收到对此特定报文段的确认,则重传报文段,并且将计时器复位。
重传时间:2*RTT(Round Trip Time,为往返时间)

坚持计时器(Persistent Timer):

目的:主要解决零窗口大小通知可能导致的死锁问题

死锁问题的产生:当接收端的窗口大小为0时,接收端向发送 端发送一个零窗口报文段,发送端即停止向对端发送数据。此 后,如果接收端缓存区有空间则会重新给发送端发送一个窗口大小,即窗口更新。但接收端发送的这个确认报文段有可能会丢失,而此时接收端不知道已经丢失并认为自己已经发送成功,则一直处于等待数据的状态;而发送端由于没有收到该确认报文 段,就会一直等待对方发来新的窗口大小,这样一来,双方都处在等待对方的状态,这样就形成了一种死锁问题。如果没有应对 措施,这种局面是不会被打破的。为了解决这种问题,TCP为每一个连接设置了坚持计时器。

工作原理:当发送端TCP收到接收端发来的零窗口通知时,就会启动坚持计时器。当计时器的期限到达时,发送端就会主动发送一个特殊的报文段告诉对方确认已经丢失,必须重新发送。

【这个特殊的报文段就称为探测报文段,探测报文段只有1个字节 的大小,里边只有一个序号,该序号不需要被确认,甚至在计算 其他部分数据的确认时该序号会被忽略。】 截止期的设置:设置为重传时间的值。但如果没有收到接收 端的响应,则会发送另一个探测报文段,并将计时器的值加倍并 复位,直到大于门限值(一般为60秒)。在此之后,发送端会每 隔60秒发送一个探测报文段,直到窗口重新打开

保活计时器(Keeplive Timer):

目的:主要是为了防止两个TCP连接出现长时间的空闲。

当客 户端与服务器端建立TCP连接后,很长时间内客户端都没有向服务器端发送数据,此时很有可能是客户端出现故障,而服务器端会 一直处于等待状态。保活计时器就是解决这种问题而生的。 工作原理:每当服务器端收到客户端的数据时,都将保活计时器重新设置(通常设置为2小时)。过了2小时后,服务器端如 果没有收到客户端的数据,会发送探测报文段给客户端,并且每隔75秒发送一个,当连续发送10次以后,仍没有收到对端的来 信,则服务器端认为客户端出现故障,并会终止连接。

时间等待计时器(Time_Wait Timer):

时间等待计时器是在连接终止期间使用的。
当TCP关闭连接时并不是立即关闭的,在等待期间,连接还处于过渡状态。这样就可以使重复的FIN报文段在到达终点之后被丢弃。 时间设置:一般为报文段寿命期望值的2倍。

生产过程调优(三次握手期间)

修改Linux内核参数来减少Squid服务器的TIME_WAIT套接字数量

#vim /etc/sysctl.conf 

net.ipv4.tcp_syncookies=1
#表示开启SYN Cookies。当出现SYN等待队列溢出 时,启用cookie来处理,可防范少量的SYN攻击。默认为0,表示关闭。 

net.ipv4.tcp_tw_reuse=1 
#表示开启重用。允许将TIME-WAIT套接字重新用于新 的TCP连接。默认为0,表示关闭。 

net.ipv4.tcp_tw_recycle=1 
#表示开启TCP连接中TIME-WAIT套接字的快速回 收。默认为0,表示关闭。 

net.ipv4.tcp_fin_timeout=30 
#表示如果套接字由本端要求关闭,这个参数决定 了它保持在FIN-WAIT-2状态的时间。 

net.ipv4.tcp_keepalive_time=1200 
#表示当keepalive启用时,TCP发送 keepalive消息的频度。默认是2小时,这里改为20分钟。 

net.ipv4.ip_local_port_range=1024 65000 
#表示向外连接的端口范围。默认值很 小:32768~61000,改为1024~65000。 

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

net.ipv4.tcp_max_tw_buckets=5000 
#表示系统同时保持TIME_WAIT套接字的 大数量,如果超过这个数 字,TIME_WAIT套接字将立刻被清除并打印警告信 息。默认为180000,改为5000。 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值