TCP/UDP详解

TCP简介(网络基础中有所介绍)

TCP传输控制协议:
  • 面向连接、可靠的、基于字节流的传输层协议
  • 将应用层的数据分割成报文段并发送给目标节点TCP层
  • 数据包都是有序号的,对方收到则发送ACK确认,未收到则重传
  • 使用校验和函数来检验数据在传输过程中是否有误
TCP报文头

其中 ACK SYN 序号 这三个部分在以下会用到,它们的介绍也在下面

TCP/UDP详解_第1张图片
TCP报文头

上面就是TCP协议头部的格式,由于它比较重要,是理解其它内容的基础,下面就将每个字段的信息都详细的说明一下。

  • Source Port和Destination Port:分别占用16位,表示源端口号目的端口号;用于区别主机中的不同进程,而IP地址是用来区分不同的主机的,源端口号和目的端口号配合上IP首部中的源IP地址和目的IP地址就能唯一的确定一个TCP连接;
  • Sequence Number:用来标识从TCP发端向TCP收端发送的数据字节流,它表示在这个报文段中的的第一个数据字节在数据流中的序号,主要用来解决网络报文乱序的问题;
  • Acknowledgment Number:32位确认序列号包含发送确认的一端所期望收到的下一个序号,因此,确认序号应当是上次已成功收到数据字节序号加1。不过,只有当标志位中的ACK标志(下面介绍)为1时该确认序列号的字段才有效。主要用来解决不丢包的问题;
  • Offset:给出首部中32 bit字的数目,需要这个值是因为任选字段的长度是可变的。这个字段占4bit(最多能表示15个32bit的的字,即4*15=60个字节的首部长度),因此TCP最多有60字节的首部。然而,没有任选字段,正常的长度是20字节;
TCP Flags
  • URG:紧急指针标志
  • ACK:确认序号标志
  • PSH:push标志
  • RST:重置连接标志
  • SYN:同步序号,用于建立连接
  • FIN:finish标志,用于释放连接

3个红色的flag是常用标志

TCP三次握手

tcp需要经过三次握手来建立全双工(允许数据在两个方向上同时传输)连接:


TCP/UDP详解_第2张图片
三次握手

seq是上方介绍的Sequence Numberack,小写的ack是上方的Acknowledgment Numbe

  • 第一次握手:客户端发送连接请求报文段,将SYN为1,Sequence Number为J,然后客户端进入SYN_SEND状态,等待服务器的确认
  • 第二次握手:服务器收到SYN报文段。服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置Acknowledgment Number(ack)为J+1;同时,自己自己还要发送SYN请求信息,将SYN位置为1,Sequence Number为K;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECV状态;
  • 第三次握手:客户端收到服务器的SYN+ACK报文段。然后将Acknowledgment Number设置为K+1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。这样就完成了连接。

为何需要三次握手才能建立连接

  • 主要就是初始化Sequence Number,也就是上面中的J和K,通讯双方都将获取对方的这个序号,以保证应用层不回因为网络问题而乱序,即TCP会用这个序号拼接数据。
  • 第一次客户端发送给服务端,服务端收到了就第二次握手发送消息给客户端,如果到这儿就结束了,也就是两次握手,那么服务端并不能确认它发出的消息客户端有没收到,所有需要第三次客户端在此发送消息给服务端,你的消息我收到了,这样双方才能确认彼此都能收到对方的消息,连接也就建立起了。

首次握手的隐患:SYN超时:

  • Server收到Client的SYN,回复SYN-ACK的时候未收到ACK确认(此时Client掉线)
  • Server不断重试直至超时,Linux默认等待63秒才断开连接

针对SYN Flood的防护措施(遭遇网络攻击恶意占用连接通道):

  • SYN队列满后,通过tcp_syncookies参数回发SYN Cookie,若是正常连接则Client会回发SYN Cookie,直接建立连接

建立连接后,Client出现故障

  • 保活机制:向对方发送保活探测报文,如果未收到则继续发送,次数达到保活探测数后仍未收到响应则中断
TCP四次挥手

tcp通过四次挥手来断开连接:

TCP/UDP详解_第3张图片
四次挥手

挥手过程

  • 第一次挥手: 主动关闭方(可以使客户端,也可以是服务器端,这里标记为:A),A发送一个FIN,用来关闭A到B的数据传输,A进入FIN_WAIT_1
  • 第二次挥手:B收到FIN后,发送一个ACK给A,确认序号(ack)为收到的序号+1(与SYN相同,一个FIN占用一个序号),B进入CLOSE_WAIT状态(还可以进行数据传送)
  • 第三次挥手:B发送一个FIN,用来关闭A到B的数据传送,B进入到LAST_ACK状态
  • 第四次挥手:A收到B发送的FIN报文段,进入TIME_WAIT状态,接着发送一个ACK给B确认序号(ack)为收到的序号+1,B在收到报文后进入CLOSED状态,A在发送完报文等待了2MSL时间后进入CLOSED状态。

为什么会有TIME_WAIT状态(为什么等待2MSL):

  • 确保有足够的时间让对方收到ACK包(如果对方没有收到,对方会再次进行第三次挥手,这样一来一回的时间就是2*MSL了)
  • 避免新旧连接混淆(有些路由器会缓存ip数据包,如果连接被重用,那么延迟收到的包有可能跟新连接混到一起)

为什么需要四次挥手才能断开连接

  • 因为全双工,发送方和接收方都需要FIN报文和ACK报文。

服务器大量出现CLOSE_WAIT状态的原因
对方关闭socket连接,我放忙于读或写,没有及时关闭连接

  • 检测代码,特别是释放资源代码
  • 检测配置,特别是处理请求的线程配置

UDP简介

报文结构

TCP/UDP详解_第4张图片
UDP报文结构

UDP的特点

  • 面向非连接
  • 不维护连接状态,支持同时向多个客户端传输相同的消息
  • 数据包报头只有8个字节,额外开销小
  • 吞吐量只受限于数据生成速率,传输速率以及机器性能
  • 尽最大努力交付,不保证可靠交付,不需要维持复杂的连接状态表
  • 面向报文,不对应用程序提交的报文信息进行拆分或者合并

UDP与TCP的区别

  • TCP面向连接vs无连接
  • 可靠性:TCP通过三次握手保证,UDP可能丢包
  • 有序性:TCP最终会进行排序(Sequence Number)
  • 速度:TCP较慢
  • 量级:TCP是重量级的,UDP是轻量级

你可能感兴趣的:(TCP/UDP详解)