TCP三次握手原理
本文主要内容1、TCP数据包格式TCP数据包格式如下:注意到中间还有几个标志位:数据包格式当中,最重要的是理解序号和确认序号。TCP为什么是稳定可靠的,与序号与确认序号这套机制紧密相关,这也是TCP的精髓。2、TCP的三次握手众所周知,TCP协议是可靠的,而UDP协议是不可靠的。在一些场景中必须用TCP,比如说用户登录,必须给出明确答复是否登录成功等。而有些场景中,用户是否接收到数据则不那么关键,比如网络游戏当中,玩家射出一颗子弹,另外的玩家是否看到,完全取决于当前网络环境,如果网络卡顿,就会有玩家已经被射杀,但界面仍然刷新不出来的情况。这种情形适合UDP。为了保证TCP协议可靠,在建立连接之时就要得到保证。最初两端的TCP进程都处于CLOSED关闭状态,A主动打开连接,而B被动打开连接。(A、B关闭状态CLOSED——B收听状态LISTEN——A同步已发送状态SYN-SENT——B同步收到状态SYN-RCVD——A、B连接已建立状态ESTABLISHED)B服务器进程就处于LISTEN(收听)状态,等待客户的连接请求。若有,则作出响应。3、TCP的传输和确认TCP 传输的可靠性,可以用一句话归结:每收到对方数据,就发送 ACK 进行确定,发送方发送后没有收到 ACK 就隔一段时间重发。就是 A 向 B 发送消息(下面将 TCP 的报文直接看做是消息,消息一词跟 TCP 报文混用),B 收到消息后需要向 A 发送 ACK。这个 ACK 相当于返回结果,没有返回结果,A 就重新发送消息。归纳起来,A 有 3 种消息需要确认。另外 A 也可以发送 RST 消息,代表出错了。出错消息不需要确认。RST 也可以当成返回接口,替代正常的 ACK。返回 ACK,表示消息发送并处理成功,返回 RST 表示消息处理失败。因为通过网络传输,还有第三种结果,就是不确定成功失败。这样归纳起来。就有三种返回结果。这两种具体情况,A 根本识别不了,都只能重发。4、TCP的序号和确认序号A 向 B 发送消息,假如同时发送 a、b、c、d 消息,因为通过网络,这些消息的顺序并非固定的。而 B 返回 ACK 结果,这样就有一个问题,这个结果到底对应了哪个消息?另外当 A 超时重发后,原来的消息延时一段时候,又重新到达了 B,这样 B 就收到两条相同的消息,那么 B 怎么确定这两条消息是相同的呢?为了解决这个对应问题,每一条消息都需要有一个编号,返回结果也应该有一个编号。TCP 的序号可以看成是发送消息的编号,确认序号可以看成是返回结果的编号。有了编号,重复的消息才可以忽略,返回结果(ACK)才可以跟消息对应起来。当建立连接的时候,TCP 选定一个初始序号,之后每发送一个数据包(消息),就将序号递增,保证每发送不同的数据包,数据包的序号都是不同的。TCP 是这样处理的:SYN、FIN 也需要递增序号。不然 A 向 B 重发多个 SYN 或者 FIN, B 根本判断不了 SYN 是否相同,这样就不可以忽略重复的数据包了。当 TCP 发送 ACK 时,相当于返回结果,需要带有确认序号,以便跟发送的消息对应起来。当发送包编号为 a,递增长度为 len。其中 SYN 和 FIN 可以看成是递增长度为 1。这条消息可以这样表示为:现在来回顾三次握手过程。 A 发送序列号x给 B , B 回复 A 确认号 x+ 1,同时发送序列号 y, A 接收到 B 的回复后,再回复确认号 y+1,同时发送序列号 x+1。给对方的回复一定是接收到的序号加1(或者是数据长度),这样对方才能知道我已经收到了,这样才能保证TCP是可靠的。

三次握手的序列标识
序列号在TCP连接中发送的字节都有一个序列号。因为编了号,所以可以确认它们的收到。对序列号的确认是累积性的。TCP必须进行的序列号比较操作种类包括以下几种:①决定一些发送了的但未确认的序列号。②决定所有的序列号都已经收到了。③决定下一个段中应该包括的序列号。对于发送的数据TCP要接收确认,确认时必须进行的:SND.UNA = 最老的确认了的序列号。SND.NXT = 下一个要发送的序列号。SEG.ACK = 接收TCP的确认,接收TCP期待的下一个序列号。SEG.SEQ = 一个数据段的第一个序列号。SEG.LEN = 数据段中包括的字节数。SEG.SEQ+SEG.LEN-1 = 数据段的最后一个序列号。如果一个数据段的序列号小于等于确认号的值,那么整个数据段就被确认了。而在接收数据时下面的比较操作是必须的:RCV.NXT = 期待的序列号和接收窗口的最低沿。RCV.NXT+RCV.WND:1 = 最后一个序列号和接收窗口的最高沿。SEG.SEQ = 接收到的第一个序列号。SEG.SEQ+SEG.LEN:1 = 接收到的最后一个序列号。

TCP三次握手的序列号分析
4、-> ack XXXX(xx表示载荷包。因为第3步仅是一个确认包,它没有包含任何有效数据,所以这里的Seq仍旧是4071231309。仍旧是对第2步确认) TCP: Sequence number =4071231309TCP: Acknowledgement number =1191340144一般应用都是客户端先向服务器发数据的。这个过程有几个规则:规则1、累计确认。接收端对收到的载荷包(数据字段有值的TCP包),回应一个确认包,确认号是所收到包的TCP数据字段最后一个字节+1。规则2、捎带确认。载荷包必须捎带确认字段。这样可以减少网络流量。 规则3、虚字节。有些数据包(ACK)不携带任何数据,所以不消耗序列号,也就是说仍旧保持不变。
TCP: Sequence number = 1191340145 TCP: Acknowledgement number =40712313101TCP: Sequence number = xTCP: Acknowledgement number =y2TCP: Sequence number = yTCP: Acknowledgement number =x+13TCP: Sequence number = x+1TCP: Acknowledgement number =y+14:TCP: Sequence number = y+1TCP: Acknowledgement number =x+2 ……
TCP需要三次握手才能建立连接,那么为什么需要三次握手呢?

为什么TCP/IP需要三次握手
至少这样正常的三次交流双方都能够知道并且确认对方初始的序列号,也就是说主机1告诉主机2序列号,主机2回复主机1说收到了你的序列号并告诉主机1我的初始序列号是什么,主机1收到来自主机2的序列号以后,告诉主机2,我也收到你的序列号了。看一下对于特殊情况,这三次握手是如何处理的:这个时候,主机2对与这个过期的CR包,将会发送确认给主机1问问是否真的是有这个包,而对于过期的DATA包,主机2会识别到序列号不对而忽略。这个时候,主机2收到的CR包将被忽略,而DATA包也会因为序列号不对而被丢弃这时主机2会发送一个确认请求给主机1,问问他是否存在这个请求,而主机1回应说我已经放弃这个请求了,所以回复REJECT(ACK = y)拒绝主机2,主机2知道后就不再理会。假设主机1向主机2发送一个请求,这个请求在网络中游荡了好久,主机2还没有收到,这是主机1看见没有反应,放弃不再请求,而之前发送的这个请求才到达主机2:假设主机1向主机2发送的CR(seq = x)包以及DATA(seq = y, ACK = z)包都在网络中游荡了很久,而这时主机1已经和主机2建立了可靠的连接(seq = x + 100,ACK = y + 200)假设主机1向主机2发送的CR(seq = x)包以及DATA(seq = y, ACK = z)包都在网络中游荡了很久,而这时主机1与主机2并没有建立连接总之,三次握手后能够确保双方都能知道对方的初始序列号,而防止误收数据包的一个关键就是使用序列号进行确认

什么是三次握手
三次握手: 所谓的“三握手”:对每次发送的数据量是怎样跟踪进行协商使数据段的发送和接收同步,根据所接收到的数据量而确定的数据确认数及数据发送、接收完毕后何时撤消联系,并建立虚连接。为了提供可靠的传送,TCP在发送新的数据之前,以特定的顺序将数据包的序号,并需要这些包传送给目标机之后的确认消息。TCP总是用来发送大批量的数据。当应用程序在收到数据后要做出确认时也要用到TCP。
tcp利用三次握手法建立连接的正常过程: 在三次握手第一次中主机A向主机B发出连接请求,其中包含主机A选择的初始序号x;第二次主机B收到请求后发出连接确认,其中包含主机B选择的初始序号y,以及主机B对主机A初始序号x的确认,第三次主机A向主机B发送序号为x的数据信息,其中包含主机A对主机B初始序号的确认

本文由 在线网速测试 整理编辑,转载请注明出处。