问题聚焦:
    本节从如下四个方面讨论TCP协议:
    TCP头部信息:指定通信的源端端口号、目的端端口号、管理TCP连接,控制两个方向的数据流
    TCP状态转移过程:TCP连接的任意一端都是一个状态机
    TCP数据流:两种主要类型:交互数据流,成块数据流
    TCP数据流的控制:保证可靠传输和提高网络通信质量,两个方面:超时重传,拥塞控制

1 TCP服务的特点
传输层协议:TCP协议,UDP协议
TCP协议特点:面向连接,字节流和可靠传输
    先建立连接,才能开始读写数据
    双方都要分配内核资源
    全双工,读写可以通过一个连接
    必须断开连接,以释放资源
    一对一,所以不适合基于广播和多播的应用程序(UDP适合)
字节流服务:发送端执行的写操作次数和接收端执行的读操作次数之间没有任何数量关系,这就是字节流的概念,即应用程序对数据的发送和接收是没有边界限制的。
    (和字节流相对应的是数据报服务:如UDP,发送端应用程序没执行一次写操作,UDP模块就将其封装成一个UDP数据报并发送之,接收端必须针对每一个UDP数据报执行读操作。)
TCP字节流服务和UDP数据报服务的工作流程区别如下图所示:
TCP传输是可靠的:
  • 发送应答机制,即发送端发送的每个TCP报文段都必须得到接收方的应答,才认为这个TCP报文段传输成功
  • 超时重传机制:发送端在发送出一个TCP报文段之后启动定时器,如果在定时时间内未收到应答,它将重发该报文段
  • 重排,整理:TCP报文段最终是以IP数据报发送的,而IP数据报到达接收端可能乱序、重复,所以TCP协议还会对接收到的TCP报文段重排、整理,再交付给应用层。

2 TCP头部结构
如图:
 
 
16位端口号:告知主机该报文段是来自哪里(源端口号),以及传给哪个上层协议或应用程序(目的端口)。对于客户端来说,端口号常为系统自动选择。
32位序号:一个TCP通信过程中某一个传输方向上的字节流的每个字节的编号。如某个TCP报文段传送的数据是字节流中的第1025到2048字节,那么该报文段的序号值就是ISN+1025,ISN为初始序号值。
32位确认号:用作对另一方发送来的TCP报文段的响应。其值是收到的TCP报文段的序号值加1。
4位头部长度:标识TCP头部有多少个4字节。最长标识60字节。
6位标志位:ACK(确认号是否有效),SYN(请求建立一个连接),FIN(通知对方本端要关闭连接)
16位窗口大小:TCP流量控制窗口。告诉对方本端的TCP缓冲区还能容纳多少字节的数据。
16位校验和:CRC算法校验。这个校验不仅包括TCP头部,也包括数据部分。
16位紧急指针:发送端向接收端发送紧急数据的方法。一个正的偏移量,它和序号字段的值相加表示最后一个紧急数据的下一字节的序号。
 
选项:最多40字节。常见7种类型。
    结构:
    
    常见的7种选项:
        
Demo 使用tcpdump观察TCP头部信息
需要注意的一点是,tcpdump输出的TCP报文段描述信息和TCP头部二进制信息是完全对应的,只是省略了一些不常用的信息,所以只是在这里具体分析TCP头部的二进制信息,而在后面只使用tcpdump的描述信息进行过程的分析。
 
首先来看一下tcpdump的描述信息的含义:
Flags [S]: 表示该TCP报文段包含SYN标识,因此它是一个同步报文段。如果TCP报文段包含其他标识,则tcpdump也会将该标志的首字母显示在Flags后的方括号中。
seg:序号值。
win:接收通告窗口的大小。这是一个同步报文段,所以win值反映的是实际的接收通告窗口的大小。
options:TCP选项字段。mss(发送端声明的最大报文长度),sackOK(发送端支持并同意使用SACK选项),TS val(发送端的时间戳),ecr(时间戳回显应答,第一个报文,所以时间戳的应答位0),nop(空选项操作),wscale(发送端使用的窗口扩大因子位6)。
接下来分析二进制信息:从第21字节开始
十六进制数 十进制表示 TCP头部信息
0xa295 41621 源端口号
0x0017 23 目的端口号
0xd099e103 3499745539 序号
0x00000000 0 确认号
0xa 10 TCP头部长度为10个4字节,即40字节
0x002   设置了SYN标志位,即SYN=1
0x8010 32792 接收窗口大小
0xfe30   头部检验和
0x0000   没设置URG位,所以紧急指针无效
0x0204   最大报文段长度选项的kind值和length值
0x400c 16396 最大报文长度
0x0402   允许SACK选项
0x080a   时间戳选项的kind值和length值
0x026e44d9 40781017 时间戳
0x00000000 0 回显应答时间戳
0x01   空操作选项
0x0303   窗口扩大因子选项的kind值和length值
0x06 6 窗口扩大因子为6

3 TCP连接的建立和关闭
Demo 使用tcpdump观察的数据来分析TCP连接的建立和关闭
当执行telnet命令登录和退出另外一台电脑时,会触发TCP连接的的建立和关闭。抓取的包筛选出TCP连接部分的包,如下图所示(为了方便观察,并没有给出对应的二进制信息)
 

分析:因为整个过程并没有发生应用层数据的交换,所以TCP报文段的数据部分的长度总是0。
时序图表示如下:
 
TCP三次握手过程
报文段1:包含SYN标志位,同步报文段,请求发起连接,初始报文序号ISN为535734930(同步报文段占了一个序号值)。
报文段2:包含SYN标志位,同步报文段,初始报文序号ISN为2159701207(同步报文段占了一个序号值)。
                包含ACK标志位,对报文段1进行确认,确认值为535734931,即第1个同步报文段的序号值加1。
报文段3:包含ACK标志位,对报文段2进行确认,确认值为2159701208,即第2个同步报文段的序号值加1。
TCP四次释放过程
报文段4:包含FIN标志位,结束报文段。占用一个序号值。
报文段5:确认结束报文段4。
报文段6:发送自己的结束报文段。
报文段7:确认结束报文段6。
特殊地,半关闭状态:
TCP连接是全双工的,所以它允许两个方向的数据传输被独立关闭。
半关闭状态:通信的一段发送结束报文段给对方,告诉它本端已经完成了数据的发送,但允许继续接收癞子对方的数据,直到对方也发送结束报文段以关闭连接。
 
    
判断对方是否已经关闭连接的方法:read系统调用返回0。
socket网络编程接口通过shudown函数提供了对半关闭的支持。
连接超时
对于提供可靠的TCP服务来说,当对方没有应答时,它必然先进行重连,如果重连仍然无效,则通知应用程序连接超时。
在应用程序中,我们可以修改连接超时时间。在后面的章节会介绍相关的内容。

4 TCP状态转移
下图是TCP完整的状态转移图。描绘了所有的TCP状态以及可能的状态转换。
  • CLOSED是一个假想的起始点,并不是一个实际的状态。
  • 粗虚线表示典型的服务器端连接的状态转移
  • 粗实线表示典型的客户端连接的状态转移
 
TIME_WAIT状态:
在主动关闭流程中,假设客户端为接收方
客户端接收到服务器的结束报文段之后,并没有直接进入CLOSED状态,而是转移到TIME_WAIT状态。
在这个状态要等待2MSL(MSL, 报文段最大生存时间)的时间,才能完全关闭。原因:
  • 可靠地终止TCP连接:若关闭确认报文段丢失(报文段7),则在这段时间等待接收重发的关闭确认报文段。
  • 保证让迟来的TCP报文段有足够的时间被识别并丢弃:2MSL可确保在网络上两个传输方向上尚未被接收到的、迟到的TCP报文段都已经小时。确保一个新的TCP连接可以安全的建立而不会接收到上一个TCP连接的数据。(这也是为什么当有些和TCP相关的程序退出后,我们无法立即启动它的原因)

复位报文段:

在某些特殊条件下,TCP连接的一端会向另一端发送携带RST标志的报文段,即复位报文段,以通知对方关闭连接或重新建立连接。
三种产生复位报文段的3种情况。
  • 访问不存在的端口:当客户端程序访问一个不存在的端口时,目标主机将给它发送一个复位报文段。
  • 异常终止连接:一旦给对方发送一个复位报文段,发送端所有排队等待的数据都将被丢弃。
  • 处理半打开连接:如果客户端(或服务器)处于半打开状态的连接写入数据,则对方将回应一个复位报文段。

5 TCP数据流
在前面的小节中,我们讨论了TCP的连接及其状态,从本节开始,我们开始讨论通过TCP连接交换的应用程序数据。
按照数据长度分为两种:
  • 交互数据(实时性):
  • 成块数据(传输效率):
    • 当传输大量大块数据的时候,发送方会连续发送多个TCP报文段,接收方可以一次确认所有这些报文段。
    • 服务器每发送4个TCP报文段就传送一个PSH标志给客户端,以通知客户端的应用程序尽快读取数据。

6 TCP超时重传
异常网络状况下,TCP控制数据传输以保证其可靠服务的措施。
Point:
  • TCP模块为每个TCP报文段都维护一个重传定时器,该定时器在TCP报文段第一次被发送时启动。
  • 如果超时时间内未收到接收方的应答,TCP模块将重传TCP报文段并重置定时器。
  • 每次重传超时时间增加一倍。
  • Linux内核有两个重要的内核参数与TCP超时重传相关:/proc/sys/net/ipv4/tcp_retries1和proc/sys/net/ipv4/tcp_retries2
  • TCP报文段的重传可以发生在超时之前,即快速重传,下一节讨论。

7 拥塞控制
目的:提高网络利用率,降低丢包率,并保证网络资源对每条数据流的公平性。
四种拥塞控制:

  • 慢启动(slow start)
  • 拥塞控制(congestion avoidance)
  • 快速重传(fast retransmit)
  • 快速恢复(fast recovery)

多种实现:

  • reno算法
  • vegas算法
  • cubic算法

最终受控制的变量:发送端向网络一次连续写入的数据量(SWND, 发送窗口)。

                               SWND限定了连续发送的TCP报文段数量。
                               TCP报文段的最大长度(仅指数据部分)称为SMSS。
影响:发送端需要合理地选择SWND的大小。如果SWND太小,会引起明显的网络延迟:反之,如果SWND太大,则容易导致网络拥塞。
窗口大小:接收方通过比较两个值:RWND(接收通告窗口)和拥塞窗口(CWND),取其较小值,作为SWND的值。
如图所示:
 
关于TCP还剩下拥塞控制的详细介绍,将在后续作为专题仔细学习。
To be continued ......

参考资料:
《Linux高性能服务器编程》
 

服务器编程入门(3)TCP协议详解的更多相关文章

  1. 第3章 TCP协议详解

    第3章 TCP协议详解 3.1 TCP服务的特点 传输协议主要有两个:TCP协议和UDP协议,TCP协议相对于UDP协议的特点是 面向连接使用TCP协议通信的双方必须先建立连接,完成数据交换后,通信双 ...

  2. TCP协议详解7层和4层解析(美团,阿里) 尤其是三次握手,四次挥手 具体发送的报文和状态都要掌握

    如果想了解HTTP的协议结构,原理,post,get的区别(阿里面试题目),请参考:HTTP协议 结构,get post 区别(阿里面试) 这里有个大白话的解说,可以参考:TCP/IP协议三次握手和四 ...

  3. TCP协议详解

    TCP协议详解 一.TCP协议 1.TCP 通过以下方式提供可靠性: ·  ◆ 应用程序分割为TCP认为最合适发送的数据块.由TCP传递给IP的信息单位叫做报文段. ·  ◆ 当TCP发出一个报文段后 ...

  4. TCP协议详解(理论篇)

    TCP协议详解(理论篇) 2012-08-20      0个评论       作者:陈立龙 收藏    我要投稿 TCP协议详解(理论篇)   1.    与UDP不同的是,TCP提供了一种面向连接 ...

  5. linux高性能服务器编程 (三) --TCP协议详解

    第三章 IP协议详解 TCP协议是TCP/IP协议族中的另外一个重要的协议,与IP协议相比,TCP协议更高进应用层.一些重要的socket选项都和TCP协议相关.这一章主要从如下方面学习: 1)TCP ...

  6. Linux 高性能服务器编程——TCP协议详解

    问题聚焦:     本节从如下四个方面讨论TCP协议:     TCP头部信息:指定通信的源端端口号.目的端端口号.管理TCP连接,控制两个方向的数据流     TCP状态转移过程:TCP连接的任意一 ...

  7. 网络通信协议八之(传输层)TCP协议详解

    传输层协议 分段是为了提高传输效率,封装是指给每个数据段添加一个编号 端到端的传输是逻辑上的端到端,并不是真正意义上的发送方某层与接收方某层之间的传输 IP协议只是保证数据报文发送到目的地,为主机之间 ...

  8. 【TCP协议详解】

    为什么会有TCP/IP协议 在世界上各地,各种各样的电脑运行着各自不同的操作系统为大家服务,这些电脑在表达同一种信息的时候所使用的方法是千差万别.就好像圣经中上帝打乱了各地人的口音,让他们无法合作一样 ...

  9. TCP协议详解---上

    TCP头格式 注意以下几点: TCP的包是没有IP地址的,那是IP层上的事.但是有源端口和目标端口. 一个TCP连接需要四个元组来表示是同一个连接(src_ip, src_port, dst_ip, ...

随机推荐

  1. QT+vs2010下改变可执行程序的图标

    原地址:http://blog.163.com/tijijun@126/blog/static/6820974520134209457308/ 在解决方案下面的工程里,点击右键 ->选择[添加( ...

  2. Swift - 获取屏幕点击坐标下所有对象(SpriteKit游戏开发)

    对于场景内对象元件的点击响应,我们可以在场景的touchesBegan()方法中内统一处理. SKScene中touchesBegan()是响应屏幕点击的方法,在这里面我们可以先获取点击位置下所有的对 ...

  3. 棋盘问题 简单搜索DFS

    Description 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子 ...

  4. /etc/security/limits.conf 设置

    jrhdpt01:/root# cat /etc/security/limits.conf  * soft nofile 65535  * hard nofile 65535  * soft npro ...

  5. matlab中plot使用方法

    MATLAB有非常强的图形功能,能够方便地实现数据的视觉化.强大的计算功能与图形功能相结合为MATLAB在科学技术和教学方面的应用提供了更加广阔的天地.以下着重介绍二维图形的画法,对三维图形仅仅作简单 ...

  6. Xamarin.forms 自定义tabview控件

    一 问题描述 forms本身ui代码是翻译为平台原生代码,forms按照xaml技术进行对android和ios两种ui模型进行公共抽象出了几种page和view,在空杯博客已经有详细介绍 http: ...

  7. #pragma 预处理指令详解

    源地址:http://blog.csdn.net/jx_kingwei/article/details/367312 #pragma  预处理指令详解              在所有的预处理指令中, ...

  8. mysql update 有无索引对比

    <pre name="code" class="html">mysql> desc ProductInfo; +--------------- ...

  9. 彻底卸载McAfee和Agent的方法

    1.控制面板中-添加或删除程序中-删除"McAfee VirusScan Enterprise"和"McAfee AntiSpyware Enterprise Modul ...

  10. java定义和实现接口

    1.定义接口     使用interface来定义一个接口.接口定义同类的定义类似,也是分为接口的声明和接口体.当中接口体由常量定义和方法定义两部分组成.定义接口的基本格式例如以下: [修饰符] in ...