【1】三次握手四次挥手
1》三次握手
第一次握手都又客户端发起,在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。服务器必须准备好接收外来的链接,这通过调用socket、bind和listen函数来完成,称为被动打开。
第一次握手:客户通过调用connect函数进行主动打开(active open)。这引起客户TCP发送一个SYN(表示同步)分节(SYN=J),他告诉服务器客户接下来将在该链接中发送的数据的初始序列号。并进入SYN_SEND状态,等待服务器确认。
第二次握手:服务器必须确认客户的SYN,同时自己也得发送一个SYN分节,他含有服务器接下来将在同一链接中发送的数据的初始序列号。服务器以单字节向客户发送SYN和对客户SYN的ACK(表示确认),此时服务器进入SYN_RECV状态。
第三次握手:客户收到服务器的SYN+ACK。向服务器发送确认分节,此分节发送完毕,客户和服务器都进入ESTABLISHED状态,完成三次握手,链接建立。
三个状态:1.SYN_SEND:客户端发送SYN报文后进入此状态,等待服务器的确认。
2.SYN_RECV:服务器收到SYN报文后进入此状态,等待客户的确认。
3.ESTABLISHED:当客户端和服务器都发送和接受了ACK报文后,链接进入此状态,表示链接已建立,可以进行数据传输。
举个比较形象的例子:
打电话
第一次握手:喂,能听见我说话把?
第二次握手:能听见你说话,你能听见我说话不?
第三次握手:能听见
开始通话
三次握手详细过程说明:
第一次握手:客户端向服务器发送一个用于建立TCP链接的请求报文,该报文中包含seq_c序列号,是由客户端随机生成的,并且将报文中的SYN字段置1,表示要建立TCP链接。(SYN=1,seq_c=200,200是客户端随机生成的)。
第二次握手:服务器对客户端发送过来的TCP请求报文做出回应,也发送一个TCP报文,该报文中包含seq_s序列号,由服务器端随机生成,并将报文中的SYN字段置1,表示建立连接,而且还会包含ACK字段,ACK置1表示却热建立连接,同时还会有一个ack_s确认序号,ack_s的值是客户端发送过来的序列号seq_c的基础上加1,用于告知客户端它的TCP请求报文已得到验证。(seq_s=500,ack_s=201,SYN=1,ACK=1,500是服务器端随机生成的)
第三次握手:客户端收到服务器端发送的TCP链接建立请求后,会再次发送一个TCP报文回复服务器,包含序列号seq_c和确认号ack_c,其中序列号是在自己上一次发的报文的序列号的基础上加1,确认号是在服务器发过来的序列号seq_s的基础上加1,同时还有ACK确认字段置1,用于告知确认链接。(seq_c=201,ack_c=501,ACK=1)
面试练习题:
TCP连接过程:
三次握手
TCP的三次握手发生在哪两个函数之间:
accept、connect
为什么一定是三次握手,而不能是两次握手?
主要是为了防止已经失效的链接请求报文突然又传送到了服务器,从而导致不必啊要的错误和资源浪费。两次握手只能保证单项链接是畅通的,因为TCP是一个双向传输协议,只有经过第三次握手,才能确保双向都可以接受到对方发送的数据。
2》四次挥手
四次挥手既可以由客户端发起,也可以由服务器端发起
第一次挥手:客户端发送一个FIN,用来关闭客户端到服务器的数据传送,客户端进入FIN_WAIT-1状态第二次挥手:服务器端收到FIN后,发送一个ACK给客户端,告诉客户端我已经收到你发过来的FIN报文,但此时可能还未传完数据,服务器端进入CLOSE_WAIT状态,;客户端收到该报文后会进入FIN_WAIT-2状态
第三次挥手:服务器端传送完数据了,向客户端发送一个FIN报文,用来关闭服务器端到客户端的数据传送,服务器进入LAST_ACK状态
第四次挥手:客户端收到FIN后,向服务器端发送一个ACK报文,告知服务器端我已收到你的FIN结束报文,客户端进入等待2MSL后进入CLOSED状态,服务器端在收到客户端发过俩的确认报文或也会进入CLOSED状态,连接断开。
举个比较形象的例子:
打电话
第一次挥手:我说完了,我要挂了
第二次挥手:好的,我知道了,但是你先别急,等我把话说完
第三次挥手:好了,我说完了,咱们可以挂电话了
第四次挥手:好的,挂了吧
四次挥手过程详细说明:
第一次挥手:客户端发送断开TCP链接请求的报文,包含seq序列号,是由客户端随机生成的,并且还将报文中的FIN字段置1,表示需要断开TCP链接,进入FIN_WAIT-1状态。(FIN=1,seq=u,u是由客户端随机生成的)
第二次挥手:服务器会回复客户端发送FIN报文,向客户端发送一个ACK确认报文,其中包含ACK标志位,置1,seq序列号,由服务器端随机生成,,ack确认号在客户端的seq序列号的基础上加1,该报文用于告知客户端我已收到你想要断开的请求,发送完进入CLOSE_WAIT状态,等客户端接收到该报文时,客户端会进入FIN_WAIT-2状态。(ACK=1,ack= u+1,seq=v, v是由服务器端随机生成的)
第三次挥手:服务器端在回复完客户端的TCP断开请求后,并不会立即断开TCP链接,而是会继续传送数据,直到自己的数据全部传输完后,会向客户端发送一个FIN报文,FIN标志位置1,表示要断开链接,ACK标志位置1,表示确认,seq序列号随机生成,ack确认号仍然是之前客户端seq的基础上加1,发送完进入LAST_ACK状态。(FIN=1,ACK=1,ack=u+1,seq=w,w是服务器端随机生成的)
第四次挥手:客户端收到服务器端的TCP断开请求后,会回复一个ACK确认报文,包含ACK标志位,置1,seq序列号,客户端随机生成的,ack确认号的值是在上一次服务器端的seq序列号的基础上加1,发送完之后,会进入TIME_WAIT状态,客户端需要等待2MSL的时间之后,才能进入CLOSED状态,服务器端在收到ACK报文后也会进入CLOSED状态。TCP链接断开。(ACK=1,ack=w+1,seq=u+1)
3》各种状态解释
LISTEN:等待从任何远端TCP 和端口的连接请求。
SYN_SENT:发送完一个连接请求后等待一个匹配的连接请求。
SYN_RECEIVED:发送连接请求并且接收到匹配的连接请求以后等待连接请求确认。
ESTABLISHED:表示一个打开的连接,接收到的数据可以被投递给用户。连接的数据传输阶段的正常状态。
FIN_WAIT_1:等待远端TCP 的连接终止请求,或者等待之前发送的连接终止请求的确认。
FIN_WAIT_2:等待远端TCP 的连接终止请求。
CLOSE_WAIT:等待本地用户的连接终止请求。
CLOSING:等待远端TCP 的连接终止请求确认。
LAST_ACK:等待先前发送给远端TCP 的连接终止请求的确认(包括它字节的连接终止请求的确认)
TIME_WAIT:等待足够的时间过去以确保远端TCP 接收到它的连接终止请求的确认。
TIME_WAIT 两个存在的理由:
1.可靠的实现tcp全双工连接的终止;
2.允许老的重复分节在网络中消逝。
CLOSED:不在连接状态(这是为方便描述假想的状态,实际不存在)
标签:服务器端,ACK,报文,编程,SYN,TCP,四次,握手,客户端 From: https://blog.csdn.net/dghbs/article/details/141982081今天的分享就到这里结束啦,如果有哪里写的不好的地方,请指正。
如果觉得不错并且对你有帮助的话点个关注支持一下吧!