TCP之————三次握手和四次挥手

一. TCP协议

TCP(Transmission Control Protocol)传输控制协议,是TCP/IP协议族中最重要的协议之一,主要工作在运输层,和UDP不同,TCP提供面向流服务面向连接的可靠传输服务,虽然是面向字节流的,但TCP的传输单元却是报文段,一个报文分为首部信息和有效数据信息两部分,其中的首部信息才是在传输过程中起到至关重要的作用;

-------------------------------------------------------------------------------------------

二. TCP报文的首部格式

源端口号:标识着发送端是从上一层应用层的哪一个应用程序端口接收下来的信息,是16位大小;

目的端口号:标识着要上交给目的主机上应用层的哪一个应用进程,为16位;和MAC帧协议一样其中有帧         类型标识表明要上交给上一层的哪一方,IP数据报中有协议类型决定上交的对象是UDP还是         TCP类型;

32位序号:在一个TCP连接中传送的字节流中的每一个字节都按照顺序编号的,一个字节占用一个序号,        因此首部信息中的序号表示本报文中所发送的数据的第一个字节的序号;

32位的确认序号:表示希望收到对方下一个报文的第一个数据字节的序号,也表示在确认序号之前发送           方发送的序号标识的字节已全部收到;

数据偏移:4位,表示报文中首部所占用的长度,也就是从报文开始部分往后偏移多少为有效数据的开       始,也是数据距离报文首部有多远;

保留:为以后保留空余以供使用,目前置为0;

URG(urgent):紧急字段,当被置为1时,表明后面的紧急指针有效;

ACK(acknowlegment):确认字段,当被置为1时,前面的确认序号才有效;

PSH(push):推送字段,当置为1时,用于及时将收到的报文向上交付处理;

RST(reset):复位字段,当置为1时,表中TCP链接出现严重差错,不许释放连接然后再重新建立;

SYN(synchronization):同步字段,当被置为1时,表明这是一个连接请求报文;

FIN(finish):终止字段,当被置为1时,表示要求释放运输连接;

窗口:指的是自身能接收的最大数据量,是发送本报文段的接收窗口,而不是发送窗口;

检验和:进行差错检验,占2个字节;

紧急指针:当URG=1时才有效,它指出报文中的紧急数据的字节数,优先处理紧急数据;

选项:长度可变,最长可达40字节;

填充:当报文低于46个字节时用来填充;

-------------------------------------------------------------------------------------------

三. TCP连接建立过程(三次握手)

TCP连接采用客户服务器方式,主动发起连接请求的一方为客户端进程,接收连接请求的一方为服务器进程;

  1. 首先,客户端和服务器都处于CLOSED(关闭)状态,客户端主动请求连接;
  2. 服务器进程会先创建出一个传输控制块TCB,准备接收客户端的请求,然后服务器进程就会一直处于LISTEN(监听)状态,随时等待客户端发送请求;
  3. 客户端进程也会先创建出一个传输控制块TCB,向服务器端发送连接请求报文,这时报文中的SYN字段置为1,表示请求连接,并且选择一个初始序号seq置入报文首部中,比如seq = n;并且这个时候,客户端会处于SYN_SENT(同步已发送)状态;
  4. 当服务器端接收到客户端发送的请求连接报文的时候,若同意连接就会做出响应,向客户端发送确认报文,报文中SYN同步字段和ACK确认字段都应设置为1,并且选择自己的一个初始序号比如seq = k,同时将确认序号部分设置为ack=n+1,表示客户端下一次发送的数据序号开始处,并且表示n+1之前的数据已全部收到,这时候服务器就处于SYN_RCVD(同步并且收到)状态;
  5. 当客户端收到了服务器端发过来的确认建立连接的响应之后,会再次给服务器端发送确认,表明已收到服务器端同意建立连接的确认报文,这时候客户端发送的报文中,ACK确认字段置为1seq = n+1,表示这次数据字节的开始处,同时对服务器的确认序号为ack=k+1,表示已收到服务器k+1之前的所有数据,这时候客户端就进入了ENSTABLISHED(连接已建立)状态;
  6. 当服务器收到客户端响应过来的确认报文的时候,也进入ENSTABLISHED(连接已建立)状态;

注意:上面的连接过程并不携带数据信息,因为连接还没有建立好,但是像SYN和ACK这样的状态字段     仍然会消耗一个序号,因此,每一次对上一次接收的报文的确认序号中,都应该加上1,表示这     个序号之前所有的序号代表的数据都已接收到;如果携带有相应大小的数据,确认序号中就应该     加上数据的大小和状态字段的1个序号;

上面过程表示为如下图:

这里要提出为什么是三次握手而不是两次四次或者五次握手:

首先,一次握手是肯定不行的,因为连接并不是一方说连接就连接;其次,如果是两次握手的话,在这种情况中每一次服务器端接到客户端发来的连接请求,只要同意连接给客户端发送了确认连接应答就算是连接好了,会出现这样的情况:如果客户端第一次请求连接的报文并没有及时到达服务器端,而是在中途被丢失或者滞留等待了,那么客户端就会第二次发送请求,当第二次成功到达服务器端之后,只要服务器端同意建立连接,那么当客户端收到服务器端发送的确认响应之后连接就建立好了,那么如果数据传输完毕连接释放之后,客户端第一次的请求才到达服务器端,那么服务器端就又会同意建立连接,此时又有一条连接被建立了,但是实际上客户端并没有再次需要建立连接,那么也就不会传输数据,这样的话,一条连接就会被白白浪费了,如果有多种这样的情况,就会浪费很多资源;最后,如果是四次五次握手根本就没有必要,这样就相当于蓝军白军的问题了,总有最后的依次确认应答是不可靠的;

因此,三次握手是最佳的次数,当客户端请求连接,如果服务器端同意连接,就发送确认连接应答,这时候客户端接收到再次回复给服务器端一个确认应答,表明收到了同意建立连接的报文,这样双方就可以建立连接了;

-------------------------------------------------------------------------------------------

四. TCP连接断开过程(四次挥手)

连接释放的过程要比连接建立的过程稍微复杂了一些,仍然需要报文首部中状态字段和双方状态的变化来描述:

  1. 当数据传输结束后,双方都可以释放连接,这时候客户端先向服务器端发起一个释放连接的报文,其中FIN字段设置为1,序号为上一次自己发送数据的最后一个字节的序号加1,(TCP规定,即使FIN报文并不携带数据也会消耗掉一个序号)比如为seq = x,因为要断开连接所以并不会携带有效数据,这时候客户端就会进入FIN_WAIT_1(终止等待1)的状态,等待服务器端的确认;
  2. 服务器端接收到客户端发来的断开连接报文时会做出回应,回应一个确认报文,ACK字段置为1,序号为自身前一个发送报文最后一个字节序号加1,比如seq = y确认序号为ack = x+1,然后服务器端就会进入一个CLOSE_WAIT(关闭等待)的状态,此时客户端到服务器端的连接就断开了,但如果服务器端的数据还没有处理完,仍然可以给客户端发送数据,客户端仍然会接收数据,因为只有一方断开了连接
  3. 当客户端接收到服务器端发送的确认断开连接的回应后,就会进入FIN_WAIT_2(终止等待2)的状态,因为只是一方断开了连接,还要等待服务器端处理完毕数据之后再发送的请求断开连接的报文才能真正断开连接;
  4. 当服务器端将所有数据处理完毕之后,就会向客户端发送一个请求断开连接的报文,报文中FIN字段设置为1,确认序号假如为seq = i,因为在半关闭状态可能服务器端又向客户端发送了一些数据,这时候服务器端就会进入一个LAST_ACK(最后确认)状态,等待客户端的确认;
  5. 当客户端收到了服务器端发来的请求断开连接的报文时,就会回应一个确认报文,报文中ACK字段设置为1序号seq = x+1,确认序号ack = i+1,这时候客户端就会进入到一个TIME_WAIT(时间等待)的状态;
  6. 当服务器端收到了客户端发过来的确认断开连接的回应报文之后,就会断开之前只有一方的连接,这时候服务器端就会进入CLOSED(关闭)的状态,同时撤销相应的传输控制块TCB;
  7. 当客户端超过TIME_WAIT(时间等待)的时间,就会进入CLOSED(关闭)的状态,同时撤销传输控制块TCB;

断开连接的过程可用下图表示:

这里要谈论一下TIME_WAIT(时间等待)状态:

当客户端进入到TIME_WAIT状态后,必须经过时间等待计时器设计的时间2MSL后,客户端才能够进入到CLOSED状态,而时间MSL叫做最长报文段寿命(Maximum Segment Lifetime),RFC793建议设为2分钟,TCP允许不同的而实现可根据具体情况使用更小的MSL值。因此,从客户端进入到TIME_WAIT状态后要经过4分钟的等待才能进入到CLOSED状态,才能开始建立下一次新的连接

那么客户端为什么要等待规定的2MSL时间后才能进入CLOSED状态呢:

是为了保证客户端发送的ACK确认报文能够到达服务器端;当服务器端向客户端发送了请求断开连接的报文而没有收到响应,如果客户端并不等待时间就直接进入CLOSED状态释放了连接,那么服务器端就无法接收到客户端的确认报文,也就一直无法进入CLOSED状态了;因此,当客户端发送给服务器端的确认ACK报文丢失了时,服务器端等待超时就会重新发送一次请求断开连接的FIN报文,这样客户端在等待的2MSL时间里就会重新接收到服务器端发送的FIN请求断开报文,也就会重新发送一次ACK确认断开连接报文,这样一来,就能够保证服务器端收到了确认断开连接报文正确进入CLOSED状态了。

《完》

时间: 2024-08-28 10:57:55

TCP之————三次握手和四次挥手的相关文章

TCP的三次握手与四次挥手

最近在看一些Tcp网络编程方面的内容,不免涉及客户端和服务器交互的内容,其中最经典的应该是TCP的三次握手和四次挥手了. 背景描述 通过上一篇中网络模型中的IP层的介绍,我们知道网络层,可以实现两个主机之间的通信.但是这并不具体,因为,真正进行通信的实体是在主机中的进程,是一个主机中的一个进程与另外一个主机中的一个进程在交换数据.IP协议虽然能把数据报文送到目的主机,但是并没有交付给主机的具体应用进程.而端到端的通信才应该是应用进程之间的通信. UDP,在传送数据前不需要先建立连接,远地的主机在

TCP/IP三次握手与四次挥手的正确姿势

A 理解TCP/IP三次握手与四次挥手的正确姿势https://www.cnblogs.com/lms0755/p/9053119.html B 四次挥手过程理解 https://blog.csdn.net/qq_38950316/article/details/81087809 C TCP三次握手四次挥手详解http://www.cnblogs.com/zmlctt/p/3690998.html 原文地址:https://www.cnblogs.com/kelelipeng/p/1021678

C/S架构,osi五层协议,TCP的三次握手与四次挥手

1.C/S B/S架构 C:client 客户端 B:Browser 浏览器 S:server 服务端 C/S 客户端与服务器之间的架构:QQ,微信,游戏,App的都属于C/S架构 优点:安全性高,个性化设置,功能全面,响应速度快 缺点:开发成本高,维护成本高,面向的客户固定 B/S 浏览器与服务器之间的架构:属于C/S架构,最近几年比较流行的特殊的C/S架构 优点:开发维护成本低,面向用户广泛 缺点:安全性相对低,响应速度相对慢,个性化的设置单一 2.互联网通信的原理 1.物理连接介质将两台电

TCP/IP三次握手与四次挥手(转)

一.TCP报文格式        TCP/IP协议的详细信息参看<TCP/IP协议详解>三卷本.下面是TCP报文格式图: 图1 TCP报文格式 上图中有几个字段需要重点介绍下:        (1)序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记.        (2)确认序号:Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1.        (3)标志位:共6个,即URG.ACK.PSH.RST.SYN.F

(转)TCP/IP三次握手与四次挥手

一.TCP报文格式 TCP/IP协议的详细信息参看<TCP/IP协议详解>三卷本.下面是TCP报文格式图: 图1 TCP报文格式 上图中有几个字段需要重点介绍下: (1)序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记. (2)确认序号:Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1. (3)标志位:共6个,即URG.ACK.PSH.RST.SYN.FIN等,具体含义如下: (A)URG:紧急指针(urge

TCP 的三次握手 与 四次挥手详解(转载)

建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资源.Client端接收到ACK报文后也向Server段发生ACK报文,并分配资源,这样TCP连接就建立了. 那如何断开连接呢?简单的过程如下: [注意]中断连接端可以是Client端,也可以是Server端. 假设Client端发起中断连接请求,也就是发送FIN报文.Server端接到FIN报文后,

理解TCP/IP三次握手与四次挥手的正确姿势

背景 和女朋友异地恋一年多,为了保持感情我提议每天晚上视频聊天一次. 从好上开始,到现在,一年多也算坚持下来了. 问题 有时候聊天的过程中,我的网络或者她的网络可能会不好,视频就会卡住,听不到对方的声音,过一会儿之后才会恢复. 中间双方可能就要不断的确认网络是否恢复,但是有时候会: 她:"你可以听到了吗?" 我:"可以了,你呢?". 她:"喂喂,你可以听到了吗?" 我:"可以了,我可以听到了,你呢?" 她:"你可以听

揭秘——TCP的三次握手和四次挥手

1.前言 本文以博主在某次前端面试中被问到"什么是TCP协议中的三次握手和四次挥手?"为契机,经过整理教材.百度百科以及他人博客,再结合博主自身的理解,尽可能的以通俗易懂的语言来解释TCP协议中的三次握手和四次挥手的具体过程. 2.TCP连接和断开 客户端与服务端在建立TCP连接时需要经过三次握手才能建立,而断开连接则需要四次挥手.整个过程全览如下图所示: 我知道,直接看此图,相信大多数伙伴是懵逼的,下面我们就分别从建立连接和断开连接进行详细介绍. 3."三次握手"

TCP的三次握手与四次挥手(个人总结)

序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生:给字节编上序号后,就给每一个报文段指派一个序号:序列号seq就是这个报文段中的第一个字节的数据编号. 确认号ack:占4个字节,期待收到对方下一个报文段的第一个数据字节的序号:序列号表示报文段携带数据的第一个字节的编号:而确认号指的是期望接收到下一个字节的编号:因此当前报文段最后一个字节的编号+1即为确认号. 确认ACK:占1位,仅当ACK=1时,确认号字段才有效.AC

TCP的三次握手与四次挥手理解及面试题(很全面)

序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生:给字节编上序号后,就给每一个报文段指派一个序号:序列号seq就是这个报文段中的第一个字节的数据编号. 确认号ack:占4个字节,期待收到对方下一个报文段的第一个数据字节的序号:序列号表示报文段携带数据的第一个字节的编号:而确认号指的是期望接收到下一个字节的编号:因此当前报文段最后一个字节的编号+1即为确认号. 确认ACK:占1位,仅当ACK=1时,确认号字段才有效.AC