关于 TCP/IP 三次握手/四次握手详解
概念
TCP/IP协议是一系列网络协议的总和,它定义了电子设备如何接入互联网以及数据之间如何相互传输, 在TCP/IP协议中可以将网络分为四层分别为应用层,传输层,网络层,链路层
应用层:负责处理特定的应用程序细节;SSH、Telnet、FTP等 传输层:为两台主机上的应用程序提供端到端的通信;TCP、UDP; 网络层:介于传输层和数据链路层之间,它在数据链路层提供的两 个相邻端点之间的数据帧的传送功能上,进一步管理网络中的数 据通信,将数据设法从源端经过若干个中间节点传送到目的端, 从而向运输层提供最基本的端到端的数据传送服务; 数据链路层:最基本的服务是将源自网络层来的数据可靠地传输到相邻节点的目标机网络层
TCP三次握手与四次握手初步了解
首先先看一张图,这张图说明了两个应用程序在建立一条TCP连接时所做的事
这是建立一次连接与断开的示意图,这张图中一些概念性词语现在做出解释: 主动打开:主动发起一个TCP请求的一端,一般由客户端向服务器发起连接 被动打开:被动接受TCP连接,并做出回应;服务器一般处于监听状态 主动关闭:一般由客户端发起,主动将该连接断开,并发送一条信息给服务器 被动关闭:服务器在收到来自客户端关闭该连接的请求之后,向客户端发送信息允许客户端关闭这条连接
在连接过程中,客户端和服务器会先后进入几个状态: 客户端: - SYN_SENT:客户端发起连接后进入该状态,等待服务器响应 - ESTABLISHED:客户端能够进行数据传递的状态 - FIN_WAIT_1:客户端主动关闭TCP连接,等待服务器回复时的状态 - FIN_WAIT_2:客户端等待服务器发来的关闭连接请求时的状态 - TIME_WAIT:回应服务器关闭连接请求后进入该状态 服务端: - SYN_RCVD:服务器回应客户连接请求,进入该状态 - ESTABLISHED:服务器能够进行数据传递的状态 - CLOSE_WAIT:等待连接关闭,当收到客户端发来的关闭请求后,发送回应,进入该状态, 随后检查自己是否还有数据要发送给对方,如果没有则发送关闭连接请求 - LAST_ACK:等待客户同意关闭的信息
在连接过程中,需要发送一些数据包: SYN段:TCP建立连接时发送该包 ack:确认回应 FIN:TCP断开时发送该包
TCP首部格式
源端口:本机端口号 目的端口:目标主机端口号 序号(seq):用来标识从TCP发端向TCP收端发送的数据字节流,它表示在这个报文段中的第一个 数据字节,序号字段包含由这个主机选择的该连接的初始序号(ISN) 确认序号:包含发送确认的一端所期望收到的下一个序号,只有ACK标志为1时确认序号才有效 数据偏移:给出首部中32bit字的数目 保留:保留为今后使用,但目前应置为0 首部中有6个标志比特,它们中的多个可同时被设置为1: - URG:紧急指针有效 - ACK:确认序号有效 - PSH:接收方应该尽快将这个报文段交给应用层 - RST:重新连接 - SYN:同步序号用来发起一个连接,当SYN=1而ACK=0时,表明这是一个连接请求报文段 - FIN:用来释放一个连接 窗口大小:起始于确认序号字段指明的值,这个值是接收端正期望接收的字节 检验和:覆盖了整个的TCP报文段,一定是由发端计算和存储,并由收端进行验证 紧急指针:紧急指针仅在URG=1时才有意义,它指出本报文段中的紧急数据的字节数
三次握手与四次握手
建立连接
第一次握手: 客户端建立连接(主动打开),将首部字段的序号设为随机值(ISN)x, SYN字段设为1,发送SYN包,客户端进入SYN_SENT状态,等待服务确认回应 第二次握手: 服务器接收到来自客户端的连接请求(SYN包)(被动打开),服务器确认该请求, 向客户端发回一个确认SYN包以及包含服务器初始序号Y (将首部字段的序号设 为Y,确认序号设为x+1,同时将ack字段设为1) 的SYN+ACK包,服务器进入SYN_RCVD状态, 等待客户端回应 第三次握手: 客户端收到服务器的SYN+ACK包,然后向服务器发送确认包ACK(将首部序号字段设为x+1, 确认序号设为y+1,ack字段设为1),此包发送完毕,客户端和服务器进入ESTABLISHED,完 成三次握手 建立连接的三次握手的过程类似: 客户端:你好,我是。。。。 服务器回应:你好,我是。。。 客户端回应:好的,我这儿有些东西要给你
关闭连接(四次握手)
建立一个连接需要三次握手,而终止一个连接要经过4次握手。这由TCP的半关闭造 成的。既然一个TCP连接是全双工(即数据在两个方向上能同时传递),因此每个方向必 须单独地进行关闭。这原则就是当一方完成它的数据发送任务后就能发送一个FIN来终止 这个方连接,当一端收到一个FIN,它必须通知应用层另一端已经终止了那个方向的数据 传送,送FIN通常是应用层进行关闭的结果。 第一次握手: 客户端向服务发出连接释放报文FIN包(主动关闭),并停止发送数据, 客户端进入FIN_WAIT_1状态,等待服务器回应 第二次握手: 服务器收到来自客户端的FIN包,发出确认ACK包,服务器进入CLOSE_WAIT(关闭等待)状态, TCP服务器通知高层的应用进程客户端已经没有数据要发送了 客户端收到服务器的确认请求ACK包后,进入FIN_WAIT_2状态,等待服务器发送连接释放报文 (在这之前还需要接受服务器发送的最后的数据) 第三次握手: 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文FIN包, 服务器进入LAST_ACK(最后确认)状态,等待客户端的确认 第四次握手: 客户端收到服务器的FIN包后,向服务器出ACK确认包,然后进入TIME_WAIT(时间等待)状态 服务器收到客户端的确认后,立即进入CLOSED状态 关闭连接的四次握手的过程类似: 客户端:你好,我的数据已经发送完了,我准备走了 服务器:好的,但是我还有些数据没给你 一段时间后 服务器:你好,我的数据已经全部发完了,我准备走了 客户端:好的 服务器断开连接, 一段时间后,客户端断开连接
TIME_WIAT状态
执行主动关闭的一端将会经历这个状态,该端点停留在这个状态的持续时间时最长分节 声明期的两倍,有时候称为2MSL TCP的实现都必须为MSL选择一个值,MSL是任何IP数据报能够在因特网中存活的最长时间 有时因为路由器的缘故,导致迷途分组陷入路由循环,TCP发生超时重传并到达目的端, 这时迷途分组也被发送到目的端,这个原来的分组称为迷途的重复分组或漫游的重复分组 TIME_WIAT状态是用来重发可能丢失的ACK报文,服务器如果没有收到确认ACK包, 将会不断重复发送FIN包,所以客户端不难立即关闭,需要等待2MSL时间来进行重发ACK包
简单介绍数据在网络中的传递过程
传输层(添加TCP首部)和网络层(添加IP首部)对数据进行封装后,将该数据发往路由器(链路层), 路由器根据目的IP地址查询路由表(IP选路),确认该向那个接口发送该数据。 确认发往的接口后,将对数据进行又一次封装(添加本地MAC地址,以及下一路由器或目的主 机的MAC地址),随后将封装好的数据发往下一路由器(送往物理层) 下一个路由器接收到数据段后,查询目的MAC地址是否属于自己的MAC地址,如果是,对该数 据进行解析,不是则丢弃; 路由器继续查询路由表与数据的目的IP地址比对,选择数据传输的接口,确定下一路由器的MAC 地址,直到数据发送到目的主机址),随后将封装好的数据发往下一路由器(送往物理层) 下一个路由器接收到数据段后,查询目的MAC地址是否属于自己的MAC地址,如果是,对该数 据进行解析,不是则丢弃; 路由器继续查询路由表与数据的目的IP地址比对,选择数据传输的接口,确定下一路由器的 MAC地址,直到数据发送到目的主机