美文网首页多线程 & 网络
网络协议:传输层之UDP与TCP

网络协议:传输层之UDP与TCP

作者: 码小菜 | 来源:发表于2021-03-16 15:30 被阅读0次

    目录
    一,UDP
    二,TCP
    三,TCP之可靠传输
    四,TCP之序号和确认号
    五,TCP之流量控制
    六,TCP之拥塞控制
    七,TCP之连接管理
    八,Wireshark

    一,UDP

    1,介绍
    • UDPUser Datagram Protocol的缩写,表示用户数据报协议
    • 是一种无需连接就可以发送数据的传输协议
    • 无连接的优点:首部占用空间小,传输速率快、资源消耗小
    • 无连接的缺点:不可靠传输,尽最大努力交付,可能丢包
    2,首部
    • 4个部分各占2个字节
    • 长度:首部长度 + 数据长度
    3,端口号
    • 取值范围:0 ~ 65535(16位都为1)
    • 客户端的端口号是临时随机开启的
    • 下面是服务端常用的端口号
    • netstat –an:查看被占用的端口号
    4,检验和
    • 计算内容:伪首部 + 首部 + 数据
    • 伪首部:源IP地址、目的IP地址、保留、协议类型(17表示UDP)、长度
    • 伪首部只用于计算检验和,不会传递给网络层

    二,TCP

    1,介绍
    • TCP是Transmission Control Protocol的缩写,表示传输控制协议
    • 是一种需要建立连接才能发送数据的传输协议
    • 面向连接的优点:可靠传输,不丢包
    • 面向连接的缺点:首部占用空间大,传输速率慢、资源消耗大
    2,首部
    • 端口号(4个字节):与UDP相同
    • 序号(4个字节):下面单独讲解
    • 确认号(4个字节):下面单独讲解
    • 数据偏移(4位):下面单独讲解
    • 保留(6位):保留
    • 标志位(6位):下面单独讲解
    • 窗口(2个字节):告知对方下一次允许发送的数据大小
    • 检验和(2个字节):与UDP相同
    • 紧急指针(2个字节):指向紧急数据在报文段中结束的位置
    3,数据偏移
    • 表示首部长度
    • 首部长度 = 固定部分(20个字节) + 选项部分(40个字节)
    • 取值范围:0x0101(十进制为5) ~ 0x1111(十进制为15)
    • 首部长度 / 4 = 十进制
    4,标志位
    • URGUrgent):当URG=1时,紧急指针才有效。表示当前报文段中有紧急数据,应优先尽快传送
    • ACKAcknowledgment):当ACK=1时,确认号才有效
    • PSHPush):当PSH=1时,表示接收端需要尽快将数据传递给应用层处理,不要在缓存区排队
    • RSTReset):当RST=1时,表示连接出现严重错误,必须释放连接,然后重新建立连接
    • SYNSynchronization):与ACK结合使用。当SYN=1、ACK=0时,表示请求建立连接;当SYN=1、ACK=1时,表示同意建立连接
    • FINFinish):当FIN=1时,表示数据已经发送完毕,请求释放连接
    5,核心要点
    • 可靠传输
    • 流量控制
    • 拥塞控制
    • 连接管理

    三,TCP之可靠传输

    1,停止等待ARQ协议
    • ARQAutomatic Repeat-reQuest的缩写,表示自动重传请求
    • 作用:发送一个分组就停止发送等待确认
    • 一个分组可以是100个字节,也可以是1000个字节
    2,连续ARQ协议和滑动窗口协议
    • 作用:发送窗口中的分组连续发送,发送完后,停止等待确认
    • 发送窗口的大小是由接收端来决定的
    • 如果M3丢失,接收端会确认M2,发送端会重新发送M3M4
    3,SACK
    • 介绍

    1>SACKSelective Acknowledgment的缩写,表示选择性确认
    2>普通确认:如果M3丢失,发送端会重新发送M3M4
    3>选择性确认:如果M3丢失,发送端只会重新发送M3
    4>SACK信息存放在首部的选项部分中

    • 信息

    1>Kind(1个字节):值固定为5,表示SACK选项
    2>Length(1个字节):SACK选项占用的字节数
    3>Left Edge(4个字节):左边界
    4>Right Edge(4个字节):右边界

    • 实例

    1>首部的选项部分最多40个字节,减去KindLength,只有38个字节可以存放边界信息
    2>一组边界信息占用8个字节,SACK选项最多可以携带4组边界信息
    3>SACK选项最大占用字节数为34(4 * 8 + 2)

    4,注意点
    • 当重传超过一定次数时,就会发送resetRST)报文来断开连接
    • 网络层有分片功能,为何在传输层还要分段?

    1>可靠传输是在传输层进行控制的
    2>如果在传输层不分段,一旦出现数据丢失,所有数据都得重传
    3>如果在传输层分了段,一旦出现数据丢失,只需重传丢失的段

    四,TCP之序号和确认号

    1,说明
    • 序号(Sequence Number):这一次发送给对方的数据第一个字节的编号
    • 确认号(Acknowledgment Number):期望对方下一次发送过来的数据第一个字节的编号
    2,发送单个分组
    • ACK号:确认号
    3,发送多个分组
    • Seq:序号
    • ack:确认号
    • ACK:标志位
    4,初始值
    • 序号并不是从1开始的,1只是一个相对值
    • 在建立连接时,通信双方会交换各自的序号初始值
    • 在收发数据时,序号和确认号会在初始值的基础上进行累加

    五,TCP之流量控制

    1,说明
    • 接收端的缓存区大小有限,需要控制发送端发送数据的速度
    • 接收端会通过确认报文中的窗口字段,来告知发送端下一次可以发送多少数据
    • 如果接收端的缓存区满了,会将窗口大小设置为0,发送端就停止发送数据
    • 如果接收端的缓存区又有空间了,会再次发送一个确认报文告知发送端
    2,图解
    • rwndreceive window):接收窗口

    六,TCP之拥塞控制

    1,介绍
    • 防止过多的数据注入到网络中,避免网络中的链路过载
    • 它是一个全局性的过程,是所有主机共同努力的结果
    • 相比而言,流量控制是点对点通信的控制
    2,控制方法
    • 慢开始
    • 拥塞避免
    • 快重传
    • 快恢复
    3,慢开始
    • MSSMaximum Segment Size):段长度的最大值
    • swndsend window):发送窗口
    • rwndreceive window):接收窗口
    • cwndcongestion window):拥塞窗口
    • swnd = min(rwnd,cwnd),发送窗口大小是由接收窗口大小和拥塞窗口大小共同决定的
    • cwnd的初始值比较小,然后每收到一个确认报文cwnd就乘以2(指数级增长),swnd也会随着变大
    4,拥塞避免
    • ssthreshslow start threshold):慢开始阈值
    • 在慢开始阶段,cwnd呈指数级增长,达到阈值后,进入拥塞避免阶段,cwnd呈线性增长(加法增大)
    • 当网络出现拥塞时,将阈值减小为拥塞峰值的一半(乘法减小),同时重新执行慢开始算法(将cwnd恢复到初始值)
    • 当网络频繁拥塞时,阈值会越来越小,cwnd的增长速度就会越来越慢
    5,快重传
    • 接收端:当收到一个失序的分组时就立即发出确认报文,让发送端及时知道有分组丢失,而不要等待自己发送数据时才进行确认
    • 发送端:当连续收到3个重复确认时(总共有4个相同的确认),就立即重传丢失的分组,而不必等待重传计时器到时再重传
    6,快恢复
    • 当发送端连续收到3个重复确认时,说明网络出现拥塞
    • 当网络出现拥塞时,将阈值减小为拥塞峰值的一半(乘法减小),同时直接执行拥塞避免算法(将cwnd设置为新的阈值)
    • 慢开始、拥塞避免、快重传、快恢复结合使用,拥塞控制的效果才最好

    七,TCP之连接管理

    1,建立连接(三次握手)
    • 图解
    • 状态

    客户端
    1>CLOSED(关闭):在连接之前处于该状态
    2>SYN-SENT(同步已发送):在发送连接请求之后进入该状态
    3>ESTABLISHED(连接已建立):在发送第三次确认之后进入该状态

    服务端
    1>LISTEN(监听):在连接之前处于该状态
    2>SYN-RCVD(同步已接收):在确认连接请求之后进入该状态
    3>ESTABLISHED(连接已建立):在接收第三次确认之后进入该状态

    • 握手

    第一次
    1>SYN=1(标志位):这是一个同步请求
    2>ACK=0(标志位):无确认号信息
    3>seq=x(序号):将自己的序号初始值告知服务端

    第二次
    1>SYN=1(标志位):这是一个同步请求
    2>ACK=1(标志位):有确认号信息
    3>seq=y(序号):将自己的序号初始值告知客户端
    4>ack=x+1(确认号):期望客户端下一次发送过来的数据是从x+1开始的

    第三次
    1>ACK=1(标志位):有确认号信息
    2>seq=x+1(序号):这一次发送给服务端的数据是从x+1开始的
    3>ack=y+1(确认号):期望服务端下一次发送过来的数据是从y+1开始的

    ⚠️注意⚠️:在握手过程中,报文中的数据部分都为0,序号和确认号只是一个形式而已

    • 首部

    1>前两次握手会用到首部的选项部分
    2>选项部分中存放的是双方需要交换的信息
    3>信息包含:段长度的最大值、窗口缩放系数、是否支持SACK
    4>窗口大小 = 首部窗口字段中的值 * 窗口缩放系数

    • 问题

    为何需要三次握手,两次不行吗?
    1>假设客户端发送的第一个连接请求,由于网络原因迟迟没有到达服务端,这时客户端就会发送第二个连接请求
    2>如果在第二个连接请求正常结束之后,第一个连接请求才到达服务端,这时服务端会认为这是一个新的连接请求,于是向客户端发送确认报文,同意此次连接
    3>如果是两次握手的话,那么该连接就建立完成了,此时服务端会等待客户端发送数据请求
    4>对应客户端来说,这是一个无效连接,并不会给服务端发送数据请求,这样服务端的资源就白白浪费了

    第三次握手失败了会怎么处理?
    1>如果服务端没有收到客户端的ACK报文,就会重发SYN+ACK报文
    2>如果重发多次还是收不到ACK报文,服务端就会发送resetRST)报文强制关闭连接

    2,释放连接(四次挥手)
    • 图解
    • 状态

    客户端
    1>ESTABLISHED(连接已建立):在释放连接之前处于该状态
    2>FIN-WAIT-1(终止等待1):在发送释放连接请求之后进入该状态
    3>FIN-WAIT-2(终止等待2):在接收确认之后进入该状态
    4>TIME-WAIT(时间等待):在确认释放连接请求之后进入该状态
    5>CLOSED(关闭):在等待2MSL之后进入该状态

    服务端
    1>ESTABLISHED(连接已建立):在释放连接之前处于该状态
    2>CLOSE-WAIT(关闭等待):在确认释放连接请求之后进入该状态
    3>LAST-ACK(最后确认):在发送释放连接请求之后进入该状态
    4>CLOSED(关闭):在接收确认之后进入该状态

    • 挥手

    第一次
    1>FIN=1(标志位):这是一个释放连接的请求
    2>ACK=1(标志位):有确认号信息
    3>seq=u(序号):这一次发送给服务端的数据是从u开始的
    4>ack=v(确认号):期望服务端下一次发送过来的数据是从v开始的

    第二次
    1>ACK=1(标志位):有确认号信息
    2>seq=v(序号):这一次发送给客户端的数据是从v开始的
    3>ack=u+1(确认号):期望客户端下一次发送过来的数据是从u+1开始的

    第三次
    1>FIN=1(标志位):这是一个释放连接的请求
    2>ACK=1(标志位):有确认号信息
    3>seq=w(序号):这一次发送给客户端的数据是从w开始的
    4>ack=u+1(确认号):期望客户端下一次发送过来的数据是从u+1开始的

    第四次
    1>ACK=1(标志位):有确认号信息
    2>seq=u+1(序号):这一次发送给服务端的数据是从u+1开始的
    3>ack=w+1(确认号):期望服务端下一次发送过来的数据是从w+1开始的

    ⚠️注意⚠️:在挥手过程中,报文中的数据部分都为0,序号和确认号只是一个形式而已

    • MSL

    1>MSLMaximum Segment Lifetime的缩写,表示段生存期的最大值
    2>生存期是报文在网络上的生存时间,MSL一般为2分钟
    3>本次连接的的报文都会在2MSL(4分钟)内消失

    • 问题

    客户端为何要等待2MSL再关闭?
    1>如果因为网络原因没有收到客户端的ACK报文,服务端就会重发FIN报文
    2>如果客户端不等待而直接关闭的话,会存在两个问题
    3>第一:服务端得不到任何的回应,会一直等待甚至多次重发FIN报文,白白浪费资源
    4>第二:客户端刚好有一个新的应用程序分配了同一个端口号,新的应用程序就会收到FIN报文,然后开始执行释放连接的操作,本来它可能打算跟服务端建立连接的

    为何要进行四次挥手?
    1>第一次:表示客户端告诉服务端已经没有数据要发送了,但是客户端还是可以接收服务端的数据
    2>第二次:表示服务端已经知道客户端没有数据要发送了,但是服务端还是可以给客户端发送数据
    3>第三次:表示服务端告诉客户端已经没有数据要发送了
    4>第四次:表示客户端已经知道服务端没有数据要发送了
    5>在双方都知道对方没有数据要发送之后,连接才能释放

    为何有时是三次挥手?
    1>当服务端收到客户端的FIN报文时,如果还有数据要发送给客户端,那么服务端就会先发送ACK报文,然后等待数据都发送完毕了再发送FIN报文,这时就是四次挥手
    2>当服务端收到客户端的FIN报文时,如果没有数据要发送给客户端,那么服务端就会直接发送FIN+ACK报文(第二次与第三次合并),这时就是三次挥手

    八,Wireshark

    网络抓包工具

    1,UDP
    • Source Port:源端口号
    • Destination Port:目标端口号
    • Length:长度
    • Checksum:检验和
    2,TCP首部
    • 首部

    1>Source Port:源端口号
    2>Destination Port:目标端口号
    3>Sequence number:序号(未加初始值)
        Sequence number(raw):序号(已加初始值)
    4>Acknowledgment number:确认号(未加初始值)
        Acknowledgment number(raw):确认号(已加初始值)
    5>Header Length:数据偏移(首部长度)
    6>Flags:标志位
    7>Window size value:窗口
        Calculated window size:窗口大小(窗口 * 缩放系数)
    8>Checksum:检验和
    9>Urgent pointer:紧急指针
    10>Options:选项部分

    • 标志位

    前面6位是保留位

    • 选项部分

    1>Maximum segment size:段长度的最大值
    2>Window scale:窗口缩放系数
    3>SACK permitted:支持SACK

    3,TCP通信
    • 三次握手
    • 数据传输
    • 四次挥手

    相关文章

      网友评论

        本文标题:网络协议:传输层之UDP与TCP

        本文链接:https://www.haomeiwen.com/subject/yojtqltx.html