网络分层结构
OSI七层模型
TCP/IP 五层模型
- 应用层:为应用程序提供交互服务。在互联网中的应用层协议很多,如域名系统DNS、HTTP协议、SMTP协议等
- 传输层:负责向两台主机进程之间的通信提供数据传输服务。传输层协议主要有传输控制协议TCP、用户数据协议UDP
- 网络层:选择合适的路由和交换地点,确保数据及时传送。主要包括IP协议
- 数据链路层:在两个相邻节点之间传送数据时,数据链路层将网络层交下来的IP数据报组装成帧。在两个相邻节点间的链路上传送帧。
- 物理层:实现相邻节点间比特流的透明传输,尽可能屏蔽传输介质和物理设备的差异。
传输层 UDP 与 TCP
1.UDP协议
UDP是一种无连接的,不可靠的传输层协议。它只提供了传输层需要实现的最低限度的功能,除了复用/分解功能和少量的差错检测外,它几乎没有对IP增加其他的东西。UDP协议适用于对实时性要求高的应用场景
特点
- 使用UDP时,在发送报文段之前,通信双方没有握手的过程,因此UDP被称作是无连接的传输层协议。因为没有握手的过程,相对于TCP来说,没有建立连接的时延。因为没有连接,所以不需要在端系统中保存连接的状态。
无连接、无状态、无时延 - UDP
提供尽力而为的交付服务,UDP协议不保证数据的可靠交付 - UDP没有
拥塞控制和流量控制的机制,所以UDP报文段的发送速率没有限制 - 一个UDP套接字只使用
目的地址和目的端口来标识,所以支持一对一、一对多、多对多的交互通信.
报文段结构
UDP报文段由首部和应用数据组成,UDP首部只有8个字节,四个字段,每个字段的长度为2个字节。分别是
源端口号、目的端口号、长度,校验和(DUP提供的差错校验机制,只能查不能恢复)
2.TCP协议
TCP协议是面向连接的,提供可靠数据传输服务的传输层协议
特点
- TCP协议是面向连接的,在通信双方进行通信前,需要三次握手建立连接,它需要在端系统中维护双方连接的状态信息。
- TCP协议通过
序号、确认号、定时重传、校验和等机制,来提供可靠的数据传输服务 - TCP协议提供的是
点对点的服务,它是在单个发送方和单个接收方之间的连接 - TCP协议提供的是全双工的服务,也就是双方能够同时向对方发送和接收数据
- TCP提供了
拥塞控制机制,在网络拥塞的时候会控制发送数据的速率,有助于减少数据包的丢失和减轻网络中的拥塞程度。 - TCP提供了
流量控制机制,保证了通信双方的发送和接收速率相同,如果接收方可接收的缓存很小时,发送方会降低发送速率,避免因为缓存填满而造成的数据包的丢失
报文段结构
TCP报文段由首部和数据组成,它的首部一般为20个字节
16比特的
源端口号 和 16比特的目的端口号 用于报文段的 多路复用 和 分解
32比特的序号 和 32比特的确认号,用于 实现可靠数据运输服务
4比特的首部长度字段,该字段指示了以32比特的字为单位的TCP首部的长度
6比特保留
6比特的标识字段,
- URG用来指示报文段里存在紧急的数据;
- ACK用于指示确认序号的值是有效的
- PSH指示接收方应该立即将数据交给上层
- RST、SYN、FIN用于连接的构建和拆除
16比特的接受窗口字段用于实现流量控制,该字段表示接收方愿意接收的字节的数量
16比特的校验和提供了对数据的差错检测
16比特的紧急指针
选项(长度可变)
填充
*TCP三次握手
第一次握手,客户端向服务器发送一个 SYN 连接请求报文段,报文段的首部中 SYN 标识位置为1,序号字段是一个任选的随机数即seq=x。它代表的是客户端数据的初始序号。第一次握手后,客户端的状态为SYN-SENT,服务端的状态为 LISTEN
第二次握手,服务端接收到客户端发送的 SYN 连接请求报文段后,服务端首先会为该连接分配 TCP 缓存和变量,然后向客户端发送 SYN ACK 报文段,报文段的首部中 SYN 和 ACK 标志位都被置为1,代表这是一个对 SYN 连接请求的确认,同时序号字段是服务器端产生的一个任选的随机数seq = y,它代表是服务器端数据的初始序号。确认号字段为客户端发生的序号 +1,即ack = x+1。
第二次握手后,客户端的状态为SYN-SENT、服务端的状态为SYN-RECV
第三次握手,客户端接受到服务器的肯定应答后,他也会为这次TCP连接分配缓存和变量,同时向服务器端发送一个对服务端的报文段的确认ACK=1,seq=x+1,ack=y+1,。第三次握手可以在报文段中携带数据。第三次握手后,两方状态均为 ESTABLISHED
为什么TCP握手要是三次
这个信息的本质是,信道不可靠,但是通信双发需要就某个问题达成一致。而要解决这个问题,3次通信是理论上的最小值。所以三次握手不是TCP本身的要求,而是为了满足 在不可靠信道上可靠地传输信息这一需求所导致的。这是一个互相确认序号的过程,如果只用两次握手,那么服务器就没法知道自己的序号是否已经被确认,此时客户端不会响应服务器的确认且不发送数据,而服务器则一直等待客户端发送数据,浪费资源。同时这样也是为了防止失效的请求报文段被服务器接收,而出现错误的情况。
*TCP四次挥手
因为TCP是全双工的,也就是通信的双方可以向对方发送和接收信息,所以断开连接需要双方的确认
第一次挥手,客户端认为没有数据要再发送给服务器端,它就像服务器发送一个 FIN=1,seq=u 报文字段,申请断开客户端到服务器端的连接。发送后客户端进入 FIN_WAIT_1 状态
第二次挥手,服务器端接收到客户端释放连接的请求后,向客户端发送一个确认报文段(ACK=1,ack=u+1,seq=v),表示已经接收到了客户端释放连接的请求,以后不再接收客户端发送过来的数据。但是因为连接是全双工的,所以此时,服务器端还可以向客户端发送数据。服务器端进入 CLOSE_WAIT 状态。客户端收到确认后,进入 FIN_WAIT_2 状态。
第三次挥手,服务器端发送完所有数据后,向客户端发送 FIN=1,ACK=1,seq=w,ack=u+1 报文段,申请断开服务器端到客户端的连接,发送后进入 LAST_ACK 状态
第四次挥手,客户端接收到 FIN 请求后,向服务器端发送一个确认应答(ACK=1,seq=u+1,ack=w+1),并进入 TIME_WAIT 阶段,该阶段会持续一段时间,这个时间为报文段在网络中的最大生存时间2MSL,如果该时间内服务端没有重发请求的话,客户端进入CLOSED的状态,这样全双工连接就被释放了,如果服务器端没有接收到客户端发送的确认应答,则会重传释放报文段。
四次挥手为什么要等待2MSL
- 确保客户端发送的最后一个ACK报文段能够到达服务器端
- 防止已失效的连接请求报文段出现在本连接中 最后一次挥手中,客户端会等待一段时间再关闭的原因,是为了防止发送给服务器的确认报文段丢失或者出错,从而导致服务器端不能正常关闭。
挥手为什么是四次
TCP使用四次挥手的原因是因为TCP的连接是全双工的,所以需要双方分别释放到对方的连接,单独一方的连接释放,只代表不能再向对方发送数据,连接处于的是半释放的状态。