TCP简介

  相对于不可靠、无连接的用户数据报协议(User Datagram Protocol, UDP),传输控制协议(Transmission Control Protocol, TCP)是可靠的、面向连接的协议。除此之外,TCP还提供了以下特性:

  1)TCP含有用于动态估算客户和服务器之间的往返时间(round-trip time, RTT),以便它知道等待一个确认需要多长时间。

  2)TCP通过给其中每个字节关联一个序列号对所发送的数据进行排序(sequencing)。

  3)TCP提供流量控制(flow control)。TCP总是告知对端在任何时刻它一次能够从对端接受多少字节的数据,这称为通知窗口(advertised window)。在任何时刻,该窗口指出接受缓冲区中当前可用的空间量,从而确保发送端发送的数据不会使接收缓冲区溢出。该窗口时刻动态变化:当接收到来自发送端的数据时,窗口大小就减小,但是当接收端应用从缓冲区中读取时,窗口大小就增大。通知窗口大小减小到0是有可能的:当TCP对应某个套接字的接收缓冲区已满,导致它必须等待应用从该缓冲区读取数据时,方能从对端再接收数据。

  4)TCP连接是全双工的(full-duplex)。

TCP头格式

  下图展示了TCP的头格式:

  

                    TCP头格式(图片来源

  需要注意有这么几点:

  • TCP的包是没有IP地址的,那是IP层上的事。但是有源端口和目标端口。
  • 一个TCP连接需要四个元组来表示是同一个连接(src_ip, src_port, dst_ip, dst_port)准确说是五元组,还有一个是协议。但因为这里只是说TCP协议,所以,这里我们只说四元组。
  • 注意上图中的四个非常重要的东西:
    • Sequence Number是包的序号,用来解决网络包乱序(reordering)问题。
    • Acknowledgement Number就是确认号——用于确认收到,用来解决不丢包的问题。需要注意这个跟TCP Flags中的ACK(只有一位)是不一样的。只有TCP Flags中的ACK有效,这个确认号才有效。
    • Window又叫Advertised-Window,也就是著名的滑动窗口(Sliding Window),用于解决流控的
    • TCP Flag ,也就是包的类型,主要是用于操控TCP的状态机的。其中常有的有ACK、SYN、FIN、PUSH、RESET。

  对于TCP Flag中的标志PUSH,它的用途在于发送方用于通知接收方将所接收到的数据全部提交给接收进程。这里的数据包括与PUSH一起传送的数据以及接收方TCP已经为接收进程收到的其他数据。现在许多程序认为PUSH标志已经过时,一个好的TCP实现能够自行实现何时设置这个标志。

  关于其它的东西,可以参看下面的图示

  

   (图片来源

  

TCP连接的建立和终止  

三路握手  

  建立一个TCP连接时会发生下述情形:

  1)服务器必须准备好接受外来的链接。这通常通过调用socket、bind和listen这3个函数来完成,我们称之为被动打开(passive open)。

  2)客户端通过调用connect发起主动打开(active open)。这导致客户端TCP发送一个SYN(synchronization,同步)分节,它告诉服务器,客户端将在(待建立的)连接中发送的数据的初始序列号。通常SYN字节不携带数据,其所在IP数据报只含有一个IP首部、一个TCP首部及可能有的TCP选项。

  3)服务器必须确认(acknowlegement, ACK)客户端的SYN,同时自己也得发送一个SYN分节,它含有服务器将在同一连接中发送的数据的初始序列号。服务器在单个分节中发送SYN和对客户端SYN的ACK(确认)。

  4)客户端必须确认服务器的SYN。

  下图展示了TCP三路握手:

  

  

  上图给出的客户端的初始序列号为X,服务器的初始序列号为Y。ACK中的确认号是发送这个ACK的一端所期待的下一个序列号。因为SYN占据一个字节的序列号空间,所以每一个SYN的ACK中的确认号就是SYN的初始序列号加1。类似地,每一个FIN(finish, 表示结束)的ACK中的确认号为该FIN的序列号加1。

TCP连接终止  

  TCP建立一个连接需要3个分节,终止一个连接则需要4个分节。

  1)某个应用进程首先调用close,我们称该端执行主动关闭(active close)。该端的TCP于是发送一个FIN分节,表示数据发送完毕。

  2)接收到这个FIN的对端执行被动关闭(passive clsose)。这个FIN有TCP确认。它的接收也作为一个文件结束符(end-of-file)传递给接收端应用进程(放在已排队等候该应用进程接收的任何其他数据之后),因为FIN的接收意味着接收端应用进程在相应连接上再无额外数据可接收。

  3)一段时间后,接收到这个文件结束符的应用进程将调用close关闭它的套接字。这导致它的TCP也发送一个FIN。

  4)接收这个最终FIN的原发送端TCP(即执行主动关闭的那一端)确认这个FIN。

  既然每个方向都需要一个FIN和一个ACK,因此通常需要4个分节。我们使用限定词“通常”是因为:某些情形下步骤1的FIN随数据一起发送;另外,步骤2和步骤3发送的分节都出自执行被动关闭的那一端,有可能被合并成一个分节。

  下图展示了TCP连接终止的4个分节:

  

  注:上图中的服务器端对客户端发送的是FIN而不是SYN。之前画错。

  类似SYN,一个FIN也占据1个字节的序列号空间。因此,每个FIN的ACK确认号就是这个FIN的序列号加1。

  在步骤2和步骤3之间,从执行被动关闭一端到执行主动关闭一端流动数据是可能的。这称为半关闭(half-close)。

  当套接字被关闭时,其所在端TCP各自发送了一个FIN。我们在图中指出,这是由应用进程调用close而发生的,不过需要认识到,当一个Unix进程无论自愿地(调用exit或从main函数返回)还是非自愿地(收到一个终止本进程的信号)终止时,所有打开的描述符都被关闭,这也导致仍然打开的任何TCP连接端也发出一个FIN。

  上图展示了客户端执行主动关闭的情形,不过,无论是客户端还是服务器,任何一端都可以执行主动关闭。通常情况是客户端执行主动关闭,但是某些协议(如HTTP/1.0)却由服务器执行主动关闭。

观察分组

  下图展示了一个完整的TCP连接所发生的实际分组交换情况,包括连接建立、数据传送和连接终止3个阶段。

  

  (图片来源

实验

  具体实验工具采用的是Wireshark,实验对象是cnBeta官网。

Wireshark与对应的OSI七层模型

  Wireshark抓到的包与对应的协议层如下图所示:

  

  1)Frame:   物理层的数据帧概况

  2)Ethernet II: 数据链路层以太网帧头部信息

  3)Internet Protocol Version 4: 互联网层IP包头部信息

  4)Transmission Control Protocol:  传输层的数据段头部信息,此处是TCP

  5)Hypertext Transfer Protocol:  应用层的信息,此处是HTTP协议

TCP包的具体内容

  从下图可以看到wireshark捕获到的TCP包中的每个字段。

  

Wireshark使用

  详细使用方法可参考博文Wireshark的使用教程--用实践的方式帮助我们理解TCP/IP中的各个协议是如何工作的

  在这里我们主要是设定:

  1)捕捉过滤器

  

  2)显示过滤器

  在这里我们只想显示端口54753的数据交互:

  

  3)显示Flow Graph

  

  

  最终得到的结果:

  

  由上图可以看出一个比较完整的TCP连接建立、数据传输以及连接终止的过程。

参考资料

  《UNIX网络编程 卷1》

  TCP那些事儿(上)

  Wireshark基本介绍和学习TCP三次握手

  Wireshark教程可参考博文Wireshark抓包图解 TCP三次握手/四次挥手详解

  Wireshark的使用教程--用实践的方式帮助我们理解TCP/IP中的各个协议是如何工作的

传输控制协议(TCP) -- 连接建立及终止过程的更多相关文章

  1. 动手学习TCP:TCP连接建立与终止

    TCP是一个面向连接的协议,任何一方在发送数据之前,都必须先在双方之间建立一条连接.所以,本文就主要看看TCP连接的建立和终止. 在开始介绍TCP连接之前,先来看看TCP数据包的首部,首部里面有很多重 ...

  2. 网络协议抓包分析——TCP传输控制协议(连接建立、释放)

    前言 TCP协议为数据提供可靠的端到端的传输,处理数据的顺序和错误恢复,保证数据能够到达其应到达的地方.TCP协议是面向连接的,在两台主机使用TCP协议进行通信之前,会先建立一个TCP连接(三次握手) ...

  3. TCP连接建立与终止,及状态转换

    TCP连接建立 三路握手 三路握手发生在客户端发起connect请求到服务端accept返回中,在三路握手发生前,服务端必须准备好接受外来连接,这通常通过服务端调用 (socket.bind.list ...

  4. TCP连接建立和终止小结

    TCP连接建立(三次握手) 如图: 请求端发送一个SYN到服务器的相应端口,以及初始序号ISN 服务器发送包含服务器的初始序号的SYN作为应答,同时确认序号设置为客户的ISN+1 客户将确认序号设置为 ...

  5. 关于TCP连接建立与终止那点事

    0. 前言 最近在处理公司遗留项目的时候发现自己对TCP协议一点都不懂,所以补了点关于TCP连接的建立和终止的内容,这里简单写下自己了解的部分,省略了报文序号确认序号这些无关的字段,主要讨论TCP状态 ...

  6. 【转】TCP三次握手过程

    写的非常明白:http://www.cnblogs.com/rootq/articles/1377355.html TCP协议三次握手过程分析 TCP(Transmission Control Pro ...

  7. [TCPIP] 传输控制协议 Note

    TCPIP  TCP 传输控制协议 TCP提供一种面向连接的,可靠的字节流服务. 面向连接意味着两个使用TCP的应用在传输数据之前先建立一个TCP连接,这个过程跟打电话相似.在一个TCP连接中仅有两方 ...

  8. TCP 三次握手过程详解

    TCP(Transmission Control Protocol) 传输控制协议 TCP:面向连接的,可靠的,基于字节流的传输层通信协议 TCP(传输层)位于IP层(网络层)之上,应用层之下,不同的 ...

  9. 《TCP/IP详解卷1:协议》第17、18章 TCP:传输控制协议(1)-读书笔记

    章节回顾: <TCP/IP详解卷1:协议>第1章 概述-读书笔记 <TCP/IP详解卷1:协议>第2章 链路层-读书笔记 <TCP/IP详解卷1:协议>第3章 IP ...

随机推荐

  1. argparse库 学习记录

    初始化 始见参数 name or flags action nargs default type choices required help dest metavar 总结 继上次的optparser ...

  2. ROS机器人程序设计(原书第2版)补充资料 (拾) 第十章 使用MoveIt!

    ROS机器人程序设计(原书第2版)补充资料 (拾) 第十章 使用MoveIt! 书中,大部分出现hydro的地方,直接替换为indigo或jade或kinetic,即可在对应版本中使用. MoveIt ...

  3. SublimeText3解决中文乱码

    1)安装Sublime Package Control.     在Sublime Text 3上用Ctrl+-打开控制台并在里面输入以下代码,Sublime Text 2就会自动安装Package ...

  4. #pragma pack(x) CPU对齐

    编译器会尽量把成员对齐以提高内存的命中率.对齐是可以更改的,使用"#pragma pack(x)" 可以改变编译器的对齐方式. C++固有类型的对界取编译器对齐方式与自身大小中较小 ...

  5. 微信小程序基础之新建的项目文件图解

    昨天发布的文章,感觉对于学习不够直观,所以今天重点在图标上进行了详细的对应介绍,稍后会尝试开发小程序控件的使用.转载请标注出处,谢谢!

  6. Android Multimedia框架总结(十)Stagefright框架之音视频输出过程

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52560012 前言:上篇文中最后 ...

  7. Java的LinkedList详解,看源码之后的总结

    1. LinkedList实现了一个带表头的双向循环链表: 2. LinkedList是线程不同步的: 3. LinkedList中实现了push.pop.peek.empty等方法,因此Linked ...

  8. Dynamics CRM 为Visual Studio 2015安装CRM Developer Toolkit

    从CRM2015的SDK以后Tools的文件夹里就没有了DeveloperToolkit,而DeveloperToolkit还是停留在VS2012版本,这对于我们这种用新版本的童鞋来说比较头疼,我本地 ...

  9. Ext JS 6开发实例(一)

    很久没写文章了,主要原因和大家差不多,都要为生活奔忙,搞了两个小项目.这两个小项目很凑巧,都可以使用Ext JS来开发,这正是练习使用Ext JS 6的好机会,自然不会错过. 很多读者可能会问,为什么 ...

  10. 03 ImageView 图片

    四  ImageView   父类 : view     >概念:展示图片的控件       >属性:      <!--  android:adjustViewBounds=&qu ...