参考博客:

http://blog.csdn.net/whuslei/article/details/6667471

http://www.2cto.com/net/201310/251896.html

一、TCP报文简介

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:紧急指针(urgent pointer)有效。
  (B)ACK:确认序号有效。
  (C)PSH:接收方应该尽快将这个报文交给应用层。
  (D)RST:重置连接。
  (E)SYN:发起一个新连接。
  (F)FIN:释放一个连接。

需要注意的是:
  (A)不要将确认序号Ack与标志位中的ACK搞混了。
  (B)确认方Ack=发起方Req+1,两端配对。 (大写ACK表示报文中的一个标志位)

二、TCP建立过程(三次握手)

所谓三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。

(1)第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
(2)第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
(3)第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

注意:三次握手的序列号和确认号,如果用(序列号,确认号)表示一次握手,则三次握手的过程序列号和确认号如下:

1)  第1步:客户端向服务器发送一个同步数据包请求建立连接,该数据包中,初始序列号(ISN)是客户端随机产生的一个值,确认号是0;
2)  第2步:服务器收到这个同步请求数据包后,会对客户端进行一个同步确认。这个数据包中,序列号(ISN)是服务器随机产生的一个值,确认号是客户端的初始序列号+1;
3)  第3步:客户端收到这个同步确认数据包后,再对服务器进行一个确认。该数据包中,序列号是上一个同步请求数据包中的确认号值,确认号是服务器的初始序列号+1。

1、(X,0)

2、(Y,X+1)

3、(X+1,Y+1)

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

【注意】中断连接端可以是Client端,也可以是Server端。

假设Client端发起中断连接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,"告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息"。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。当Server端确定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭连接了"。Client端收到FIN报文后,"就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“,Server端收到ACK后,"就知道可以断开连接了"。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。Ok,TCP连接就这样关闭了!

由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,上图描述的即是如此。
 (1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
  (2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
 (3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
  (4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

四次挥手的序列号和确认号

(u,0)

(v,u+1)

(w,u+1)

(u+1,w+1)

上面是一方主动关闭,另一方被动关闭的情况,实际中还会出现同时发起主动关闭的情况,具体流程如下图:

【问题1】为什么连接的时候是三次握手,关闭的时候却是四次握手?
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

【问题2】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。

为什么是2MSL,主要是为了考虑到如果最后一个ACK丢失,服务端会重新发FIN,客户端等待2MSL,才能接收到服务端重新发送的FIN报文。

【问题3】RST的作用

RST表示复位,用来异常的关闭连接,在TCP的设计中它是不可或缺的。就像上面说的一样,发送RST包关闭连接时,不必等缓冲区的包都发出去(不像上面的FIN包),直接就丢弃缓存区的包发送RST包。而接收端收到RST包后,也不必发送ACK包来确认。

TCP处理程序会在自己认为的异常时刻发送RST包。例如,A向B发起连接,但B之上并未监听相应的端口,这时B操作系统上的TCP处理程序会发RST包。

又比如,AB正常建立连接了,正在通讯时,A向B发送了FIN包要求关连接,B发送ACK后,网断了,A通过若干原因放弃了这个连接(例如进程重启)。网通了后,B又开始发数据包,A收到后表示压力很大,不知道这野连接哪来的,就发了个RST包强制把连接关了,B收到后会出现connect reset by peer错误。

【问题4】当URG=1时

紧急比特URG——当URG=1时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。

转载于:https://www.cnblogs.com/LCCRNblog/p/5228648.html

TCP建立连接和断开连接图解相关推荐

  1. TCP建立连接和断开连接流程

    [转]http://blog.csdn.net/gamekit/article/details/53888674 一.基本描述 TCP协议为提供面向连接的服务,需要先建立连接,然后才可以通信,通信结束 ...

  2. 图解TCP四次握手断开连接

    建立连接非常重要,它是数据正确传输的前提:断开连接同样重要,它让计算机释放不再使用的资源.如果连接不能正常断开,不仅会造成数据传输错误,还会导致套接字不能关闭,持续占用资源,如果并发量高,服务器压力堪 ...

  3. mysql的tcp链接过程_tcp建立连接和断开连接过程

    在之前对TCP协议的介绍中,说到了其中它的一个特点是面向连接.今天就来介绍一下它的连接和断开过程. 面向连接指的是采用TCP协议通讯,在数据传输之前必须先建立连接,通讯完成之后,必须关闭连接. 建立连 ...

  4. TCP建立连接与断开连接的过程

    在CS模式的TCP连接建立过程中,客户端与服务器端流程如下: 客户端流程:发送请求->接收服务器端确认->发送对服务器端确认的确认. 服务器端流程:接收客户端的连接建立请求->发送确 ...

  5. TCP建立连接和断开连接的过程

    一. TCP建立连接- 三次握手 1. 客户端向服务器端发送syn包,进入syn_send状态,等待服务器的回复 2. 服务器端收到客户端发送的syn包,发送syn_ack包给客户端,进入syn_re ...

  6. 每天一道面试题一谈谈TCP建立连接和断开连接的过程

    简介 传输控制协议(Transmission Control Protocol) 建立连接(三次握手) 第一次握手是客户端发送消息给服务端,服务端接收到客户端发送的消息. 第二次握手是服务端回复客户端 ...

  7. TCP四次挥手断开连接

    四次挥手的流程 1.主动关闭方发送FIN连接释放报文段 客户端调用 close 方法,告诉服务器自己要主动关闭连接,会发送一个 FIN 报文给服务端,客户端进入FIN-WAIT-1状态. 2.被动关闭 ...

  8. [Qt] TCP客户端与服务器断开连接自动重联机制

    TCP服务器断开连接自动重联机制 客户端加入定时器实现断线重联(客户端服务端代码见上一篇博客) 编译环境:Qt 5.9.5 ui界面如图: 代码如下 tcpclient.h #ifndef TCPCL ...

  9. php websocket 连接已断开连接,客户端websocket 无法连接上PHP socket问题

    我客户端是用c++写得websocket 客户端我请求的地址是ws://127.0.0.1:100322 (我请求ws://echo.websocket.org这个是可以的说明客户端代码是没问题的 问 ...

最新文章

  1. GNN教程:第六篇Spectral算法细节详解!
  2. 启明云端WT32-CAM操作视频,让你快速上手ESP32camera应用
  3. vscode自动修复eslint规范的插件及配置
  4. php版本kms,通过 AWS KMS API 和 AWS SDK for PHP 版本 3 使用密钥 - 适用于 PHP 的 AWS 开发工具包...
  5. cheatsheet 常用图标大全
  6. as3通用三方库大全
  7. 【POJ3335】Rotating Scoreboard(多边形的内核-----半平面交+特殊情况)
  8. 【原创】flv文件的三种下载方法
  9. kali PHP网站渗透,小白日记35:kali渗透测试之Web渗透
  10. goodix触摸屏(IIC)外设驱动
  11. canvas橡皮擦功能
  12. keepalived结合nginx主备高可用实现
  13. PhotoShop PS液化抖动 使用液化时,鼠标、数位板光标抖动
  14. 1.13 golang中的Map
  15. Kotlin高仿微信-第26篇-朋友圈-选择图片、小视频对话框
  16. Web全栈~09.JavaScript入门
  17. 实现网站对IP地址的限制访问
  18. 数据交易相关法规比较研究
  19. mysql plsql 语法_PL/SQL基本语法
  20. 什么是background-attachment

热门文章

  1. EMC防护设计-浪涌
  2. 轩辕传奇服务器合并信息,轩辕传奇3月15日部分服务器合服公告
  3. 李开复给中国学生的第一封信:从诚信谈起
  4. 达梦数据库DM8版本DSC集群启停注意事项
  5. 关于可调节头颈胸固定支具介绍
  6. 74ls161中rco是什么_芯片74ls160十进制计数器引脚图及功能_真值表_设计进制计数器方法...
  7. 【C++】用一棵红黑树同时封装出map和set
  8. 张钹:人工智能技术已进入第三代
  9. matlab工具将matlab脚本转C语言实现
  10. matlab C 混编 --- 在MATLAB中使用c语言函数