TCP内核中的建立连接
众所周知,TCP是有连接的.
当我们在客户端敲出socket =new Socket(serverIp,severPort)时,就在系统内核就在建立连接
真正建立连接是在系统内核中建立的,我们程序员只是调用相关的api.
在此处,我们把TCP的建立连接称为三次握手.
系统在内核建立连接时如上图所示,总共有四次交互,但是在实际过程中,其中的两次交互能够合二为一,所以我们称作"三次握手"
这个所谓的建立连接的过程,本质上就是通信双方各自给对方发起一个syn,各自给对方回应一个ack.
(这里客户端的信息告知服务器 这个操作确实在第一次握手的时候就完成了,但是最终确立这个连接要建立,确立出,后续要进行通信,得把所有的流程都走完)
虽然第一次"握手",客户端已经把自己的信息告诉服务器了,但是服务器具体是否要确定存储这个信息,还得再看看.
等到所有的"握手"环节都完成后,服务器才会最终保存客户端的相关信息.
首先,我们客户端作为发起通信的一方,应该首先发起syn(同步报文段),
此处的syn是一个特殊的TCP数据报.
1.没有载荷.不会携带应用层数据.
2.六个标志位中的第五位,为1.
虽然syn不会带有应用层载荷,但是也会带有IP报头/以太网数据帧帧头...更会有TCP报头
TCP包头就包含了客户端自己的端口.IP报头中就包含了客户端自己的IP.(这个过程,也是客户端在告诉服务器,我是谁)
这里当客户端第一次给服务器发起syn(同步报文)时,有两种可能性
1.服务器同意了,服务器表示我也愿意和你建立连接
2.服务器没同意.(一般来说这种情况比较少见,就是服务器负载极高的情况下,服务器完全无法响应,客户端太多了,直接就没下文了)
服务器收到syn之后,会返回ack(确认应答),意思就是收到了
接下来服务器还会再返回syn,代表我接收你的连接(我也愿意和你建立连接)
这里的syn指的是synchronized,同步,就是使其进入连接状态.客户端服务器就得相互配合好一系列工作.
syn这样的数据包,不携带载荷,没有应用层数据,也就不代表任何应用程序的业务逻辑,syn起到的作用就只是"打招呼",因此我们就把这个动作称为"握手".
简略版的三次握手
详细版三次"握手"
三次"握手的意义"
1.三次握手,可以针对通信路径,进行投石问路,初步的确认一下通信链路是否畅通.(可靠性的前提条件)(关注点在中间过程)
2.三次握手,也是在验证通信双方,发送能力和接收能力是否正常.(关注点在两端)
(1)客户端首先发送一个syn报文,服务器就会知道客户端的数据发送能力和服务器的数据接收能力是正常的,但是此时客户端并不知道.
(2)服务器给客户端返回syn+ack报文,客户端就会知道自己的数据接收和服务器的数据发送功能是正常的,也包括客户端的数据发送和服务器的数据接收功能,但是服务器此时并不知道
(3)客户端给服务器返回ack报文,此时,服务器就知道了自己的数据发送和客户端的数据接收功能是正常的,当然也包括客户端的数据发送和服务器的数据接收功能是正常的.
3.三次握手的过程中也会协商一些必要的參数
通信是客户端服务器两方的事情.要配合.其中的有些内容要保持一致.
TCP中也是有很多參数要进行协商的.往往是以"选项"部分来体现的.
最少0字节
最多40字节
其中有一个关键的信息,TCP通信的序号,起始值.
TCP一次通信过程中,序号不是从0或者从1开始计算的.
而是选择一个比较大的数字,以这个数字开头来计算的
即使是同一个客户端和服务器,每次连接,开始的序号都会不同,(这样设计主要是为了避免"前朝的剑,斩本朝的官").
第一次连接的过程中,传输的有一个数据包,还没有发送成功,还在数字链路里面进行等待,迟迟没有到达对端.等待终于到了对端的实收,已经是另外一个客户端,另外一次连接了,之前的连接早没了,现在是新的连接了!!
此时,这份数据应该被丢弃!!数据报按照ip+端口进行识别.第一个连接,是用客户端A来连的.第二个连接是用客户端B来连的.(恰好是同一个端口的话,客户端概率是比较低的,服务器概率很大)
此时数据到达这一边,早已不是之前的客户端了,再把这个数据进行发送,就不合适了,
此时,应该丢弃这个数据包
在这种情况下,如何识别出数据是之前的数据包??
就是通过序号识别出来的!!
(序号是不同的,也不是随机的,背后还有一系列分配策略)
正常数据包的序号都是从开始序号往后依次排的.就算偶尔丢包,偶尔数据部连续,差异也不会很大.
"前朝"的数据包的序号和本朝的数据包的序号差异是非常大的,很容易一眼识别出来
断开连接(四次挥手)
连接,本质上就是让通信双方保存对方的信息!!
每个客户端/服务器,都要保存很多的对端信息.
一旦多了,就要使用"数据结构".
断开连接的本质目的,就是为了把对端的信息,从数据结构中删除掉/释放掉.
有了"逻辑删除之后",此时就相当于断开连接了.