TCP
Transmission Control Protocol,传输控制协议,传输层通信协议。
采用“带重传的肯定确认”(Positive Acknowledge with Retransmission)技术实现数据传输服务的可靠性。
- 超时重传:如果发送端实体在合理的往返时延(RTT)内未收到ACK确认,则假定数据包已丢失并重传;
- TCP用一个校验和函数来检验数据是否有错误,在发送和接收时均要计算校验和;
- MD5认证对数据进行加密;
- TCP采用滑动窗口机制提高网络吞吐量、同时解决端到端的流量控制;
特点
- 有状态的通信协议,基础是建立连接(连接建立耗费资源);
- 面向连接(实质是虚连接)的双通道通信服务:TCP连接(全双工通信),发送缓存和接收缓存;
- 高可靠性(数据无丢失、数据无错误、数据无重复、数据无失序)的端到端数据传输服务:SSL(Secure Socket Layer,安全套接字层,加强版的TCP)提供安全服务;
- 流模式:用于传输大量数据,但是速度慢;
- 流量控制和拥塞控制:滑动窗口机制(Sliding Window);
- 基于TCP的应用层协议:FTP、Telnet、SMTP、HTTP、POP3、DNS;
- 点对点、端到端、进程到进程的通信,不支持组播与广播;
报文协议
具体参考:计算机网络基础 - sqh 报文协议部分;协议森林08 不放弃 (TCP协议);
三次握手:Three-way Handshake
TCP的创建过程和连接拆除过程由TCP/IP协议栈自动完成,三次握手的目的是连接服务器指定端口、建立TCP连接,同步连接双方的序列号和确认号并交换TCP窗口(滑动窗口机制)大小信息。握手前,客户端和服务端都处于CLOSED状态。服务端创建socket对象、绑定地址、开始监听客户端连接,处于LISTEN状态;客户端创建socket,向服务端发送连接请求、准备连接。
- 建立连接时,客户端发送SYN包(SYN=j)到服务器,并进入SYN_SEND状态,等待服务器确认连接;
- 服务器收到SYN包,确认客户端的SYN(ACK=j+1),同时自己也发送一个SYN包(SYN=k), 即SYN+ACK包,此时服务器进入SYN_RECV状态;
- 客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ACK=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态;
其中,SYN_SEND和SYN_RECV状态非常短暂。
确认号ACK:数值等于发送方的发送序号+1(SYN+1) (即接收方期望接收的下一个序列号)。
四次挥手:Four-way Handshake
- Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
- Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1,Server进入CLOSE_WAIT状态,Client收到ACK信号后进入FIN_WAIT_2状态。
- Server发送一个FIN,关闭Server到Client,Server进入LAST_ACK状态。
- Client收到FIN后,Client进入TIME_WAIT状态,并发送一个ACK给Server,确认序号为收到序号+1,等待一个2MSL(最大报文段生存时间,Max Segment Lifetime)时间之后,Client变成CLOSED状态;Server收到ACK后进入CLOSED状态。
注意,一个TCP连接存在双向的读写通道,完整的TCP连接释放一共需要四个阶段: “先关读,后关写”,以Client发起关闭连接为例:
服务器读通道关闭 ---> 客户机写通道关闭 ---> 客户机读通道关闭 ---> 服务器写通道关闭
- 第一阶段:客户机发送完数据之后,向服务器发送一个FIN数据段,序列号为i;
- 服务器收到FIN(i)后,返回确认段ACK,序列号为i+1,关闭服务器读通道;
- 客户机收到ACK(i+1)后,关闭客户机写通道;
(此时服务端还可以向客户端发送数据(半连接状态):客户机仍能通过读通道读取服务器的数据、服务器仍能通过写通道写数据)
- 第二阶段:服务器发送完数据之后,向客户机发送一个FIN数据段,序列号为j;
- 客户机收到FIN(j)后,返回确认段ACK,序列号为j+1,关闭客户机读通道;
- 服务器收到ACK(j+1)后,关闭服务器写通道。
TCP连接过程图和状态转换图
注:服务器和客户机都可以发起和关闭,完全对称。Client和Server端间的一个TCP逻辑连接,实际上是两条成对的物理连接:
- 创建连接时,有Client端和Server端的区分;
- 断开连接时,没有特别区别,只有主动断开和被动断开的差别;
客户端状态变迁
CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED
服务端状态变迁
CLOSED->LISTEN->SYN收到->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED
参考:
UDP
User Datagram Protocol,即用户数据报协议,传输层通信协议。
UDP协议的主要作用是将网络数据流量压缩成数据包的形式传输,传输可靠性(到达确认、分组传输顺序的检查与排序)由应用层负责。同TCP一样,UDP协议使用端口号为不同的应用保留其各自独立的数据传输通道,实现同一时刻内对多个应用程序同时发送和接收数据的支持。IETF RFC 768是UDP的正式规范,UDP在IP报文的协议号是17。
特点
- 轻量级,无连接的;
- 面向事务,简单不可靠的数据传输服务、不需要接收方确认,Best Effort;
- 数据包模式:用于传输少量数据,但是速度快;
- 没有流量控制和拥塞控制机制;
- 基于UDP的应用层协议:TFTP、SNMP、DNS;
- 广播发送,支持1对1、1对多、多对1和多对多的交互通信;
正因为UDP协议的控制选项较少,数据传输资源消耗少、延迟小、效率高,适合对可靠性要求不高、高速传输或有实时性要求的应用程序(流媒体、实时游戏)。
报文协议
具体参考:计算机网络基础 - sqh 报文协议部分;协议森林07 傀儡 (UDP协议);
常见问题:
[1]. 为什么TCP建立连接需要三次握手?断开连接需要四次挥手?
- 三次握手:防止服务器端因为接收了早已失效的连接请求导致一直等待客户端请求、浪费资源;(解决网络中存在延迟的重复分组的问题)
- 四次挥手:保证双方都能通知对方“需要释放连接”,在连接释放前确保数据完成传输、释放后无法接收或发送消息;(S端接收到FIN包意味着不会再有数据接收,但是还可以继续发送数据)
[2]. 主动发起关闭连接的一方从TIME_WAIT状态、为什么要保持2MSL的时间才进入CLOSED状态?
- 保证TCP协议的全双工连接能够可靠关闭(全双工关闭);
- 保证此次连接的重复数据段从网络中消失;
[3]. TCP采用哪些机制来实现可靠数据传输、流控和拥塞控制?
- 采用面向连接的三次握手实现可靠对象传输;
- 使用数据窗口机制协商队列大小实现数据队列传输;
- 通过序列化应答和必要时重发数据包,TCP为应用程序提供了可靠的传输流和虚拟连接服务;
[4]. TCP与UDP的对比学习
- TCP通信就像打电话,双方通信前需要建立连接、双方就位后才可以开始会话;UDP通信就像发短信,一方给另一方发送数据前,并不需要对方就位。
- 如果把TCP传输数据比如成河里的流水;UDP传输数据就是邮局寄信或发送短信。
- 如果每次连接时间较短,或者即时性要求高、发送内容较少,采用UDP;对数据完整性、可靠性要求较高,传输性能要求较低时采用TCP。(QQ聊天软件:UDP为主、TCP为辅,避免服务器负载过大。)
- 首部开销:UDP小、8个字节,TCP大、20个字节;
参考:QQ 为什么采用 UDP 协议,而不采用 TCP 协议实现?
[5]. TCP三次握手中,ACK确认包丢失怎么办?
- 第二次握手的ACK确认包
三次握手保证该ACK确认包,如果丢失,客户端需重新发送SYN包进行握手连接;
- 第三次握手的ACK确认包
错误方法:按照TCP协议处理丢包的一般方法,服务端重新向客户端发送FIN包,直至收到ACK确认为止,但实际上这种做法有可能遭到SYN泛洪攻击。
正确方法:服务端发送RST报文进入CLOSE状态。RST数据包的TCP首部中,设置控制位RST=1表示连接信息全部被初始化、原有的TCP通信不能继续进行。客户端如果还想重新建立TCP连接,必须重新开始第一次握手。
[6]. TCP四次挥手中,ACK确认包丢失怎么办?
- 第二次挥手的ACK确认包
四次挥手保证该ACK确认包,如果丢失,客户端需重新发送FIN包进行挥手关闭连接;
- 第四次挥手的ACK确认包
第三次挥手中,客户端收到服务端发来的FIN包并返回ACK包给服务端,同时设置一个计时器等待2MSL,客户端进入TIME_WAIT状态,ACK包发送成功后(2MSL内)双方变为CLOSED状态。如果客户端返回的ACK包丢失,服务端会重发FIN包、处于TIME_WAIT状态的客户端再次返回ACK包并重置计时器。假设在计时器失效前(2MSL)服务器重发的FIN包没有到达客户端,客户端就会进入CLOSED状态,导致服务端永远无法收到ACK确认、无法关闭连接。 如果客户端不等待2MSL直接进入CLOSED状态,当客户端返回的ACK丢失,服务端会重发FIN包、客户端会返回RST包,指示TCP连接重置;
参考