TCP通信----三次握手与四次挥手状态转换

一、TCP与TCP报文格式:

首先让我们或了解或巩固一下TCP协议的基本概念。

1、TCP协议:

TCP即传输控制协议(Transmission Control Protocol),是面向连接的运输层协议,也就是说,应用程序要使用TCP协议,首先需要建立TCP连接(三次握手建立),数据传输完毕之后再释放连接(四次挥手释放)。并且TCP连接具有点对点式连接、流量控制、拥塞控制、差错检测、可靠传输等优点。虽然TCP面向字节流(无边界,不保证发送方与接收方数据块大小对应),但是,TCP传送的数据单元却是报文段,而一个数据报的报文分为首部和数据两部分。如下图:
这里写图片描述

2、TCP报文段首部格式与参数含义:

TCP首部,虽然它最少占有20个字节,但是TCP的全部功能都在其首部的各个字段之中实现。所我们有必要对其首部进行细致的了解,其首部格式如下:

这里写图片描述

各字段的意义:
(1)、源端口(2字节):在需要对方回信时使用,不需要可全为0;
(2)、目的端口(2字节):在终点数据交付时必须要用到;
(3)、序号(4字节):TCP传送的每一个字节(面向字节流)都按顺序编号(编号范围为[0~2^32-1]),报文段的第一个字节的编号即为该报文段的序号值。由于编号范围在4G以内,而发送的数据往往不止4G,所以编号是可以重复利用的;
(4)、确认号(4字节):期望收到对方的下一个报文段的序号(即下一个报文段第一个字节的编号),比如已收到了字节编号为200~500的报文段(该报文段序号即为200),那么在给对方回复时发送的报文段确认号就是501。并且,确认号之前的所有字节都已经完全收到;
(5)、数据偏移(4位):报文段数据起始位距报文段首部起始位的4倍字节数。即报文段首部长度(最大长度为2^4 * 4 = 60字节,所以选项与填充最大占40字节且是4字节的倍数);
(6)、保留(6位):保留为今后使用,目前设为0;
(7)、紧急URG(1位):当URG=1时,表明紧急指针字段有效,告知系统有紧急数据,当优先传送。为0则无效(即使有紧急数据,而该位发生了错误(原本为1,因传输信道的噪声干扰等原因而错读为0)也不优先传输);
(8)、确认ACK(1位):当ACK为1时,确认字段才有效,否则无效。当三次握手建立连接后,所有传输报文段的ACK都必须设置为1;
(9)、推送PSH(1位):一般情况下,数据发送与接收都会设置缓冲区,当接收的多个报文段填满缓冲区之后,才向上交付清空缓冲区。PSH=1则表示不等待缓冲区填满便立即交付;
(10)、复位RST(1位):用来处理TCP连接中发生的严重差错(如主机崩溃),当RST=1表明发生严重差错,必须断开连接,重新建立。所以说断开TCP连接并非只有四次挥手这一种途径;
(11)、同步SYN(1位):在连接建立时用来同步序列号,SYN=1,ACK=0表示请求建立连接,SYN=1,ACK=1表示同意建立连接;
(12)、终止FIN(1位):用来释放连接,FIN=1表示数据传输完毕,要求断开连接;
(13)、窗口(2字节):接收方用来告诉发送方发送的最大数据量,因滑动窗口接收数据时速度不固定而时刻改变着,实现流量控制;
(14)、检验和(2字节):用来检验数据段是否发生数据错误,实现差错控制;
(15)、紧急指针(2字节):指出本报文段紧急数据的字节数;
(16)、选项(最小为0字节,最大为4字节):MSS(Maxumum Segment Size)选项,用来设置最大报文段长度,MSS应尽可能大,以提高网络利用率,但是又不能过大,否则会发生IP层的分片,对数据出错造成隐患。时间戳选项,用来计算RTT(round-trip time)往返时间(受网络拥塞程度变化而变化),也用来处理序号超过2^32的情况(当网络速度很快时,几十秒内序号就需要重复利用);
(17)、填充(最大3字节,最小0字节):用来将选项不足4字节的倍数补齐为4的倍数。

二、三次握手与四次挥手:

我们已经说了TCP是面向连接的运输层协议,应用程序要使用TCP协议,需要建立TCP连接,数据传输完毕之后再释放连接。而建立连接需要三步:“三次握手”,释放连接需要四部“四次挥手”。首先让我们来看看三次握手的过程:

1、三次握手:

建立过程:如下图所示:

这里写图片描述

(1)、客户端(Client)主动打开,向服务器(Server)发起连接请求(同步SYN=1,确认ACK=0),发送的序号为x(初始序号不携带数据,但也需要消耗占用一个序号);
(2)、服务器接收到请求连接的报文段之后,向客户端回复,回复信息为接收请求,建立连接(同步SYN=1,确认ACK=1),并且向服务器发送了序号为y(服务器端的初始序号)的报文段,首部中包含了希望下次收到的序号x+1,因为请求时不携带数据所以为x+1;
(3)、客户端收到服务器的同意连接的请求之后,向服务器发送报文段,确认ACK=1,确认收到同意连接的回复,客户端的序号seq=x+1(服务器同意连接时候的确认号),并且确认号ack=y+1表示客户端希望下次收到的序号。

三次握手完成之后,就进入服务器监听队列的已完成连接队列之中。

2、数据通信:

当服务器从已完成连接队列中接收(accept)队头连接之后,该连接就和服务器开始通信,通信就是客户端与服务器分别发送报文段接收报文段,read、write处于阻塞与返回状态转换的过程。

这里写图片描述

3、四次挥手:

断开连接过程如下所示:

这里写图片描述

当数据通信完成时,客户端和服务器都可以主动断开连接,现在由客户端主动释放。
(1)、客户端将释放连接的报文段首部FIN=1,seq=u(请求断开之前接收到的ack=u),发出之后客户端处于终止等待1状态(FIN_WAIT_1);
(2)、服务器收到客户端断开连接请求(收到连接释放报文段)之后,发出确认收到的报文段,继续传送数据,TCP服务器进程通知高层的应用进程,然后进入关闭等待状态(CLOSE_WAIT)。客户端收到服务器的服务器的确认报文段之后,就进入终止等待2状态(FIN_WAIT_2),等待服务器高层应用进程得到TCP服务器进程终止连接的报告;
(3)、当服务器没有数据发送时,应用进程就通知TCP释放连接,服务器就再次发送一个结束连接的报文段(FIN=1),表示服务器已没有数据要发送(如果还有数据要发送,就不使FIN=1,则客户端要继续接收),然后服务器进入最后确认状态(LAST_ACK);
(4)、客户端收到服务器断开连接的报文段之后,就向服务器发出最后确认报文段,该报文段seq=u+1未结束序号,与三次握手时请求连接一样,只消耗一个序号但不携带数据,并且ack=w+1之后进入TIME_WAIT状态。服务器收到该报文段之后就关闭,如果2MSL(MSL≥TTL)时间之内服务器没有回复,客户端也就关闭;如果在TIME_WAIT的2MSL内,再次收到服务器端的FIN=1的断开连接报文段,说明服务器端没有收到ACK确认信息,需要重发ACK确认信息。

我们分过程来说建立链接、通信与断开链接只是为了方便学习,而事实上,他们是一个整体,不可分割(以一次数据交互为例,如下所示):

这里写图片描述

三、TCP状态转换:

1、TCP通信,从请求建立连接到建立连接,再到断开连接,这些个各自的状态时怎样的呢?让我们来看看下面这张图(TCP状态转换图):

这里写图片描述

关于TCP的连接状态,总共有11个,在四次挥手中我们就已经接触到了一些。下面是这十一种状态的简述:

CLOSED:连接未建立,处于关闭状态
LISTEN:服务器端被动打开,处于监听状态
SYN_SEND:客户端之前的状态是CLOSED,在发送请求连接的SYN之后,就处于该状态(SYN发送状态);
SYN_RECV: 服务器接收到SYN请求包,向客户端发送确认报文之后,服务器处于SYN接收状态;
ESTABLISHED:建立连接之后,服务器与客户端的数据传送状态;
FIN_WAIT_1:完成等待状态1,客户端在等待服务器对其发送的关闭连接的应答;
FIN_WAIT_2:完成等待状态2,客户端在等待服务发送完成数据发送,关闭连接的报文;
CLOSE_WAIT:TCP进程服务器向上级应用进程上报关闭连接信息,处于关闭等待状态;
LAST_ACK:被动关闭的一方收到FIN报文后,等待对方的ACK报文。在等待过程中,TCP状态为 LAST_ACK,如果收到了ACK报文,则转为 CLOSED。
CLOSING:这种状态比较特殊,属于一种比较罕见的例外状态。正常情况下,当客户端发送FIN报文后,应该先收到服务器端的ACK报文,再收FIN报文(或同时收到)。但是CLOSING状态表示客户端发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了服务器端的FIN报文。什么情况下会出现此种情况呢?如果双方几乎在同时关闭一个SOCKET的话,那么就出现了双方同时发送FIN报文的情况,也就会出现CLOSING状态,表示双方都正在关闭SOCKET连接。
TIME_WAIT:这个状态,存在于客户端FIN_WAIT_1与CLOSED之间,其主要目的是,等待2MSL,防止服务器未接收到ACK确认,服务器超时重传,客户端却已经关闭,而使服务器一直处于LAST_ACK状态无法关闭;TIME_WAIT的等待还可以使老的重复的分节在网络中消失。

其中SYN_SENT、FIN_WAIT_1 、FIN_WAIT_2 、CLOSING 、TIME_WAIT 为客户端独有;
LISTEN 、SYN_RCVD 、CLOSE_WAIT 、LAST_ACK 为服务器端独有;
CLOSED 、ESTABLISHED 则是服务器与客户端都有的状态。

2、基本状态测试:
(1)、未运行时的TCP状态:
这里写图片描述

(2)、当运行服务器程序与客户端程序以后的TCP状态,客户端和服务器均为ESTABLISHED:
这里写图片描述

(3)、当结束通信进程后,客户端仍处于TIME_WAIT状态:
这里写图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值