网络互联模型:
OSI参考模型 | TCP/IP协议 | 学习研究 |
7 应用层 | 4 应用层 | |
6 表示层 | | |
5 会话层 | | 5 应用层 |
4 运输层 | 3 运输层 | 4 运输层 |
3 网络层 | 2 网际层 | 3 网络层 |
2 数据链路层 | 1 网络接口层 | 2 数据链路层 |
1 物理层 | | 1 物理层 |
首部固定部分20个字节,版本4位,首部长度4位,区分服务8位,总长度16位;标识16位,标志加片偏移16位;生存时间8位;协议8位,首部检验和8位;源IP地址32位;目的IP地址32位。
剩下为可选字段(长度可变)加填充部分。
数据链路层的帧数据不能超过1500字节,过大的IP数据包需要分成片(fragments)传输给数据链路层,且每一片都有自己的网阔层首部(IP首部)。
版本:IPv4或IPv6.
首部长度:首部长度乘4即为首部实际长度。
区分服务:可以提高网络的服务质量。
总长度:4个字节,首部+数据长度之和,范围0-65535。
标识:数据包过大分片时,同一个数据包的标识都是一样的。
标志和片偏移:标志3位,保留位,不分片位,更多片位。片偏移13位,数值乘8得到字节偏移量,每一片的长度都是8的整数倍。
生存时间:TTL,路由器跳数,每次转发减1,减到0丢弃,返回错误报告。
协议:表明封装的数据是什么协议。
首部校验和:计算首部数据完整性。
TCP | UDP | |
---|---|---|
连接性 | 面向连接 | 无连接 |
可靠性 | 可靠传输 | 不可靠传输 |
首部占用 | 大 | 小 |
传输速率 | 慢 | 快 |
资源消耗 | 大 | 小 |
应用场景 | 浏览器、文件传输、邮件发送 | 音视频通话、直播 |
应用层协议 | HTTP、HTTPS、FTP、SMTP、DNS | DNS |
UDP协议头中的长度表示整个报文的长度。
UDP检验和是计算伪首部(12个字节)+首部+数据。
端口
- UDP首部中的端口是占用2字节:0-65535。
- 客户端的源端口是临时开启的随机端口。
HTTP:TCP+80
HTTPS:TCP+443
FTP:TCP+21
MySQL:TCP+3306
DNS:UDP/TCP+53
SMTP:TCP+25
POP3:TCP+110
TCP首部至少20个字节,20个字节固定首部+可变部分;
固定首部:
URG:当URG=1时,紧急指针字段才有效,应优先尽快传递。
ACK:当ACK=1时确认字段有意义。
PSH:一般用不上。
RST:当RST=1时,表名连接中出现验证差错,必须释放连接,然后重新建立连接。
SYN:SYN=1,ACK=0时表名时建立连接请求;
FIN:FIN=1,表示要求释放连接。
TCP可靠传输采用连续ARQ协议+窗口滑动协议,每次发送窗口大小数据,只发送最后收到的有效数据的确认序号,代表之前的数据都收到了。发送端的窗口是由接收端决定的。
SACK是一种选择重传的技术,下面是传统的重传技术:
- 在TCP通信中,如果发送序列中某个数据报丢失(比如1、2、3、4、5中丢失3)
- TCP会通过重传最后确认的分组后续的分组(最后确认的是2,会重传3、4、5)
- 这样原先已经正确传输的分组也可能重复发送(比如4、5)降低了TCP的性能。
为了改善上述情况发展出了SACK技术。可以告诉发送方那些丢失那些收到。实现部分在TCP头部的选项(可变长度)部分。
接收窗口时由接收方告诉发送方的,接收窗口由接收端的缓冲区决定窗口大小,让发送方的发送速率不要太快,让接收方来的及处理。
原理:通过确认报文中窗口字段来控制发送方的发送速率,发送方的发送窗口大小不能超过接收方给出窗口大小,当窗口大小为0的时候发送方会停止发送。
一种特殊情况:
- 一开始接收方给发送方发送了0窗口的报文段;
- 后面接收方又有了一些存储空间,给发送方发送非0窗口的报文段丢失了;
- 发送方的发送窗口一直为零,双方陷入僵局
解决方案:
- 当发送方收到0窗口通知时,发送方停止发送报文;
- 并同时开启一个定时器,每隔一段时间就发送一个测试报文询问接收方的窗口大小;
- 如果窗口大小还是0,则刷新启动定时器。
拥塞控制:防止过多数据注入到网络中,避免网络中的路由器或连路过载。
拥塞控制是一个全局性的过程,色寄到所有的主机、路由器以及与降低网络传输性能有关的所有因素,相比而言流量控制时点对点通信的控制。
- MMS(Max Segment Size):每个段最大的数据部分大小,在建立连接时确定。有SYN(建立连接的前两次)TCP首部都是32字节,多出的12字节为MMS(Max Segment Size)和其他内容。
- rwnd:接收窗口,最多一次性发送的数据量。
- cwnd:拥塞窗口,拥塞控制的窗口,发送方根据网络状态自行判断。
- swnd:发送窗口,swnd=min(cwnd, rwnd)
最开始不会按照接收窗口发送,会从1单位的MSS发送,成倍增加2,4,8…直到到达拥塞窗口上限或者接收窗口后停止。cwnd的初始值比较小,然后随着数据包被接方接受确认(收到一个ACK)cwnd开始成倍(指数级)增长。
ssthresh(Slow Start Threshold):慢开始阈值,cwnd达到阈值后,以线性方式增加。
加法增大:拥塞窗口缓慢增大,以防止网咯过早出现拥塞。
乘法减小:只要网络出现网络拥塞,把ssthresh减半,与此同时,执行慢开始算法。现在已经弃用这种方法,而是出现拥塞后将cwnd(ssthresh)减半,与此同时,执行加法增大(快恢复)。
接收方
每收到一个失序的分组后就立即发出重复确认,使发送方及时知道有分组没有到达,而不要等待自己发送数据时才进行确认。
发送方
只要连续收到三个重复确认(总计4个相同的确认),就应当立即重传对方尚未收到的报文段,而不比继续等待重传计时器到期后再重传。
TCP Reno版本的拥塞控制采用快重传+快恢复的方法,收到3个重复确认后执行快速重传,将cwnd(ssthresh)减半,与此同时,执行加法增大。
三次握手:
(1)客户端:发送 SYN , sq = c1,len = 0;
(2)服务端:回应 SYN ACK, ack = c1+1, sq = s1, len = 0;
(3)客户端:再发送 ACK, ack = s1+1, sq = c1+1, len = 0。
握手之后发送HTTP请求。结束后服务器发送200OK。SYN和FIN都占序列号,而空的ACK不占序列号。
(4)客户端:发送HTTP请求 ACK, ack = s1+1, sq = c1+1, len = k;
(5)服务端:返回数据ACK, ack = c1+1+k, sq = s1+1, len = j ;
ACK的确认号ack表示接收方期望下一次数据的起始序号。
客户端状态:CLOSED(关闭)-> SYN-SENT(同步已发送)->ESTABLISHED(连接已经建立);
服务端:LISTEN(监听)->SYN-RCVD(同步已接收)->ESTABLISHED(连接已建立)。
TCP连接前两次握手的特点:
Q:为什么是三次握手不是两次?
A:主要目的是防止server端一直等待,浪费资源。如果只需要两次握手,可能回出现客户端发出的第一个连接请求报文段因为网络延迟,在连接释放以后的某个时间才到达server,会导致二次“连接”服务端会空等,客户端不会理会。三次握手,客户端会返回确认,如果没返回确认就知道客户端没有建立连接的要求。
Q:第三次握手失败了,会怎么处理?
A:如果server的状态是SYN-RCVD(同步已接收),若等不到ACK,server会重新发送SYN+ACK包;如果server多次重发SYN+ACK都等不到client的ACK,就会发送RST包,强制关闭连接
四次挥手:(客户端先)
(1)客户端:发送FIN, ACK,sq = u,ack = v;
(2)服务端:发送ACK, sq = v, ack = u+1;…最后请求序号w;
(3)服务端:发送FIN, ACK, sq = w, ack = u+1;
(4)客户端:发送ACK,sq = u+1,ack = w+1。
状态:
客户端状态:ESTABLISHED(连接已建立)-> FIN-WAIT-1(终止等待1)->FIN-WAIT-2( 终止等待2)-> TIME-WAIT(时间等待)-> CLOSED(关闭)。
服务端:ESTABLISHED(连接已建立)->CLOSE-WAIT(关闭等待)->LAST-ACK(最后确认)->CLOSED(关闭)。
细节问题:
TCP/IP协议栈在设计上,允许任何一方先发起断开请求。这里演示的时client主动要求断开;
client发送ACK后进入TIME-WAIT状态需要等待一段时间后,再真正关闭连接,一般等待时2倍的MSL(Maximum Segment Lifetime,最大分段生存时间),一般建议是2min。
如果client发送完ACK马上释放了,然后又因为网络原因,server没有收到ACK,server就会重发FIN,这时就可能出现的情况是:
(1)client没有任何响应,服务器那边会干等,甚至多次重发FIN浪费资源;
(2)client有个新的应用程序刚好分配了同一个端口号,新的应用程序收到FIN后马上开始执行断开连接的操作,导致异常。
Q:为什么释放连接的时候,要进行4次挥手?
A:TCP是全双工模式,第一次挥手,当主机1发出FIN报文时,仅仅代表主机1告诉主机2,主机1已经没有数据要发送了,但是此时主机1还是可以接收来自主机2的数据;第二次挥手,当主机2发送ACK报文时,表名主机2已经知道主机1没有数据要发送了,但是主机2还是可以发送数据到主机1;第三次挥手,当主机2也发送FIN报文;第四次挥手,当主机1返回ACK报文。随后正式断开整个TCP连接。
Q:长连接和短连接是如何区分的?
A:短链接:一般称创建连接后进行一轮交互就马上断开连接称为短链接。其区分的关键为建立连接的目的。