文章目录
一、TCP包头
字段 | 长度 | 含义 |
---|---|---|
Source Port | 16比特 | 源端口,标识哪个应用程序发送。 |
Destination Port | 16比特 | 目的端口,标识哪个应用程序接收。 |
Sequence Number | 32比特 | 序号字段。TCP链接中传输的数据流中每个字节都编上一个序号。序号字段的值指的是本报文段所发送的数据的第一个字节的序号。 |
Acknowledgment Number | 32比特 | 确认号,是期望收到对方的下一个报文段的数据的第1个字节的序号,即上次已成功接收到的数据字节序号加1。只有ACK标识为1,此字段有效。 |
Data Offset | 4比特 | 数据偏移,即首部长度,指出TCP报文段的数据起始处距离TCP报文段的起始处有多远,以32比特(4字节)为计算单位。最多有60字节的首部,若无选项字段,正常为20字节。 |
Reserved | 6比特 | 保留,必须填0。 |
URG | 1比特 | 紧急指针有效标识。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。 |
ACK | 1比特 | 确认序号有效标识。只有当ACK=1时确认号字段才有效。当ACK=0时,确认号无效。 |
PSH | 1比特 | 标识接收方应该尽快将这个报文段交给应用层。接收到PSH = 1的TCP报文段,应尽快的交付接收应用进程,而不再等待整个缓存都填满了后再向上交付。 |
RST | 1比特 | 重建连接标识。当RST=1时,表明TCP连接中出现严重错误(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立连接。 |
SYN | 1比特 | 同步序号标识,用来发起一个连接。SYN=1表示这是一个连接请求或连接接受请求。 |
FIN | 1比特 | 发端完成发送任务标识。用来释放一个连接。FIN=1表明此报文段的发送端的数据已经发送完毕,并要求释放连接。 |
Window | 16比特 | 窗口:TCP的流量控制,窗口起始于确认序号字段指明的值,这个值是接收端正期望接收的字节数。窗口最大为65535字节。 |
Checksum | 16比特 | 校验字段,包括TCP首部和TCP数据,是一个强制性的字段,一定是由发端计算和存储,并由收端进行验证。在计算检验和时,要在TCP报文段的前面加上12字节的伪首部。 |
Urgent Pointer | 16比特 | 紧急指针,只有当URG标志置1时紧急指针才有效。TCP的紧急方式是发送端向另一端发送紧急数据的一种方式。紧急指针指出在本报文段中紧急数据共有多少个字节(紧急数据放在本报文段数据的最前面)。 |
Options | 可变 | 选项字段。TCP协议最初只规定了一种选项,即最长报文段长度(数据字段加上TCP首部),又称为MSS。MSS告诉对方TCP“我的缓存所能接收的报文段的数据字段的最大长度是MSS个字节”。新的RFC规定有以下几种选型:选项表结束,无操作,最大报文段长度,窗口扩大因子,时间戳。窗口扩大因子:3字节,其中一个字节表示偏移值S。新的窗口值等于TCP首部中的窗口位数增大到(16+S),相当于把窗口值向左移动S位后获得实际的窗口大小。时间戳:10字节,其中最主要的字段是时间戳值(4字节)和时间戳回送应答字段(4字节)。选项确认选项: |
Padding | 可变 | 填充字段,用来补位,使整个首部长度是4字节的整数倍。 |
data | 可变 | TCP负载。 |
二、TCP的三次握手
第一次握手: 建立连接时,客户端发送SYN同步请求到服务器,即将SYN位置为1,序列号seq=x,并进入同步已发送状态。
第二次握手: 服务器收到SYN同步请求,回复确认ACK,同时自己也发送SYN同步请求,序列号seq=y,确认号ack=x+1,并进入同步已接收状态。
第三次握手: 客户端收到之后,再向服务器发送确认ACK,序列号seq=x+1,确认号ack=y+1,进入连接已建立状态。
追问:为什么TCP需要三次握手?
如果TCP的握手是两次:
<1>如果client发给server的SYN报文因为网络原因,延迟发送。由于client没有收到server对SYN的确认报文,会重发SYN报文,服务器和回复ACK,连接建立。数据发送完毕,这条连接被正常关闭。这时,延迟的SYN报文发到了server,server误以为这是client重新发送的同步报文,又回复了一个ACK,和client建立了连接。
<2>如果server给client发送的ACK报文因为网络原因,报文被丢弃,此时server认为已经建立好连接,但是client没有收到确认报文,认为没有建立好连接。client会重发SYN报文,此时server已经处于就绪状态,认为已经建立好连接。
如果TCP的握手是四次:
–1.client给server发送SYN同步报文;
–2.server收到SYN后,给client回复ACK确认报文;
–3.server给client发送SYN同步报文;
–4.client给server发送ACK确认报文。
第2.3步之间,server和client没有任何的数据交互,分开发送相当于多发了一次TCP报文段,SYN和ACK标识只是TCP报头的一个标识位。很明显,这两步可以合并,从而提高连接的速度和效率。
1, 为了达到可靠的效果
如果是两次握手,A已经确认B收到了自己发送的信息,但是B无法知道A是否收到了自己的确认信息,不可靠,如果有了第三次握手,B收到了A的确认信息,那么就可以进入连接建立状态。即双方发送的信息都被对方确认才能达到可靠。
2, 降低资源的浪费
为了防止已经失效的连接请求报文段突然又传到服务端,因而产生错误
三、TCP的四次挥手
第一次挥手: 客户端主动发出连接释放报文(FIN=1),序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),进入终止等待1状态。
第二次挥手: 服务器收到连接释放报文,回复确认ACK=1,确认号ack=u+1,同时带上自己的序列号seq=v,进入关闭等待状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
客户端收到服务器的确认后,进入终止等待2状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
第三次挥手: 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了最后确认状态,等待客户端的确认。
第四次挥手: 客户端收到服务器的连接释放报文后,回复确认ACK=1,序列号为seq=u+1,确认号为ack=w+1,进入了时间等待状态。注意此时TCP连接还没有释放,必须经过2MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
追问:为什么连接的时候是三次握手,关闭的时候确实四次挥手?
连接的时候SYN可以和ACK合并为一个步骤,因为连接的时候并没有数据的交互,三次加快了建立连接的速度和效率
断开的时候因为第二次挥手之后,服务端还有数据没传输完毕,不能立即关闭,只能等数据传送完了,再给客户端发送连接释放报文,这就多了一次挥手。
追问:为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
1,网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来等待服务端是否重发了FIN报文,如果是的话,那么客户端需要重丢失的ACK报文。
2、可以确保每成功建立一个TCP连接时,来自该连接先前化身的老的重复分组都已经在网络中消逝。
四、TCP的syn攻击怎么防御
什么是SYN洪水攻击?
恶意者通过ip欺骗,发送大量SYN包给受害者系统,导致服务端存在大量未决的连接并占用大量内存和tcp连接,从而导致正常客户端无法访问服务端,这就是SYN洪水攻击的过程。、
如何防御?
1,减小超时时间
2,SYN网关和SYN代理
3、增大最大半连接数
4、SYN cookies技术
对tcp的三次握手进行了一定的修改,但是修改仅在于服务器端,对任何客户端的使用都没有影响。原本tcp协议是在收到syn包时,服务器返回syn+ack包并分配一个专门的数据区来储存tcp连接需要的数据,这就使攻击者有机可乘,可以利用伪造的syn包来消耗服务器的内存空间和半开连接数,这就可以使服务器的内存或者半开连接数耗尽而拒绝服务。而syn cookie技术是服务器在收到syn包时并不马上分配储存连接的数据区,而是根据这个syn包计算出一个cookie,把这个cookie填入tcp的Sequence Number字段发送syn+ack包,等对方回应ack包时检查回复的Acknowledgment Number字段的合法性,如果合法再分配专门的数据区。
五、TCP是如何保证可靠的
确认、重传
什么时候重传?
- 为了保证数据包的可靠传递,发送方必须把已发送的数据包保留在缓冲区;
- 并为每个已发送的数据包启动一个超时定时器;
- 如在定时器超时之前收到了对方发来的应答信息(可能是对本包的应答,也可以是对本包后续包的应答),则释放该数据包占用的缓冲区;
- 否则,重传该数据包,直到收到应答或重传次数超过规定的最大次数为止。
- 接收方收到数据包后,先校验,如果正确则把数据交给上层协议,然后给发送方发送一个累计应答包,表明该数据已收到,如果接收方正好也有数据要发给发送方,应答包也可放在数据包中捎带过去。
六、TCP是如何通过滑动窗口协议实现流量控制和拥塞控制的?
什么是滑动窗口协议?
为了实现可靠的协议,每一个数据包发送之后,都要被接收方发送ACK来进行确认,这样效率低,性能差,窗口滑动协议就是 接收方告诉发送方,没必要一次发送一个包,每一个包我都给你确认,而是告诉发送方,你一次可以发送多个包,如果我接收的这多个包都没问题,那么我只需要给你发送最后一个包的确认即可,发送方一次发送多少数据包,由我接收方的滑动窗口大小决定,这个字段再TCP的首部的窗口字段中。
流量控制: 接收方可以根据自己的情况来决定滑动窗口的大小,比如说自己的缓冲区不够了,那么我就可以把窗口大小设定的小一点,让发送方慢点发送
拥塞控制: 为了避免突然的流量拥塞,有很多的tcp拥塞控制的算法,最简单的就是,慢开始-拥塞避免-快重传-快恢复。
慢开始:先以指数形式增加到窗口大小的一半;
拥塞避免:然后再一点一点增大到滑动窗口的大小;
快重传:当发送方收到三个重复确认,就立即重传,并且将阈值降低到发送窗口大小的一半;
快恢复:重新执行拥塞避免。
七、描述TCP和UDP的区别
TCP是面向连接的可靠传输协议,UDP是非面向连接的不可靠传输协议
x | TCP | UDP |
---|---|---|
可靠性 | 可靠 | 不可靠 |
连接性 | 面向连接 | 非面向连接 |
效率 | 低 | 高 |
流量控制 | 滑动窗口 | 无 |
传输速度 | 慢 | 快 |
类型 | 面向数据流 | 面向报文 |
功能 | 提供点到点通信 | 支持单播,组播,广播 |
八、TCP有哪些定时器
重传定时器
此计时器时间内收到了确认,就撤销计时器,否则就重传报文。
坚持定时器
当发送方收到接收方的0窗口通知时,就停止发送数据,等待接收方发送新的非0窗口以便继续发送数据,等待一个坚定计时器的时间发送探测报文,说你的确认信息我没有收到,必须重传,若仍然没有收到响应,就把这个时间复位并且加倍,继续发送一个探测报文。
保活定时器
防止在两个TCP之间的连接出现长时期的空闲。客户端两个小时都没有给服务端发送信息,那么服务端就发送探测报文段。若发送了10个探测报文段,每一个相隔75秒,还没有响应就假定客户出了故障,因而就终止该连接。
2MSL定时器
再TCP的第四次挥手之后,等待一个2msl的时间,才关闭连接,防止服务器没有收到自己的确认ACK而重复发送FIN报文。若在两个报文寿命的时间没有收到服务器的FIN报文,才关闭连接。