(啥也不说了,好好学习)
最近在学习Linux的时候,发现TCP的三次握手四次挥手这里,面试问的特别频繁,觉得有必要留下我复习的痕迹,等将来自己想看的时候能找着地方
一、TCP协议特点
传输控制协议:面向连接,可靠传输,面向节流
二、三次握手的过程
所谓三次握手,是指建立一个TCP连接的时候,需要客户端和服务器总共发送3个包。
三次握手的目的是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号并交换TCP窗口大小信息。在socket编程中,客户端执行connect()时候,将触发三次握手!
- 第一次握手
客户端发送一个TCP的SYN标志位置1的包,表明客户打算连接的服务器的端口,以及初始序列号X,保存在报头的序列号(Sequence Number)字段里
2.第二次握手
服务器发回确认包ACK应答,即SYN标志位和ACK标志位均为1,同时,将确认序号设置为客户的ISN加一,即X+1
3.第三次握手
客户端再次确认发送确认包ACK,SYN标志位为0,ACK标志位为1,并且把服务器发来的ACK的序号字段+1,放在确定字段中发送给对方
好像这样是不是比较晦涩难懂,那我这样举个栗子吧(因为笔者在不懂得时候,突然想到这个例子感觉就懂了)
在马路的这边,你看到一个美女,你很想向她打招呼,于是给美女一个挥手,向她打招呼,这就可以理解为第一次的握手,发送了一个信息。而美女看到了你的招手信息,向你挤出一个微笑,顺便也向你招手了。这算是第二次握手。那么你感觉很开心,但是又不确定人家是否真的在向你打招呼,万一是你身后的人打招呼呢,你岂不是自作多情?于是再次向她微笑,并且招手一次,这样就确定了确实人家在向你打招呼,这个就是第三次握手。
- 需要注意的是在三次握手过程中,服务器发送SYN-ACK之后,收到客户端的AXK之前的TCP连接成为办理按揭状态,此时服务器处于Syn-RECV状态,当收到ACK后,服务器转入ESTABLISH状态。
三、四次挥手过程
当客户端或者服务端的任何一段发关闭连接动作,都会引起挥手动作
·因为TCP连接是全双工的,因此每个方向都必须单独进行关闭,这个原则是当一方完成它的数据发送人物之后就能发送一个FIN来种植这个方向上的数据流动。但时在收到FIN包不是立即就停止数据流动,可能在收到FIN包后数据还在继续流动,只是不再继续发送数据了
(1)客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送
(2)服务器B收到这个FIN,她发挥一个ACK确认信息,确认序号为收到的序号+1。
(3)服务器B关闭与客户端A的连接,发送一个FIN包给客户端A
(4)客户端A发挥ACK确认信息,并将确认序号设置为收到序号加1
四、为什么建立连接协议是三次握手,而关闭连接却是四次呢?
这个问题也是面试经常问到的问题
因为服务端的LISTEN状态下的SOKET当收到SYN报文的连接请求后,**它可以把ACK和SYN放在一个报文里面起应答作用,SYN起同步作用,放在一个报文里面发送。**到那时关闭连接的时候,当收到对方的FIN请求后,他仅表示对方已经没有数据可以穿送给你了,但是未必你这次的数据都已经发送完了,所以你不能立即就关闭连接,否则就会造成数据丢失,也可你再发送一些数据给对方,再次发送FIN包给对方,表示你同意关闭连接,所以他会将ACK确认信息报文和FIN报文分开发送。
五、TCP 的可靠传输
如何保证TCP的可靠传输:
1、确认应答机制–发送的每一条数据要求对方进行确认回复
2、超时重传机制–等待确认回复超时,则重发数据
3、协议字段中的序号和确认序号
数据的确认回复还有一个作用:确认序号一定是保证在这个序号之前的数据都已经收到了第一条数据,没有收到,就算收到了第二条,也不会对第二条数据进行回复,因为每一条回复都要保证在这之前的数据都已经收到了
4、协议字段中的校验和–若数据不一致,则对其数据要求重传
5、面向连接