多线程 & 网络

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

2021-03-16  本文已影响0人  码小菜

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

一,UDP

1,介绍
2,首部
3,端口号
4,检验和

二,TCP

1,介绍
2,首部
3,数据偏移
4,标志位
5,核心要点

三,TCP之可靠传输

1,停止等待ARQ协议
2,连续ARQ协议和滑动窗口协议
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,注意点

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

四,TCP之序号和确认号

1,说明
2,发送单个分组
3,发送多个分组
4,初始值

五,TCP之流量控制

1,说明
2,图解

六,TCP之拥塞控制

1,介绍
2,控制方法
3,慢开始
4,拥塞避免
5,快重传
6,快恢复

七,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,序号和确认号只是一个形式而已

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
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通信
上一篇下一篇

猜你喜欢

热点阅读