摘要:

    本文简单介绍了TCP面向连接理论知识,详细讲述了TCP报文各个字段含义,并从Wireshark俘获分组中选取TCP连接建立相关报文段进行分析。

一、概述

    TCP是面向连接的可靠传输协议,两个进程互发数据之前需要建立连接,这里的连接只不过是端系统中分配的一些缓存和状态变量,中间的分组交换机不维护任何连接状态信息。连接建立整个过程如下(即三次握手协议):

首先,客户机发送一个特殊的TCP报文段;

其次,服务器用另一个特殊的TCP报文段来响应;

最后,客户机再用第三个特殊报文段作为响应。

图1 三次握手协议示意图[1]

二、TCP报文格式

2.1 概述

为了提供可靠的数据传输,TCP报文首部字段有较多的字段,TCP报文格式如下图:

图2 TCP报文格式

源和目标端口

    用于多路复用/多路分解来自或送至上层应用的数据,可以这样理解,端口用来标识同一台计算机的不同进程。

序列号和确认号

    这两个字段是TCP可靠传输服务的关键部分,序列号是该报文段首字节的字节流编号(TCP把数据看成是有序的字节流,TCP隐式地对数据流的每个字节进行编号)。这样理解可能更直观,当报文被分解成多个报文段时,序列号就是报文段首字节在整个报文的偏移量。确定号指定下一个期待的字节。TCP是全双工的,假设从主机A接收到主机B的数据,则主机A填充进报文段的确认号是主机A期望从主机B收到的下一个字节序号。还没理清这两者的关系?见下图(三次握手):

图3 正常情况下TCP连接建立过程

首部长度(4位)

    因为选项是不定长的,这就需要标识整个首部字段的长度(单位是32位字),即5+选项个数。4位,单位是32位字,所以首部最长是15*4=60字节,即选项最长是40字节(10个选项)。

标志

URG

    指示报文段里存在着被发送方的上层实体标记为"紧急"数据,当URG=1时,其后的紧急指针指示紧急数据在当前数据段中的位置(相对于当前序列号的字节偏移量),TCP接收方必须通知上层实体。

ACK

    当ACK=0时,表示该数据段不包含确认信息,当ACK=1时,表示该报文段包括一个对已被成功接收报文段的确认。

PSH

    当PSH=1时,接收方在收到数据后立即将数据交给上层,而不是直到整个缓冲区满。

RST

    用于重置一个已经混乱的连接(如主崩溃),也可用于拒绝一个无效的数据段或者拒绝一个连接请求。一般而言,如果你得到的数据段被设置了RST位,那说明你这一端有问题了。

SYN

    用于建立连接过程,在连接请求中,SYN=1和ACK=0表示该数据段没有使用捎带的确认域,而连接应答捎带一个确认,即SYN=1和ACK=1

    注:捎带是指对客户机到服务器数据的确认被装载在一个承载服务器到客户机的数据报文段中。

FIN

    用于释放一个连接,表示发送方已经没有数据要传输了。此时,接收方可能继续接收数据,好在SYN和FIN数据段都有序列号,从而保证了这两种数据段以正确顺序被处理。

窗口大小

    用于流控制(确保连接的任何一方都不会过快地发送过量的分组而淹没另一方),窗口大小指定了从被确认的字节算起可以发送多少个字节。

校验和

    提供了额外可靠性,在计算检验和的时候,TCP的Checksum域设为0,如果数据域的字节数为奇数,则数据域填补一个额外的0字节。校验和算法:将所有的16位字按1的补码形式累加起来,取累加结果的补码。因此,当接收方执行同样计算时(包括Checksum域),结果应该是0。

紧急指针

    参考标志字段的URG位。

选项

    选项部分是为了适合复杂网络环境和更好地服务于应用层设计的。TCP选项最长是40字节。详情见2.2。

数据

    无任何数据的TCP段也是合法的,通常用于确认和控制信息。

2.2 选项字段[2]

    TCP选项部分很好出现在已经建立连接的会话中,只要出现在TCP连接建立阶段,即三次握手。TCP选项部分实际运用有以下几种:

(1)最大报文传输段(MMS, Maximum Segment Size)

    用于发送发与接收方协商最大报文段长度(仅仅是净荷数据,不包括TCP首部字段)。TCP在三次握手中,每一方都会通告期望收到的MSS(MSS只出现在SYN数据包中),如果一方不接受另一方的MSS值,则使用默认的536字节净荷数据,即主机能够接受20+536字节的TCP报文段。

(2)窗口扩大选项(Window scaling)

    TCP报文的窗口大小字段占16位,即最大值是65535,但随着时延和带宽比较大的通信产生(如卫星通信),需要更大的窗口满足性能和吞吐率,这就是窗口扩大选项存在的意义。例子见参考资料[2]。

    Windows scaling占3个字节,最后一个字节是移位值(Shift count),即首部的窗口位数16向左移动,如移位值为14,则新的窗口最大值增大到65535*(2^14)。

    窗口扩大选项是在TCP建立之初进行协商,如果已实现了窗口扩大,当不再需要扩大窗口时,发送移位值=0就可以恢复到原窗口大小,即65535。

(3)选择确认选项(SACK, Selective Acknowledgements)

    考虑这样情况,主机A发送报文段12345,主机B收到135且报文无差错,SACK用来确保只重传缺少的报文段,而不是重传所有报文段。

    SACK选项需要2个功能字节,一个用来指明使用SACK选项(SACK Permission),另一指明这个选项占多少字节。

    那怎么形容丢失的报文段2,说明2的左右边界分别是1、3。TCP的数据报文是有字块边界的,而这种边界是由序列号表示的。

    最多能指明多少个字节块的边界信息呢?答案是4个。这是因为选项字段最大是40字节,去除2个功能字节,序列号是32位即4字节,并且需要左右边界,所以(40-2)/8 = 4。

(4)时间戳选项(timestamps)

    时间戳选项用来计算往返时间RTT,发送方在发送报文段时把当前时钟的时间值放入时间戳字段,接收方将该时间戳字段的值复制到确认报文中,当接收方收到确认报文,对比确认报文的时间戳(等于发送方发送报文段的时间戳)和现在的时钟,即可算出RTT。

    时间戳选项还可用于防止回绕序号PAWS。序列号只有32位,每2^32个序列号就会回绕(想想环形队列),采用时间戳选项很容易区分相同序列号的报文段。

(5)NOP(NO-Operation)

    TCP的头部必须是4字节的倍数,而大多数选项不是4字节倍数,不足的用NOP填充。除此之外,NOP也用于分割不同的选项数据,如窗口扩大选项和SACK之间使用NOP隔离(下面的实例将看到这一点)。

三、实例解析

3.1 概述

    还是以访问百度首页为例,首先用DNS协议将URL解析成IP地址,接着在客户机和服务器间建立TCP连接,用Wireshark俘获的分组如下图:

图4 Wireshark俘获建立TCP连接分组

    你一看会觉得有些奇怪,理论上应该是3个分组的,怎么有6个分组?先不急,先把这6个报文收发示意图作出来(结合时间和报文含义),如下:

图5 TCP连接建立实例

    从图可知,连接建立伊始,客户机发了两个报文段,这也许是为了更快建立连接(假设有个请求报文段丢失,也不至于要等一段时间,重发报文)。接下来,以19、21、22(上图红色线条所示)分析TCP连接建立过程。

3.1 第一次握手19

Wireshark俘获TCP连接第一次握手的报文段如下:

图6 TCP连接第一次握手实例

这里主要挑几个字段分析:

    标志字段,SYN=1、ACK=0表示该数据段没有使用捎带的确认域。

    最大报文段长度(MMS)1460是怎么来的,链路层的以太网物理特性决定数据帧长度为1500(即MTU,最大传输单元),1460=1500-20(IP首部长度)-20(TCP首部长度)。不要被该报文首部长度32字节所迷惑,这只是建立连接过程。MSS与MTU关系见下图[2]:

图7 MSS与MTU关系

    NOP字段,可以作为不足4倍数字节填充,也可作为选项间分隔,该报文段出现了3个NOP,具体功能见下图:

图8 TCP报文NOP字段

3.3 第二次握手21

    服务器响应客户端TCP报文段,此时确认号为1了,SYN=1、ACK=1表明连接应答捎带一个确认,Wireshark俘获分组如下:

图9 TCP连接第二次握手实例

    为什么MSS是1452而不是1460?这是因为使用PPPoE(Point-to-Point over Ethernet,可以使以太网的主机通过一个简单的桥接设备连到一个无端的接入集中器上[3])拨号上网,PPoP首部是8个字节,所以PPPoE的MTU是1492,MSS也就为1492-40=1452。

    那么,TCP连接建立后数据传输的MSS是多少呢,1460 or 1452 or 536 ?我的理解是默认值536,这样理解对吗?求指点!

3.4 第三次握手22

    客户机再次服务器的报文段,此时序列号和确认号都为1,没有选项字段,Wireshark俘获的分组信息如下:

图10 TCP连接第三次握手实例

    值得注意的,因为窗口扩展大小协商未果,所以就不扩大窗口了,即窗口大小最大为65535。

如此,TCP连接建立:-)

参考资料:

[1] 百度百科词条:三次握手

[2] 文章《TCP头部选项功能详解

[3] 百度百科词条:PPPOE

[4] Andrew S.Tanenbaum.计算机网络[M].

[5] 《计算机网络--自顶向下方法与Internet特色》[M].

 TCP报文格式.rar

 TCP连接建立过程.rar

from:http://blog.chinaunix.net/uid-9112803-id-3212041.html

结合Wireshark捕获分组深入理解TCP/IP协议栈之TCP协议(TCP报文格式+三次握手实例)的更多相关文章

  1. 结合Wireshark捕获分组深入理解TCP/IP协议栈

    摘要:     本文剖析了浏览器输入URL到整个页面显示的整个过程,以百度首页为例,结合Wireshark俘获分组进行详细分析整个过程,从而更好地了解TCP/IP协议栈.   一.俘获分组 1.1 准 ...

  2. 结合Wireshark捕获分组深入理解TCP/IP协议栈之DNS协议

    摘要:     本文简单介绍了DNS协议理论知识,给出URL解析步骤,详细讲述了DNS报文各个字段含义,并从Wireshark俘获分组中选取DNS相关报文进行分析. 一.概述 1.1 DNS      ...

  3. 结合Wireshark捕获分组深入理解TCP/IP协议之以太网帧

    摘要:     本文摘抄并整理了以太网相关理论知识,包括CSMA/CD协议机制及工作.LAN互连,详细分析了Ethernet II帧格式,最后给出Ethernet II帧实例. 一.以太网[1] 1. ...

  4. 结合Wireshark捕获分组深入理解TCP/IP协议之IP协议

    摘要:     本文简单介绍了网络层理论知识,详细讲解了IP数据报各个字段,并从Wireshark俘获分组中选取IP数据报进行分析,也阐述了分组和分片的区别.   一.IPv4数据报     网络层是 ...

  5. 结合Wireshark捕获分组深入理解TCP/IP协议栈之HTTP协议

    摘要:     本文简单介绍了Web应用层协议理论知识,详细讲述了HTTP请求报文和响应报文各个字段含义,并从Wireshark俘获分组中选取HTTP相关报文进行分析. 一.概述     Web的应用 ...

  6. TCP/IP网络编程之基于TCP的服务端/客户端(一)

    理解TCP和UDP 根据数据传输方式的不同,基于网络协议的套接字一般分为TCP套接字和UDP套接字.因为TCP套接字是面向连接的,因此又称为基于流(stream)的套接字.TCP是Transmissi ...

  7. 使用TCP/IP Monitor监视Soap协议

    什么是soap? soap,简单对象访问协议,基于http传输xml数据,soap协议体是xml格式. SOAP 是一种网络通信协议 SOAP即Simple Object Access Protoco ...

  8. 理解TCP/IP协议栈之HTTP2.0

    1 前言 前面写了10多篇关于Redis底层实现.工程架构.实际应用的文章,感兴趣的读者可以进行阅读,如有问题欢迎交流: 1.Redis面试热点之底层实现篇-12.Redis面试热点之底层实现篇-23 ...

  9. TCP/IP协议栈概述及各层包头分析

    TCP/IP协议栈中各层包头的分析 Protocol列表示的是该数据包最高层对应的协议,Length列表示该包的长度(包括从底层的协议到最高层的协议,其中包头一般是,链路层14字节,IP20字节,TC ...

随机推荐

  1. Mahout的推荐系统

    Mahout的推荐系统 什么是推荐系统 为什使用推荐系统 推荐系统中的算法 什么是推荐系统 为什么使用推荐系统? 促进厂商商品销售,帮助用户找到想要的商品 推荐系统无处不在,体现在生活的各个方面 图书 ...

  2. 洛谷P1908 逆序对(归并排序)

    题目描述 猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计.最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定 ...

  3. C++标准库概述

    一.C++标准库的主要组件: 1.标准C库 2.I/O流技术(对标准输入输出设备称为标准I/O,对在外磁盘上文件的输入输出称为文件I/O,对内存中指定的字符串存储空间的输入输出称为串I/O) 3.st ...

  4. C# 爬虫总结

    static void Main(string[] args) { //WebRequest request = WebRequest.Create("http://www.cnblogs. ...

  5. Kinect 开发 —— 显示骨骼用户插件

    public partial class SkeletonViewer : UserControl { private readonly Brush[] _SkeletonBrushes = new ...

  6. IFC数据模式架构的四个概念层

    IFC模型体系结构由四个层次构成, 从下到上依次是 资源层(Resource Layer).核心层(Core Layer).交互层(Interoperability Layer).领域层(Domain ...

  7. Android 控件:CheckBox

    首先,在布局文件里注冊CheckBox activity_main.xml <LinearLayout xmlns:android="http://schemas.android.co ...

  8. BZOJ4025: 二分图(LCT)

    Description 神犇有一个n个节点的图.因为神犇是神犇,所以在T时间内一些边会出现后消失.神犇要求出每一时间段内这个图是否是二分图.这么简单的问题神犇当然会做了,于是他想考考你. Input ...

  9. Eclipse导入Maven项目出现错误:Unsupported IClasspathEntry kind=4

    使用Eclipse导入Maven项目失败,提示: An internal error occurred during: "Importing Maven projects". Un ...

  10. php函数,static,globalkeyword及三种变量作用域

    函数 和js函数相似,关注php与其它语言不用的地方 函数的形參默认值 形式: function f($a,$b=3,$vc = "abc"){ } 注意:没有给默认值的形參必须传 ...