本文主要是介绍服务器tcp第三次发送信息,TCP的绅士行为—gt;“三次握手”,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
为什么说TCP的握手是一种绅士行为?
于UDP直接对数据发送的蛮横粗鲁相比,TCP通过握手(报文段交换)的方式来实现两者之间的沟通是否就很“Gentleman”了呢?
我们知道,UDP是面向无连接的,这种方式使得UDP的首部小(仅8个字节),不会因为建立连接而增加额外的开销和数据发送之前的时延。
但TCP是面向连接的,是端到端的,属于两个人之间的事。其实这个过程颇类似于打电话,应用程序必须建立连接(把电话拨通),彼此之间才能通信(两者进行交流),通话结束后还需要释放连接(挂掉电话)。
TCP连接方式是CS模式(Client 客户端 Server服务器),客户端发出连接请求,服务器端一直处于监听模式,来等待客户端的请求。
为保证TCP连接有效稳定建立的三个问题:
1、要使双方都能确认对方的存在。保证两者能够进行消息传递。
2、允许双方根据网络情况来协商TCP首部的一些参数。(如窗口数值大小,时间戳)现实中的网络是不断变化着的,所以应动态的修改参数来维持稳定的连接。比如网络状况不算良好,则应适当减小窗口值,减轻网络拥塞。
3、能够对运输实体资源进行分配。(如接收方和发送方的缓存区大小)让接收到的数据有处可居。
okay,下面我们开始来谈谈关于三次握手的原理。首先了解TCP首部需要知道的一些关键字:
确认ACK位 :只有当ACK = 1时,确认字段才有效。TCP规定,在建立连接后所传送的报文段都必须是ACK=1。
确认号ack 对收到数据包的确认,值是等待接受的数据包的序列号(即期望对方继续发送的那个数据包的序列号)。
(确认号ack != ACK ACK是位于首部的一个位 表示确认号有效)
序号seq:在一个tcp连接中传送发的字节流的每一个字节都需要按照顺序编号 值为所发数据地址
同步SYN位:建立连接时候用来同步序号 当SYN=1而ACK=0的时候,表明这是一个来凝结请求报文段。若同意建立连接则响应报文段中的 ACK =1,SYN =1.
了解这些关键字之后,大概就可以来讲述关于三次握手的详细过程了。1、客户端发送连接请求,向服务器端发送自己想牵她手的想法。
通过上面的首部关键字SYN 我们可以知道 Client客户端发送的tcp首部ACK需要置1 才能表明自己的心意,同时需要消耗一个序号x 数据部分为空
此时客户端进入SYN-SENT状态(同步已发送)2、服务器端接收到来自客户端的连接请求后,若同意建立连接,便向客户端发送确认信息,服务器端将把SYN 置 1 确认号ack = x+1 seq = y 准确的来说,服务器端发送的报文段信息和上一步客户端发送的报文段是太大区别的,类似传统的握手,你应我答。此时服务器端进入SYN-RCVD(同步接收)状态。但是要记住,此时连接并没有建立!3、客户端收到来自服务器端的报文段信息后,ACK = 1 确认号ack = y+1 seq = x+1
客户端进入ESTABLISHED(连接建立)状态
当服务器端收到来自客户端的确认后,也进入ESTABLISHED状态
(网络图)
在讨论问题之前,不妨先闭上双眼,想象一下在一场晚会上,你穿着燕尾服,寻找一位可以与你一同摇曳在巴赫十二平均律的姑娘。此时映入眼帘的一幕
(希望我的那个谁 能更漂亮点,已经很好了,就是我比较贪 嘿嘿)
你毫不犹豫的看向她,目光瞬间闪烁起来,没错,你流露出想和她一同跳舞的想法了(SYN-SENT),恰好她星眸一瞥,摘落穿戴在手上的蕾丝手套,暗示她收到你的热情了(SYN-RCVD),此刻的你,读懂了她的少女心,你欠了欠身,伸出了自己的手(Client ESTABLESHED) ,她宛然一笑,倾了你思绪里的那座城,也伸出了她的柔荑。(Server ESTABLESHED) 接下来的事,就是你我不能说的秘密啦 ~下面再来讨论为什么需要三次握手而非两次?
本质上来说,主要是为了防止已经失效的连接请求报文段发送到了服务器端,使得数据的发送接收造成混乱。
失效的连接请求报文段的产生原因:1、该报文段丢失,客户端重新发送,这种情况无干扰。2、网络是不稳定的,有延迟的,可能客户端发送的请求报文段,没有丢失,只是在某地耽误了太久,让客户端误认为报文段丢失了,于是客户端重新发送了一份新的请求报文段。
如果只是两次握手的话,第一份的请求数据报文段就会导致服务器端一直处于接收数据的状态,但是客户端利用第二次重新发送的报文段已经获取了它想取得的数据信息,所以根本不会理睬服务器端是什么情况,服务器端傻傻的等,造成了无效的资源浪费。
如果是三次握手的话,即使服务器端收到了来自客户端的请求报文段,也不会立即进入连接建立阶段,而是会向客户端询问一下(step2),但是对于客户端而言,第一份请求报文段早已经失效,所以,就不会理睬服务器端发送的报文信息,不会发送第三次请求( !step3),收不到确认的服务器端,也就不会进入ESTABLISHED阶段,连接自然也就不会建立。为什么建立连接需要消耗序号呢?
这是为了保证之后的通信能够无误的进行,网络的连接并不是稳定的,可能会存在丢失的现象。为了与服务器端建立同步,并明确自己采用的初始序号。SYN报文段是不能丢失的,(传错或者丢失就需要重传,否则无法建立连接)故而采用编号的方式来保证能够有序准确的组成完整的信息。当服务器端收到该报文段的时候给出确认号ack= x+1 表示客户端发送的SYN报文段已经准确接受到(客户端发送的请求已接收)。那么TCP传输为什么不可以是四次握手呢?
三次握手是因为握手请求同步过程中并不需要数据传输因此可以将两次(确认 +同步)合并为一次。
首先,我们明确一下,四次握手如果出现,应该出现在哪?
头两次的你侬我侬自然是不会再多出来一次信息的发送的,本质上的四次挥手,是把第三次挥手进行拆解,分成两步进行,
首先是确认报文段(ACK =1,ack = x+1),表示已经接收到来自服务器的信息,再而,就是发送同步报文段(SYN = 1,seq = y),
本质上效果是一样的,但是会有风险。因为不能有效的增加TCP连接的安全性,反而让客户端等待的时间变长,在实际应用中反而不如三次握手直接把后两次直接掐在一起划算的多。如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP设有一个保活计时器(keepalive timer),客户端如果出现故障,服务器不会一直等下去,以免浪费资源。服务器每收到一次客户端的请求后都会重新复位计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
关于三次握手的故事大概也就这么多,小生能力有限,如有错误,欢迎讨论~。
这篇关于服务器tcp第三次发送信息,TCP的绅士行为—gt;“三次握手”的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!