TCP 3向握手的工作方式如下:
Client ------SYN-----> Server
Client <---ACK/SYN---- Server
Client ------ACK-----> Server
为什么不只是这个呢?
Client ------SYN-----> Server
Client <-----ACK------ Server
TCP 3向握手的工作方式如下:
Client ------SYN-----> Server
Client <---ACK/SYN---- Server
Client ------ACK-----> Server
为什么不只是这个呢?
Client ------SYN-----> Server
Client <-----ACK------ Server
Answers:
将握手分解为实际操作。
在TCP中,双方通过使用序列号来跟踪发送的内容。实际上,它最终是发送的所有内容的运行字节数。接收方可以使用对方讲话者的序列号来确认接收到的内容。
但是序列号不是从0开始。它从ISN(初始序列号)开始,这是一个随机选择的值。并且由于TCP是双向通信,双方都可以“讲话”,因此双方都必须随机生成一个ISN作为其起始序列号。反过来,这意味着双方都需要将其初始ISN通知另一方。
因此,您以以下事件序列结束,开始了Alice和Bob之间的TCP对话:
Alice ---> Bob SYNchronize with my Initial Sequence Number of X
Alice <--- Bob I received your syn, I ACKnowledge that I am ready for [X+1]
Alice <--- Bob SYNchronize with my Initial Sequence Number of Y
Alice ---> Bob I received your syn, I ACKnowledge that I am ready for [Y+1]
注意,发生了四个事件:
实际上,中间的两个事件(#2和#3)发生在同一数据包中。使数据包成为一个SYN
或ACK
仅仅是使每个TCP标头中的二进制标志处于打开或关闭状态的原因是什么,所以没有什么可以阻止在同一数据包上同时启用这两个标志。因此,三向握手最终为:
Bob <--- Alice SYN
Bob ---> Alice SYN ACK
Bob <--- Alice ACK
请注意两个方向上“ SYN”和“ ACK”的两个实例,每个实例之一。
因此,回到您的问题上,为什么不仅仅使用双向握手?简短的答案是因为双向握手只会允许一方建立一个ISN,而另一方承认它。这意味着只有一方可以发送数据。
但是TCP是双向通信协议,这意味着任何一端都应该能够可靠地发送数据。双方都需要建立一个ISN,并且双方都需要确认对方的ISN。
因此,实际上,您所拥有的只是双向握手的描述,但是在每个方向上。因此,发生了四个事件。同样,中间两个标志出现在同一数据包中。这样,三个数据包将包含在完整的TCP连接启动过程中。
因为双方都需要的三次握手是必要的顺式 chronize其传输过程中所使用的部分序列号。为此,它们中的每发送(依次)设置为随机值的序列号的SYN段Ñ,其然后被ACK由另一方经由与设置为序列号的ACK段那位博n + 1个。
Eddie
的评论对他的回答。
为了使连接正常工作,每一端都需要验证是否可以将数据包发送到另一端。确保您收到另一端的数据包的唯一方法是从他们那里获得一个数据包,根据定义,除非您发送的数据包通过,否则这些数据包不会被发送。TCP 本质上为此使用两种消息:SYN(请求证明此数据包已通过)和ACK(仅在SYN通过后才发送,以证明SYN已通过)。实际上有第三种信息,但是我们稍后会谈到。
在连接开始之前,任何一方都不了解对方。客户端将SYN数据包发送到服务器,以请求证明其消息可以通过。那没有告诉任何人任何信息,但这是握手的第一步。
如果SYN通过,则服务器知道客户端可以向其发送数据包,因为它刚发生。但这并不能证明服务器可以发回数据包:客户端可以出于多种原因发送SYN。因此,服务器需要将两个消息发送回客户端:一个ACK(证明SYN通过了)和一个SYN(请求自己的ACK)。TCP将这两个消息合并为一个-SYN-ACK消息(如果愿意),以减少网络流量。这是握手的第二步。
由于SYN-ACK是ACK,因此客户端现在确定可以将数据包发送到服务器。并且因为SYN-ACK是SYN,所以它也知道服务器希望证明此消息已通过。因此它发送回一个ACK:这次只是一个普通的ACK,因为它不再需要证明其数据包可以通过的证据。这是握手的最后一步:客户端现在知道数据包可以双向传输,并且服务器即将解决此问题(因为它知道ACK将通过)。
一旦该ACK通过,现在服务器便知道可以向客户端发送数据包了。它还知道客户端知道这一点,因此它可以立即开始发送数据。握手完成。我们有一个很好的渠道。
好吧,严格来说,我们不能确定我们拥有良好的渠道。仅因为此顺序的数据包通过并不能严格保证其他人会通过。我们无法证明,如果不发送无限数量的SYN和ACK,那么将一事无成,因此这不是一个实际的选择。但是实际上,三个步骤对于大多数目的来说已经足够了。
实际上,三向握手并不是建立TCP连接的唯一方法。还允许同时进行SYN交换:http ://www.tcpipguide.com/free/t_TCPConnection EstablishmentmentProcessTheThreeWayHandsh-4.htm
这可以看作是两次双向握手。
如果服务器和客户端要创建连接,则需要确认四件事:
客户端需要确认他可以从服务器接收数据包
客户端需要确认一件事:服务器可以从客户端接收数据包
之后Client ------SYN-----> Server
,确认规则1。
之后Client <---ACK/SYN---- Server
,确认规则2和3。
因此,需要第三个数据包来确认规则4。
完全没有必要。显然,一条短消息只需要向服务器发送一个包含开始+消息的数据包,并向后发送一个确认它的数据包。
前面的答案仅描述了系统,而没有首先讨论对随机序列号等的需求。最初的问题是关于TCP本身的设计的-显然,如果您使用TCP协议,则需要三个消息,因为这是该协议。但是,为什么TCP首先要采用这种方式设计?
我相信最初的想法是客户端和服务器之间没有区别。双方都以双向方式知道对方的端口,并且任何一方都可以开始对话。而这需要Syns等
但这当然不是今天的用法。服务器在一个众所周知的端口上侦听并“接受”,客户端端口号是临时的。我什至认为在正常操作系统中,等待“接受”的服务器不可能在同一客户端端口号上向另一个发送请求。
(请注意,这是关于双向启动连接的,今天从未做过。这与在建立连接后通过连接发送双向消息完全不同。)
要解决TCP效率低下的问题,我们使用HTTP 1.1之类的协议,该协议可以将同一连接重用于多个请求,从而避免了TCP握手,而这种握手一开始就没有必要。
但是Http 1.1相对较新。由于PKI算法的成本,SSL / TLS从一开始就需要一种重用会话的方法。因此,该协议包括自己的会话重用机制,该机制在Http 1.1之上运行,而HTTP 1.1在TCP之上运行。
软件就是这样。捏在一起的软糖会产生可接受的结果。
在阅读了Eddie的答案(被接受为正确的答案)之后,仍然存在一个问题,为什么第一个主机不能同时为两个ISN分配随机数,而第二个主机只能接受它。使用三向握手的真正原因是为了避免半连接。2次握手的半连接情况:
1)客户端--- SYN->服务器
2)客户端改变了主意,不想再连接
3)客户端<-X-ACK--服务器// ACK丢失
服务器未看到重新发送的SYN,因此他认为客户端得到了ACK并建立了连接。因此,服务器具有永远不会关闭的连接