传输层协议 UDP 数据格式:
首部+数据
首部只有8个字节
2个字节的源端口号 , 2个字节的目的端口号, 2个字节的UDP长度,2个字节的UDP校验和。
注意的是:
UDP长度是:头部+UDP数据的总长度
2个字节的源端口号 ,
2个字节的目的端口号,
注意的是,查看端口被占用的命令
2个字节的UDP长度
头部+UDP数据的总长度
2个字节的校验和
传输层协议 TCP 数据格式
至少20个字节
2个字节的源端口,
2个字节的目的端口
4个字节的序号,
4个字节的确认号
1个字节的数据偏移
6位保留
6位明确位
URG
当URG中的值是1的时候,紧急指针中的值会有意义。
当URG中的值是0的时候,紧急指针中的值没有意义。
紧急指针中一般放什么呢?一般存放的是长度,我们假设是8,那么表示 TCP数据部分有8个字节是紧急数据,需要赶紧发送过去。
ACK
当ACK ==1时候,确认号才会有用
PSH
push,
RST
reset ,当RST==1时,表明链接发生严重错误,需要释放连接后,重新连接
SYN,FIN
三次握手
1个字节的窗口大小
如下图中,sender在左边,receiver 在右边。
当sender 第一次返送的时候 SYN为0,滑动窗口
- 发送端发起连接,声明最大段尺寸是1460,初始序号是0,所带数据也是0,因为只有头部,因此数据是0,窗口大小是4K,表示“我的接收缓冲区还有4K字节空闲,你发的数据不要超过4K”。接收端应答连接请求,声明最大段尺寸是1024,初始序号是8000,窗口大小是6K。发送端应答,三方握手结束。
- 发送端发出段4-9,每个段带1K的数据,发送端根据窗口大小知道接收端的缓冲区满了,因此停止发送数据。
- 接收端的应用程序提走2K数据,接收缓冲区又有了2K空闲,接收端发出段10,在应答已收到6K数据的同时声明窗口大小为2K。
- 接收端的应用程序又提走2K数据,接收缓冲区有4K空闲,接收端发出段11,重新声明窗口大小为4K。
- 发送端发出段12-13,每个段带2K数据,段13同时还包含FIN位。
- 接收端应答接收到的2K数据(6145-8192),再加上FIN位占一个序号8193,因此应答序号是8194,连接处于半关闭状态,接收端同时声明窗口大小为2K。
- 接收端的应用程序提走2K数据,接收端重新声明窗口大小为4K。
- 接收端的应用程序提走剩下的2K数据,接收缓冲区全空,接收端重新声明窗口大小为6K。
- 接收端的应用程序在提走全部数据后,决定关闭连接,发出段17包含FIN位,发送端应答,连接完全关闭。
上图在接收端用小方块表示1K数据,实心的小方块表示已接收到的数据,虚线框表示接收缓冲区,因此套在虚线框中的空心小方块表示窗口大小,从图中可以看出,随着应用程序提走数据,虚线框是向右滑动的,因此称为滑动窗口。
从这个例子还可以看出,发送端是一K一K地发送数据,而接收端的应用程序可以两K两K地提走数据,当然也有可能一次提走3K或6K数据,或者一次只提走几个字节的数据。也就是说,应用程序所看到的数据是一个整体,或说是一个流(stream),在底层通讯中这些数据可能被拆成很多数据包来发送,但是一个数据包有多少字节对应用程序是不可见的,因此TCP协议是面向流的协议。而UDP是面向消息的协议,每个UDP段都是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任意字节的数据,这一点和TCP是很不同的。
网络延迟的情况,SACK技术细节
那么我们来一种情况,当我们发送了4-9数据包后呢?6由于一些问题没收到,那么接受方应该怎么回复呢?
这里有两种方法,一种是 接收方回复 确认号ACK 为2049,告诉6我没收到,请从2049再次发给我。那么发送方收到后,就会将6-12的数据包,发送过去。之所以发送6个包,是因为,4和5在接收方大概率会被处理给上一层应用层。
一种是 接收方回复 确认号ACK 为2049,告诉6我没收到,但是4,5,7,8,9我都收到了。那么发送方收到后,就会发送6,10,11,发送过去,会比较精确的发送丢失的包,这里为什么发送3个包呢?是因为,4和5在接收方大概率会发送给上一层应用层,但是7,8,9应该还是要等6过来,由于6,7,8,9占用的窗口字节还剩2048,因此还可以再发送10,和11. 这种技术就叫做SACK技术
但是这个接收方到底发送多少个数据,是不确定的,万一接收方的应用层没有来得及处理呢?因此这里还是要看接收方发送过来的滑动窗口的大小,确定发送多少过去。上述只是我们认为的一般情况。
我们来看一下SACK的技术细节,那么从前面学习的知识,我们可以明确的是:使用SACK技术的接收方回复的信息一定多了4,5,7,8,9没收到的信息,那么这些信息是在 TCP头部的哪里包裹着?
1个字节的 校验和
1个字节的 紧急指针
12位选项,8位填充
选项就是可以填写各种情况
SACK是一种,详情可以参见 前面的SACK技术
一个问题:为什么选择在传输层就将数据 封层传输
TCP 的几个要点:可靠传输,流量控制,拥塞控制,连接管理,建立连接,释放连接
可靠传输,
流量控制,通过滑动窗口实现
拥塞控制,
MSS 每个段最大的数据部分大小。max segment size
从上述图片我们可以知道,MSS 的理论最大值是 1460,但是实际中 是由 发送方 和 接收方 协商来的,那么在什么时候协商的呢? 是在三次握手的时候,在TCP 头部的选项中 就会有这个协商值。
从上述的这次访问来看,客户端(接收方)是192,服务器(发送方)是111,
在三次握手的第一次的时候,客户端告知服务器的MSS 是1460
再第二次握手的时候,服务器告知 客户端我的MSS 是1452.
然后会选择 客户端 和 服务器端的 MSS的最小值 1452 作为 两者共同的MSS
RWND:接收窗口, 告诉对方,我最多能接受的大小
SWND:发送窗口
假设接受窗口最多能接受 1000个字节,那么发送窗口一次就发送1000个字节吗?
不是的,因为要考虑到拥塞控制的问题,网络上的每一个机器都要贡献力量,因此实际上的
发送窗口 = min(接收窗口,拥塞窗口)
CWND:拥塞窗口
发送方,根据当前网络情况,如果网络拥塞的严重呢,拥塞窗口就会小
慢开始
拥塞避免
快速重传
快恢复
连接管理,
这里先看一遍,序号,确认号的意义,再往下看
建立连接,
3次握手改成2次行吗?
释放连接
为什么需要4次挥手?
正常连接到释放的过程如下:
还有一种情况是 3次 挥手:
长连接
短连接:
客户端发送数据给服务器端,或者服务器端发送数据给客户端完成后,立马关闭连接。这种我们就叫做短连接。也就是说:做完交互后立马关闭连接的这种。