TCP三次握手(建立连接)/四次挥手(关闭连接)

  相对于SOCKET开发者,TCP创建过程和链接折除过程是由TCP/IP协议栈自动创建的.因此开发者并不需要控制这个过程.但是对于理解TCP底层运作机制,相当有帮助. 而且对于有网络协议工程师之类笔试,几乎是必考的内容.因此在这里详细解释一下这两个过程。

TCP数据包格式

  顺序号( 32 位):用来标识从 TCP 源端向 TCP 目的端发送的数据字节流,它表示在这个报文段中的第一个数据字节的顺序号。如果将字节流看作在两个应用程序间的单向流动,则TCP用顺序号对每个字节进行计数。序号是32bit的无符号数,序号到达2^32-1 后又从 0 开始。当建立一个新的连接时, SYN 标志变 1 ,顺序号字段包含由这个主机选择的该连接的初始顺序号 ISN ( Initial Sequence Number )。

  确认号( 32 位):包含发送确认的一端所期望收到的下一个顺序号。因此,确认序号应当是上次已成功收到数据字节顺序号加 1 。只有ACK标志为1时确认序号字段才有效。TCP 为应用层提供全双工服务,这意味数据能在两个方向上独立地进行传输。因此,连接的每一端必须保持每个方向上的传输数据顺序号。

  TCP 报头长度(4 位):给出报头中 32bit 字的数目,它实际上指明数据从哪里开始。需要这个值是因为任选字段的长度是可变的。这个字段占 4bit ,因此TCP最多有 60 字节的首部。然而,没有任选字段,正常的长度是20字节。

  保留位(6 位):保留给将来使用,目前必须置为 0 。

  控制位( control flags , 6 位):在 TCP 报头中有 6 个标志比特,它们中的多个可同时被设置为 1 。依次为:  

  • ACK :为 1 表示确认号有效,为 0 表示报文中不包含确认信息,忽略确认号字段。
  • PSH :为 1 表示是带有 PUSH 标志的数据,指示接收方应该尽快将这个报文段交给应用层而不用等待缓冲区装满。
  • RST :用于复位由于主机崩溃或其他原因而出现错误的连接。它还可以用于拒绝非法的报文段和拒绝连接请求。一般情况下,如果收到一个RST为1的报文,那么一定发生了某些问题。
  • SYN :同步序号,为1表示连接请求,用于建立连接和使顺序号同步。
  • FIN :用于释放连接,为1表示发送方已经没有数据发送了,即关闭本方数据流。

  窗口大小(16 位):数据字节数,表示从确认号开始,本报文的源方可以接收的字节数,即源方接收窗口大小。窗口大小是一个16bit字段,因而窗口大小最大为65535字节。

  校验和(16 位):此校验和是对整个的 TCP 报文段,包括 TCP 头部和 TCP 数据,以 16 位字进行计算所得。这是一个强制性的字段,一定是由发送端计算和存储,并由接收端进行验证。

  紧急指针(16 位):只有当 URG 标志置 1 时紧急指针才有效。紧急指针是一个正的偏移量,和顺序号字段中的值相加表示紧急数据最后一个字节的序号。 TCP 的紧急方式是发送端向另一端发送紧急数据的一种方式。

  选项:最常见的可选字段是最长报文大小,又称为 MSS(Maximum Segment Size) 。每个连接方通常都在通信的第一个报文段(为建立连接而设置 SYN 标志的那个段)中指明这个选项,它指明本端所能接收的最大长度的报文段。选项长度不一定是 32 位字的整数倍,所以要加填充位,使得报头长度成为整字数。

  数据:TCP 报文段中的数据部分是可选的。在一个连接建立和一个连接终止时,双方交换的报文段仅有 TCP 首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。在处理超时的许多情况中,也会发送不带任何数据的报文段。

TCP三次握手

  所谓三次握手(Three-way Handshake),是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。三次握手的目的是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号并交换TCP窗口大小信息.在socket编程中,客户端执行connect()时。将触发三次握手。

第一次握手:

  客户端发送一个TCP的SYN标志位置1的包指明客户打算连接的服务器的端口,以及初始序号X,保存在包头的序列号(Sequence Number)字段里。

第二次握手:

  服务器发回确认包(ACK)应答。即SYN标志位和ACK标志位均为1同时,将确认序号(Acknowledgement Number)设置为客户的I S N加1以.即X+1。

第三次握手.

  客户端再次发送确认包(ACK) SYN标志位为0,ACK标志位为1.并且把服务器发来ACK的序号字段+1,放在确定字段中发送给对方.并且在数据段放写ISN的+1

SYN攻击

  在三次握手过程中,服务器发送SYN-ACK之后,收到客户端的ACK之前的TCP连接称为半连接(half-open connect).此时服务器处于Syn_RECV状态.当收到ACK后,服务器转入ESTABLISHED状态.Syn攻击就是攻击客户端在短时间内伪造大量不存在的IP地址,向服务器不断地发送syn包,服务器回复确认包,并等待客户的确认,由于源地址是不存在的,服务器需要不断的重发直至超时,这些伪造的SYN包将长时间占用未连接队列,正常的SYN请求被丢弃,目标系统运行缓慢,严重者引起网络堵塞甚至系统瘫痪。

  Syn攻击是一个典型的DDOS攻击。检测SYN攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击.在Linux下可以如下命令检测是否被Syn攻击netstat -n -p TCP | grep SYN_RECV

  一般较新的TCP/IP协议栈都对这一过程进行修正来防范Syn攻击,修改tcp协议实现。主要方法有SynAttackProtect保护机制、SYN cookies技术、增加最大半连接和缩短超时时间等.但是不能完全防范syn攻击。

TCP 四次挥手

  TCP的连接的拆除需要发送四个包,因此称为四次挥手(four-way handshake)。客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作。

  参见wireshark抓包,实测的抓包结果并没有严格按挥手时序。我估计是时间间隔太短造成。

1、建立连接协议(三次握手)

  (1)客户端发送一个带SYN标志的TCP报文到服务器。这是三次握手过程中的报文1。

  (2)服务器端回应客户端的,这是三次握手中的第2个报文,这个报文同时带ACK标志和SYN标志。因此它表示对刚才客户端SYN报文的回应;同时又标志SYN给客户端,询问客户端是否准备好进行数据通讯。

  (3)客户必须再次回应服务段一个ACK报文,这是报文段3。

2、连接终止协议(四次挥手)

 
 由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

 (1)TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送(报文段4)。

 (2)服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1(报文段5)。和SYN一样,一个FIN将占用一个序号。

 (3)服务器关闭客户端的连接,发送一个FIN给客户端(报文段6)。

 (4)客户段发回ACK报文确认,并将确认序号设置为收到序号加1(报文段7)。

  CLOSED: 这个没什么好说的了,表示初始状态。

  LISTEN: 这个也是非常容易理解的一个状态,表示服务器端的某个SOCKET处于监听状态,可以接受连接了。

  SYN_RCVD:
这个状态表示接受到了SYN报文,在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂,基本
上用netstat你是很难看到这种状态的,除非你特意写了一个客户端测试程序,故意将三次TCP握手过程中最后一个ACK报文不予发送。因此这种状态
时,当收到客户端的ACK报文后,它会进入到ESTABLISHED状态。

  SYN_SENT:
这个状态与SYN_RCVD遥想呼应,当客户端SOCKET执行CONNECT连接时,它首先发送SYN报文,因此也随即它会进入到了SYN_SENT状
态,并等待服务端的发送三次握手中的第2个报文。SYN_SENT状态表示客户端已发送SYN报文。

  ESTABLISHED:这个容易理解了,表示连接已经建立了。

  FIN_WAIT_1:
这个状态要好好解释一下,其实FIN_WAIT_1和FIN_WAIT_2状态的真正含义都是表示等待对方的FIN报文。而这两种状态的区别
是:FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即
进入到FIN_WAIT_1状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2状态,当然在实际的正常情况下,无论对方何种情况下,都应该马
上回应ACK报文,所以FIN_WAIT_1状态一般是比较难见到的,而FIN_WAIT_2状态还有时常常可以用netstat看到。

  FIN_WAIT_2:上面已经详细解释了这种状态,实际上FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你,稍后再关闭连接。

TIME_WAIT:
表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。如果FIN_WAIT_1状态下,收到了对方同时带
FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。

  CLOSING:
这种状态比较特殊,实际情况中应该是很少见,属于一种比较罕见的例外状态。正常情况下,当你发送FIN报文后,按理来说是应该先收到(或同时收到)对方的ACK报文,再收到对方的FIN报文。但是CLOSING状态表示你发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。什
么情况下会出现此种情况呢?其实细想一下,也不难得出结论:那就是如果双方几乎在同时close一个SOCKET的话,那么就出现了双方同时发送FIN报
文的情况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET连接。

  CLOSE_WAIT:
这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方close一个SOCKET后发送FIN报文给自己,你系统毫无疑问地会回应一个ACK报文给对
方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是察看你是否还有数据发送给对方,如果没有的话,那么你也就可以
close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。

  LAST_ACK: 这个状态还是比较容易好理解的,它是被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,也即可以进入到CLOSED可用状态了。

1、 为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?

  这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步
作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,
所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里
的ACK报文和FIN报文多数情况下都是分开发送的。

2、 为什么TIME_WAIT状态还需要等2MSL后才能返回到CLOSED状态?

  这是因为:虽然双方都同意关闭连接了,而且握手的4个报文也都协调和发送完毕,按理可以直接回到CLOSED状态(就好比从SYN_SEND状
态到ESTABLISH状态那样);但是因为我们必须要假想网络是不可靠的,你无法保证你最后发送的ACK报文会一定被对方收到,因此对方处于
LAST_ACK状态下的SOCKET可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT状态的作用就是用来重发可能丢失的
ACK报文。

时间: 2024-08-24 21:33:54

TCP三次握手(建立连接)/四次挥手(关闭连接)的相关文章

TCP三次握手建立链接与四次挥手断开链接

防伪码:从基础开始,一步一个脚印 先简单介绍一下TCP协议. TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层协议.很复杂,但属于不论程序员还是运维人员都必会的基本功. 面向对象的--连接双方在通信前需要预先建立一条连接,这犹如实际生活中的打电话,电话必须拨通了以后才能交流. 可靠的--TCP协议中有诸多的规则来保障通信链路的可靠性,含应用数据分隔.重传机制.对首部和数据校验.对收到的数据进行排序,然后交给应用层.接收

TCP 三次握手建立连接,四次挥手断开连接,图解详细分析,有个疑点求帮忙解答????

继文章  http://blog.csdn.net/simonchi/article/details/41722511   之后,我觉得有必要来详细的说一下TCP的三次握手和四次挥手的过程,帮助大家理解这个过程. 首先来看一下tcpdump抓取的网络数据包,如何抓包分析参考 上面给出的链接 图中红色框选的是三次握手建立连接 第一次:客户端发送SYN报文,并设置seq=0, 第二次:服务端收到SYN报文,知道对方要求建立连接,发送SYN和ACK报文,并设置seq=0,ack=0(第一次的seq)+

TCP中三次握手建立和四次握手释放以及相关问题

本文基于个人所学和网上博文所整理,若有不妥处,欢迎留言指出 TCP连接过程中标志位的意义: 字符缩写 描述 SYN 同步序号,表示此报文是一个连接请求或连接接受报文 ACK 确认位,对接收到的报文的确认 FIN 终止位,表示发送方完成数据发送,用来释放一个连接 RST 复位连接,表示TCP连接中出现严重错误 PSH 推送位,尽可能快递将数据送往接受进程 一.三次握手建立 1.三次握手建立连接详解 TCP建立连接要进行"三次握手",即交换三个分组.大致流程如下: (1)客户端向服务器发送

1.tcp协议 三次握手建链接 四次挥手断开链接 tcp协议的状态 syn洪水攻击与半连接池 互联网协议详解 3. socket介绍 4. 基于socket来编写C/S架构的软件

网络=底层的物理连接介质+互联网协议(就是计算机界的英语) OSI七层 应用层(应用层\表示层\会话层):http,ftp 传输层:tcp/udp 网络层:ip 数据链路层:ethernet 物理层:发送电信号 1. 互联网协议,可看作是一个安装在计算机上的包 2. 交换机:有mac地址学习功能 3. ARP(地址解析协议),可将IP地址转成mac地址,mac地址转成IP地址 4. IP+端口可锁定一架计算机上的某个应用程序 5. IP 和子网掩码->局域网地址(子网地址) 6.  TCD又称好

tcp ip三次握手链接和四次挥手断开

一 三次握手目的是为了建立连接... 1 核心的就是client端和service端,进行数据"报文" 交换 2 报文,目的是互相通知,确认链接 或 过程描述:::::: 1 首先Client端发送连接请求报文, 2 Server段接受连接后回复ACK报文,并为这次连接分配资源. 3 Client端接收到ACK报文后也向Server段发生ACK报文,并分配资源, 这样TCP连接就建立了. 二 数据socket传输 1 不断的往某ip 的某端口,写入数据 2 ip服务器上不断的监听该端口

TCP的三次握手(建立连接)和四次挥手(关闭连接)

http://www.cnblogs.com/Jessy/p/3535612.html http://blog.csdn.net/whuslei/article/details/6667471

TCP三次握手连接和TCP四次挥手及大量TIME_WAIT解决方法:

1.TCP建立连接,三次握手 建立的TCP连接可靠的连接,必须经过三次握手建立连接才能正式通信彼此传输数数据. 客户端请求服务端建立连接 第一次握手:客户给服务发送一个请求报文SYN, 客户端的状态置SYN_SENT状态 第二次握手:服务端在收到客户端发过来的SYN请求报文后,开始给客户端发送ACK报文和SYN报文,状态置为SYN_RECE 第三次握手:客户端口收到服务端口过来的SYN报文和ACK报文后,状态由原来的SYN_SENT状态变为ESTABLISHED:并且给服务发送一个ACK报文告知

学习TCP/IP - TCP三次握手连接和四次握手断开连接

TCP连接 一.为什么需要TCP 链路层将位流封装成数据帧,同时屏蔽了底层物理层的复杂性; 网络层定义了IP地址,划分了网段,使得源计算机可以快速找到目标计算机,但它无法保证数据准确到达. 所以在传输层定义了TCP协议,它是面向连接的可靠传输协议, 二.TCP如何建立连接 2.1) TCP三次握手建立连接 TCP三次握手创建连接 a. 由于TCP是面向连接的,所以有服务端和客户端之分.服务端先在对应的端口监听(LISTENING), 等待客户端发送的tcp连接请求. b. A机器向B机器发起TC

tcp 三次握手 四次挥手

TCP协议中的三次握手和四次挥手 建立TCP需要三次握手才能建立,而断开连接则需要四次挥手. 三次握手,建立连接 首先Client发送连接请求报文,Server端接收连接后回复ACK报文,并为这次连接分配资源.Client接收到ACK报文后也向Server端发送ACK报文,并分配资源,这样TCP连接就建立. 四次挥手断开连接 可以是Client端也可以是Server端 假设Client端发起中断连接请求,也就是发送FIN报文.Server端接收到FIN报文后,意思是说"我Client端没有数据要

TCP三次握手 和四次挥手

1 .TCP三次握手(重点) 1.1         TCP报文字段详细说明 1.     [源端口] ---字段说明(占用16bit,即2个字节),表示网络访问来源处的端口号,即指定了发送端的端口. 2.     [目的端口]---字段说明(占用16bit,即2个字节):表示网络访问目的处的端口号,即指定了接受段的端口号. 说明:由上面可以看出,源端口和目标端口都是占用了16bit/2字节,因此也可以通过计算得知源目标端口范围是2的16次方=65536. 3.     [序列号]---字段说明