TCP详解(2):三次握手与四次挥手

  TCP(Transmission Control Protocol,传输控制协议)是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接,就好像你给别人打电话,必须等线路接通了、对方拿起话筒建立了连接才能相互通话。

  一个TCP连接必须要经过三次“对话”才能建立起来,其中的过程非常复杂,我们这里只做简单、形象的介绍,你只要做到能够理解这个过程即可。我们来看看这三次对话的简单过程:主机A向主机B发出连接请求数据包:“我想给你发数据,可以吗?”,这是第一次对话;主机B向主机A发送同意连接和要求同步(同步就是两台主机一个在发送,一个在接收,协调工作)的数据包:“可以,你什么时候发?”,这是第二次对话;主机A再发出一个数据包确认主机B的要求同步:“我现在就发,你接着吧!”,这是第三次对话。三次“对话”的目的是使数据包的发送和接收同步,经过三次“对话”之后,主机A才向主机B正式发送数据。

   

1. 建立连接三次握手

  TCP用三次握手(three-way handshake)过程创建一个连接。在连接创建过程中,很多参数要被初始化,例如序号被初始化以保证按序传输和连接的强壮性。

  一对终端同时初始化一个它们之间的连接是可能的。但通常是由一端打开一个套接字(socket)然后监听来自另一方的连接,这就是通常所指的被动打开(passive open)。服务器端被被动打开以后,用户端就能开始创建主动打开(active open)。

  1)客户端通过向服务器端发送一个SYN来创建一个主动打开,作为三路握手的一部分。客户端把这段连接的序号设定为随机数 A。

  2)服务器端应当为一个合法的SYN回送一个SYN/ACK。ACK 的确认码应为 A+1,SYN/ACK 包本身又有一个随机序号 B。

  3)最后,客户端再发送一个ACK。当服务端受到这个ACK的时候,就完成了三路握手,并进入了连接创建状态。此时包序号被设定为收到的确认号 A+1,而响应则为 B+1。

   

  Win:窗口字段明确指出现在允许对方发送的数据量(经常变化)

  Len:TCP数据段长度

  MSS(Maximum Segment Size):最大报文段长度,即每个TCP报文段中的数据字段的最大长度.这里需要在握手的时候进行协商,双方都给出MSS,最后以最小MSS确定为最终的MSS。IP数据报最大传输单位为MTU(Maximum Transmission Unit,Effect of short board),对于大多数使用以太网的局域网来说,MTU=1500。MSS往往基于MTU计算出来,通常MSS=MTU-sizeof(IP Header)-sizeof(TCP Header)=1500-20-20=1460,如果服务器MSS=1460,而客户端的MSS=1440,最终为1440。

  在TCP的三次握手中,不仅是建立了连接,还让双方交换了有效信息,过程如下:

  1) 嗨~ , 这是我sequence number和MSS

  2) 我收到啦~, 这是我sequence number和MSS

  3) 我也收到~

为什么需要三次握手?

  简单地说,就是要保证在一段有效时间内,双方收到对方的有效信息。

  一个简单例子,A发给B,B回复A,如果A不再回复B,B如何知道A收到了自己的信息?

  谢希仁版《计算机网络》中的例子是这样的,“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”。

  不管哪个例子,都是为了满足”在不可靠信道上可靠地传输信息”这一需求。请注意这里的本质需求,信道不可靠,数据传输要可靠。还是那句话,就是要保证在一段有效时间内,双方收到对方的有效信息。

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攻击。

Socket状态对应

  Socket API 和 TCP 协议中各个状态是如何对应的呢?我们可以通过下图来看:

  

2. 断开连接四次挥手

  由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。比如服务器收到一个FIN只意味着客户端不再发送数据,但它还可以向客户端发送数据,当服务器不再发数据了,他也要向客户端发送FIN。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

  

    

四次挥手过程如下:

  1)客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送。

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

  3)服务器B关闭与客户端A的连接,发送一个FIN给客户端A。

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

状态变化

  

  FIN_WAIT_1: 当SOCKET在ESTABLISHED状态,主动关闭连接时,向对方发送FIN报文,此时该SOCKET进入到FIN_WAIT_1状态。当对方回应ACK报文后,则进入到FIN_WAIT_2状态。(主动方)

  FIN_WAIT_2:处于FIN_WAIT_2状态下的SOCKET为半连接状态,等待对方发起断开要求,(注意对方可以在断开时捎带信息)稍后再关闭连接。(主动方)

  TIME_WAIT: 收到了对方FIN报文,并发送出了ACK报文,等待2MSL后即可回到CLOSED状态了。

  注意:在FIN_WAIT_1状态下,如果收到了对方同时带FIN和ACK标志的报文(复用一个报文)时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。(主动方)

  CLOSING(比较少见): 如果双方几乎同时试图断开一个SOCKET的话,那么就出现了双方同时发送FIN报文的情况,即会出现CLOSING状态,表示双方都试图关闭SOCKET连接。

  CLOSE_WAIT: 等待关闭连接,当对方发送FIN报文,回应ACK报文给对方后,则进入到CLOSE_WAIT状态。如果此时没有数据发送给对方,就可以关闭这个SOCKET,发送FIN报文给对方,即关闭连接。(被动方)

  LAST_ACK: 被动关闭方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,进入到CLOSED状态。(被动方)

  CLOSED: 连接中断。

Socket状态变化

  

    

参考:

https://zh.wikipedia.org/wiki/%E4%BC%A0%E8%BE%93%E6%8E%A7%E5%88%B6%E5%8D%8F%E8%AE%AE

http://www.kuqin.com/shuoit/20141018/342719.html

http://hackerxu.com/2014/11/16/TCP.html

https://www.centos.bz/2012/08/tcp-establish-close/

http://blog.csdn.net/xifeijian/article/details/12777187

http://www.cnblogs.com/skynet/archive/2010/12/12/1903949.html

http://blog.163.com/[email protected]/blog/static/13222965520118139252103/

https://commons.wikimedia.org/wiki/File:Tcp_close.svg

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-09 10:09:22

TCP详解(2):三次握手与四次挥手的相关文章

TCP协议中的三次握手和四次挥手(图解)【转】

建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. [更新于2017.01.04 ]该部分内容配图有误,请大家见谅,正确的配图如下,错误配图也不删了,大家可以比较下,对比理解效果更好.这么久才来更新,抱歉!! 错误配图如下: 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资源.Client端接收到ACK报文后也向Server段发生ACK报文,并分配资源,这样TCP连接就建立了. 那如何断开连接呢?

TCP/IP之TCP协议首部、三次握手、四次挥手、FSM

TCP包头 <--------------------------------32 位------------------------------> 0 8 16 24 32 |----------------|----------------|----------------|----------------| ----- | Source port | Destination port | | |-----------------------------------------------

tcp协议报文和三次握手与四次挥手

tcp协议: tcp是面向连接.可靠的进程到进程之间的协议.tcp提供全双工服务:即:数据可在同一时间双向传输. tcp报文段首部格式: 各字段含义: 源端口号:16位字段,为发送端进程对应的端口号 目标端口:16位字段,为接收端进程对应的端口号,接收方接收到数据包之后根据这个字段确定将数据发送给对应程序来处理 序号:32位字段,当tcp从进程中接收到数据之后,就会把他存储在发送缓存中.并对每一个字节进行编号,形成的序列号.特点如下: 会生成一个随机数作为第一个字节的编号,成为序列号(ISN),

【转】 TCP协议中的三次握手和四次挥手(图解)

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

TCP协议中的三次握手和四次挥手(图解)

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

TCP协议中的三次握手和四次挥手

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

python网络编程-TCP协议中的三次握手和四次挥手(图解)

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

TCP协议中的三次握手和四次挥手(图解)【转载】

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

【编程基础】TCP协议中的三次握手和四次挥手(图解)

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

TCP协议中的三次握手和四次挥手(图解) 转载

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