传输控制协议(TCP)是一种面向连接的协议,网络程序使用这个协议的时候,网络可以保证客户端和服务端的连接是可靠的,安全的。

如果 A机向 B机发送“hello”,在物理网线上传输的数据不仅仅是“hello”这5个字符,其实除了hello(被称为有效载荷)之外,还必须有用于TCP/IP协议进行处理所需要的其他很多内容。这其中与socket 编程相关的最主要有4 个东西:A机 IP地址(源IP)、B的 IP地址(目标IP)、A机端口号(源端口)、B机端口号(目标端口)。目标IP用来使数据包能到达指定的目标机,源IP使得目标机能获知源机的IP地址,从而能回送数据包。目标端口用于表示目标机上应当接收和处理数据包内容的程序是谁(目标机上不同的网络应用程序占用不同的端口号,例如:http服务器占用端口80,ftp服务器占21,POP3服务器占110,SMTP服务器占25,TELNET服务器占23)。源端口用于标识源机上发送数据的应用程序是谁,这使得目标机能够将回送数据送给该应用程序,而不是别的应用程序。

源机会在将数据包发送到网线上之前,使用上述4个内容对有效载荷进行封包操作,目标机会在收到数据包之后,进行解包操作,从而得到有效载荷。封包的过程简要描述如下:在有效载荷之前加上TCP包头(最重要的就是目标端口和源端口),然后再在前面加上IP包头(最重要的就是目标IP和源IP)。解包过程就是封包过程的逆操作。

TCP数据被封装在一个IP数据报中。

如第一个图所示:每个TCP数据段都包含源端口和目标端口的端口号(在TCP头部),用于寻找发端和收端应用进程。这两个值加上IP头部中的源IP地址和目标IP地址唯一确定一个TCP连接。有时,一个IP地址和一个端口号也称为一个插口(socket),插口对(包含源IP地址,源端口号、目标机IP地址和目标端口号的四元组)可唯一确定互联网络中每个TCP连接的双方。

第二个图:序列号用来标识从TCP发端向TCP收端发送的数据字节流,它表示在这个报文段中的第一个数据字节。确认号指定的是下一个期待的字节,而不是已经正确接收到的最后一个字节。

TCP连接建立过程——三次握手

第一次握手:客户端发送位码为 SYN = 1(SYN 标志位置位),随机产生初始序列号 Seq = J 的数据包到服务器。服务器由 SYN = 1(置位)知道,客户端要求建立联机。
第二次握手:服务器收到请求后要确认联机信息,向客户端发送确认号Ack = (客户端的Seq +1,J+1),SYN = 1,ACK = 1(SYN,ACK 标志位置位),随机产生的序列号 Seq = K 的数据包。
第三次握手:客户端收到后检查 Ack 是否正确,即第一次发送的 Seq +1(J+1),以及位码ACK是否为1。若正确,客户端会再发送 Ack = (服务器端的Seq+1,K+1),ACK = 1,以及序号Seq为服务器确认号J 的确认包。服务器收到后确认之前发送的 Seq(K+1) 值与 ACK= 1 (ACK置位)则连接建立成功。
经过了这三步之后,客户端与服务器端就成功建立起一个 TCP连接。这三个步骤统称为三次握手。

(上面Seq表示序列号,Ack表示确认号,SYN和ACK以及FIN等都是标志位。ACK 被设置为 1表示确认号字段是有效的,如果 ACK为 0,则该段不包含确认信息。SYN 被用于建立连接过程,在连接请求中,SYN = 1 和 ACK = 0 表示该段没有捎带确认字段。连接应答会捎带一个确认,所以应答时会有 SYN= 1 和 ACK= 1。另外发送ACK无需任何代价,所以我们会看到一旦一个连接建立起来,ACK标志总是被置为1)

从上图可以看出,当客户端调用connect 时,触发了连接请求,向服务器发送了 SYN J包,这时 connect 进入阻塞状态;服务器监听到连接请求,即收到 SYN J包,调用 accept函数接收请求向客户端发送 SYN K,ACK J+1,这时 accept 进入阻塞状态,客户端收到服务器的 SYN K,ACK J+1之后,这时 connect 返回,并对 SYN K 进行确认,服务器收到 ACK K+1时,accept返回,至此三次握手完毕,连接建立。可以得知:客户端的 connect在三次握手的第二次返回,而服务器端的 accept在三次握手的第三次返回。

为什么是三次握手:

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

下面用抓包工具 Wireshark 实际分析下三次握手的过程,这里是登陆一个网址,然后Wireshark 过滤http 找到与浏览器打开该网站相关的数据包。

连接的是 HTTP 服务器,可以看到其端口号正是80,客户端的端口号则是随机的。红色框框标记的则是三次握手过程,下面具体来看

第一次握手数据包:

客户端发送一个TCP,标志位SYN置位,序列号为4225926656(默认是相对序列号,可以在Wireshark中protocol preference 设置Absolute Number,显示真正的序列号)。表示客户端请求建立连接。

第二次握手数据包:

看源端口和目的端口。服务器发回确认包,标志位SYN和ACK置位,将确认序号Ack设置为客户的ISN(初始序号)+1,为4225926657,同时发送序列号为3022381253。

第三次握手数据包

客户端再次发送确认包,其中ACK置位,确认序号Ack设置为服务器发过来的序号Seq+1,为3022381254,并发送序号=服务器发过来的确认号。

对于建连接的三次握手,主要是初始化Seq的值。通信的双方要互相通知对方自己的初始化的Seq(ISN),这个号(上面的K,J)作为以后的数据通信的序号,以保证应用层接收到的数据不会因为网络上的传输问题而乱序,TCP会用这个序号来拼接数据。

TCP连接终止过程——四次挥手

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

这里我们假定客户端主动关闭(实际上谁先执行主动关闭没本质区别,通话结束了,谁先挂断没啥区别)

  • 1、客户端发送一个FIN Seq = M(FIN置位,序号为M)包,用来关闭客户端到服务器端的数据传送。
  • 2、服务器端收到这个FIN,它发回一个ACK,确认序号Ack 为收到的序号M+1。
  • 3、服务器端关闭与客户端的连接,发送一个FIN Seq = N 给客户端。
  • 4、客户端发回ACK 报文确认,确认序号Ack 为收到的序号N+1。

  

对于四次挥手,其实仔细看是两次,因为TCP是全双工的,必须双方都关闭才可以,单方会有两次,共有四次。终止的时候,有一方是被动的,所以看上去就成了四次挥手。

前面有说道,一旦连接建立起来,ACK标志位总是被置为1。所以我们在下图可以看到TCP建立连接之后,ACK总是被置为1的。

关闭连接过程主要看FIN标志位是否置位,ACK在连接建立成功之后都是置为1的。

上面Wireshark抓包是服务器端先执行主动关闭。

第一次挥手:服务器端发起主动关闭,FIN置位,Seq = 3022381791;

第二次挥手:客户端收到FIN后,发回ACK,Ack = Seq + 1 = 3022381792;至此服务器端的连接关闭了,接下来还需要关闭客户端的。

第三次挥手:客户端发送FIN,Seq = 4225929031;

第四次挥手:服务器端收到FIN后,发回ACK,Ack = Seq + 1 = 4225929032.这样客户端的连接也关闭了。至此全双工的TCP连接关闭。

另外通过下面的截图可以发现:数据传输中的 Sequence Number 的增加是和传输字节数相关的。

转自:https://blog.csdn.net/wenqian1991/article/details/39667131

【TCP/IP】TCP的三次握手和四次挥手的更多相关文章

  1. TCP/IP协议、三次握手、四次挥手

    1.什么是TCP/IP协议 TCP/IP 是一类协议系统,它是用于网络通信的一套协议集合. 传统上来说 TCP/IP 被认为是一个四层协议 1) 网络接口层: 主要是指物理层次的一些接口,比如电缆等. ...

  2. TCP的基本概念三次握手,四次挥手

    TCP的特性 TCP提供一种面向连接的.可靠的字节流服务 在一个TCP连接中,仅有两方进行彼此通信.广播和多播不能用于TCP TCP使用校验和,确认和重传机制来保证可靠传输 TCP使用累积确认 TCP ...

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

    建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. [更新于2017.01.04 ]该部分内容配图有误,请大家见谅,正确的配图如下,错误配图也不删 ...

  4. TCP常见的定时器三次握手与四次挥手

    1.TCP常见的定时器 在TCP协议中有的时候需要定期或者按照某个算法对某个事件进行触发,那么这个时候,TCP协议是使用定时器进行实现的.在TCP中,会有七种定时器: 建立连接定时器(connecti ...

  5. 真的懂了:TCP协议中的三次握手和四次挥手(关闭连接时, 当收到对方的FIN报文时, 仅仅表示对方不在发送数据了, 但是还能接收数据, 己方也未必全部数据都发送对方了。相当于一开始还没接上话不要紧,后来接上话以后得让人把话讲完)

    一.TCP报文格式 下面是TCP报文格式图: (1) 序号, Seq(Sequence number), 占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记. (2) 确 ...

  6. TCP/IP具体解释--三次握手和四次握手 Dos攻击

    TCP连接的状态图 TCP建立连接的三次握手过程,以及关闭连接的四次握手过程 贴一个telnet建立连接,断开连接的使用wireshark捕获的packet截图. 1.建立连接协议(三次握手) (1) ...

  7. 可靠的TCP连接为何是三次握手和四次挥手

    首先,咱们先来熟悉下经典的tcp/ip模型. tcp/ip 模型为了方便使用,将osi七层模型划分成了四层,分别为网络接口层,网络层,传输层,应用层. 他们作用分别为: 1)网络接口层:主要作用是将i ...

  8. 网络编程简介(OSI七层协议,TCP协议原理,三次握手与四次挥手)

    目录 网络编程 软件开发架构 C/S架构 B/S架构 网络编程的发展史 互联网协议 1.物理连接层 2.数据链路层 3.网络层 4.传输层 5.应用层 三次握手四次挥手 三次握手建链接 数据传输 四次 ...

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

    建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资 ...

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

    建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资 ...

随机推荐

  1. maven eclipse远程部署tomcat

    pom.xml tomcat 配置信息  <properties><project.build.sourceEncoding>utf8</project.build.so ...

  2. SQL IN 运算符

    SQL IN 运算符 IN运算符允许您在WHERE子句中指定多个值. IN运算符是多个OR条件的简写. SQL IN 语法 SELECT column_name(s) FROM table_name ...

  3. UNP学习第六章(二)

    一.描述符就绪条件 对于引起select返回套接字“就绪”的条件我们必须讨论得更明确: (1)满足一下塞个条件中的仍和一个时,一个套接字准备好读. a)该套接字接收缓冲区中的数据字节数不大于等于套接字 ...

  4. 常见sql操作

    1. select '`'||b.mrchno 商户号, b.name 商户名称, b.contact3 注册地址联系人, '`'||b.telno1 邮寄地址联系电话, a.MRCHT_NAME X ...

  5. 在Delphi中使用系统对应文件类型的图标

    在应用程序的编写中,组合框(ComboBox).列表框(ListBox).等常见的部件,通常不仅要用于显示文字,而且还要显示其与文字相关的图标.在一般的Windows应用程序中,这些图标的显示都要随列 ...

  6. Mistakes Collection I

    Symbol =>'s meaning: what it used to be like => what it should be. 1) mistake array subscript: ...

  7. Stream流式编程

    Stream流式编程   Stream流 说到Stream便容易想到I/O Stream,而实际上,谁规定“流”就一定是“IO流”呢?在Java 8中,得益于Lambda所带来的函数式编程,引入了一个 ...

  8. JS-text节点模拟innerHTML属性

    # [在线预览](https://jsfiddle.net/1010543618/mz7ybu8g/2/) text 节点无 innerHTML 这个属性!!! 如果直接修改 text 节点的属性(d ...

  9. SQL server 2012序列号 注册码

    企业核心版: FH666-Y346V-7XFQ3-V69JM-RHW28 商业智能版: HRV7T-DVTM4-V6XG8-P36T4-MRYT6 开发版: YQWTX-G8T4R-QW4XX-BVH ...

  10. 全局配置一个ajax的错误监控

    全局配置一个ajax的错误监控,比如$(document).ajaxError(function(evt, req, settings){    if(req && (req.stat ...