什么是TCP?
TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层协议,它在数据传输过程中提供可靠的、有序的、错误检测和恢复的数据传输
说人话就是:两者在传数据之前要先连接一下
TCP的历史
我们都知道 计算机早期是20世纪50年代末,二战时期,为了计算弹道,美国陆军机械部在马里兰州的阿拉伯丁设立了“弹道研究实验室”, 计算机便是在这个背景下诞生的。
话说战争为什么很多次都是战争在推动科技的进步?
当时美军为了保证计算网络的稳定性,建设了一个军用网络,也就是NCP,是不是听起来有点熟悉(不是NPC哈)这也是最早的“互联网”
但我们都知道计算机的种类有很多,最常见的就是我们现在的移动端和PC端。
随着计算机的种类越来越丰富,NCP协议的弊端也就暴露出来了,也就是 不支持跨平台 即 手机和电脑之间不能进行通信,最大的影响就是你摸鱼时不能用公司的电脑撩小妹妹了,气不气~
为了解决你的后顾之忧,罗伯特·卡恩和 温特·瑟夫 这两个被称为互联网之父的男人在1974年正式提出了TCP/IP协议,据说当时使用了TCP/IP协议的数据包在在距离10万千米得到传输过程中没有丢失一个数据包,随后TCP/IP便渐渐的取代了NCP协议。
那好奇的同学和不好奇的同学就有疑问了
Q:丁老师,什么是面向连接啊 ,我听过面向对象,但没有听过面向连接
A:不错,不错,面向连接是一种通信方式,在通信前建立连接,通信结束后再断开连接,这样就确保了通信的可靠性和完整性
Q:丁老师,那为什么要握手和挥手啊,为了讲礼貌吗?
A:嗯…
TCP握手和挥手是为了建立和关闭一个可靠的连接。
握手过程中,客户端和服务器之间交换信息以确认对方可以正常通信,从而建立连接;
而挥手过程中,双方都确认对方已经关闭连接,避免出现数据丢失或混乱的情况。这样可以保证数据的可靠传输。
这就好比你中学时背着爸妈给你对象打电话
握手是为了保证你对象现在方便且可以接你的电话
挥手是为了保证你对象听完了你的甜言蜜语并挂掉了电话,避免你对象没听到你想了半天的小情话
Q:可是俺中学没有对象
A:没关系 学长给你 new 一个
Q:…
Q:那具体的流程是怎样的啊
在介绍三次握手流程之前,我觉得有必要给大家介绍一下TCP的报文结构
TCP的报文结构
TCP报文的固定长度与IP报文一致,都是20字节
源端口(source port):16 bits,标识数据发送端的应用层程序
目的端口(destination port):16 bits,标识数据接收方的应用层程序。
取值范围为0~65535
序列号(sequence port):32 bits ,标识数据发送方所发出数据的编号,序列号以字节为单位。是一个的随机数字
确认号(acknowledge port):32 bits,标识数据接受方期望下次收到的数据编号(数据接受方表示之前的数据都接受到了,数据发送方,你下次得发这个标号得数据了)。
报头长度(header length):4 bits,标识TCP报头的长度,单位是4字节。所以说TCP的报头的长度范围为20~60字节。
保留位(reserverd): 3 bits
标志位(flag):9 bits
bit 1: nonce:详见RFC 3450,同样是关于ECN相关的一个参数
bit 2: congestion window reduce(CWR),拥塞窗口减小,CWR =1表示链路拥塞,会减少TCP窗口。
bit 3:ECN-Echo(ECE):explicit congestion Notification显式拥塞报告
bit 4:Urgent (URG):紧急,标志高优先级的紧急数据,URG=1表示报文中有紧急数据,需要优先处理,并且URG=1,TCP报头中的紧急指针字段才会生效
bit 5:ACK(acknowledgement):确认,表示TCP报头中的确认号是否有效,ACK = 1代表有效。
bit 6:Push (PSH):推送,PSH=1,表示需要把接收到的数据推送给上层应用程序,而不是缓存起来
bit 7:Reset(RST):重置,复位,RST = 1
bit 8:Syn,同步,表示请求建立连接,并同步双方的序列号
bit 9:Fin ,FIN = 1,表示数据已经发送完毕,请求关闭连接。
窗口大小(windows size):16 bits,用于表示数据接收方当前可以接收的最大的数据量,单位是字节。窗口大小其实代表了数据接受方当前缓存池的大小,告知发送方不要一次发送过量的数据。这个大小会根据传输的拥塞情况进行调整
检验核(checksum):16 bit,用于TCP头部+应用层数据的差错校验
紧急指针(urgent point):16 bit,表明紧急数据的字节数,与序列号搭配使用,单位是字节
可选项&填充数(option & padding):用于协商一些其他的参数。最常用的协商MSS(最大分段长度)。
三次握手
第一次握手(SYN=1, seq=x):
客户端发送一个 TCP 的 SYN 标志位置1的包,指明客户端打算连接的服务器的端口,以及初始序号 X,保存在包头的序列号(Sequence Number)字段里。
发送完毕后,客户端进入 SYN_SEND 状态。
第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1):
服务器发回确认包(ACK)应答。即 SYN 标志位和 ACK 标志位均为1。服务器端选择自己 ISN 序列号,放到 Seq 域里,同时将确认序号(Acknowledgement Number)设置为客户的 ISN 加1,即X+1。 发送完毕后,服务器端进入 SYN_RCVD 状态。
第三次握手(ACK=1,ACKnum=y+1)
客户端再次发送确认包(ACK),SYN 标志位为0,ACK 标志位为1,并且把服务器发来 ACK 的序号字段+1,放在确定字段中发送给对方,并且在数据段放写ISN的+1
发送完毕后,客户端进入 ESTABLISHED 状态,当服务器端接收到这个包时,也进入 ESTABLISHED 状态,TCP 握手结束。
四次挥手
第一次挥手(FIN=1,seq=x)
假设客户端想要关闭连接,客户端发送一个 FIN 标志位置为1的包,表示自己已经没有数据可以发送了,但是仍然可以接受数据。
发送完毕后,客户端进入 FIN_WAIT_1 状态。
第二次挥手(ACK=1,ACKnum=x+1)
服务器端确认客户端的 FIN 包,发送一个确认包,表明自己接受到了客户端关闭连接的请求,但还没有准备好关闭连接。
发送完毕后,服务器端进入 CLOSE_WAIT 状态,客户端接收到这个确认包之后,进入 FIN_WAIT_2 状态,等待服务器端关闭连接。
第三次挥手(FIN=1,seq=y)
服务器端准备好关闭连接时,向客户端发送结束连接请求,FIN 置为1。
发送完毕后,服务器端进入 LAST_ACK 状态,等待来自客户端的最后一个ACK。
第四次挥手(ACK=1,ACKnum=y+1)
客户端接收到来自服务器端的关闭请求,发送一个确认包,并进入 TIME_WAIT状态,等待可能出现的要求重传的 ACK 包。
服务器端接收到这个确认包之后,关闭连接,进入 CLOSED 状态。
客户端等待了某个固定时间(两个最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,没有收到服务器端的 ACK ,认为服务器端已经正常关闭连接,于是自己也关闭连接,进入 CLOSED 状态。
所有内容会在公粽号【CV工程师丁Sir】最先发布!点点关注,一起进步!