接触unix网络编程一年多了,偶尔用户态进程表现出一些不能理解的现象,因此将《TCP/IP协议卷1》TCP协议相关的章节通读了一遍,总结了一下相关的知识点。

1.TCP数据报格式

  TCP封装在IP数据报中,如下:

-------------------------------------------------------------------------------------

  |----IP首部(20字节)----||----TCP首部(20字节)||----TCP选项----||----TCP数据----|

  TCP数据包首部的格式如下:

  |--------16位源端口号---------------||--------------16位目的端口号--------------|

  |--------------------------------32位序号---------------------------------------|

  |--------------------------------32位确认序号-----------------------------------|

  |-4位首部长度-||-保留6位-||-TCPflag-||------------16位窗口大小------------------|

  |-----------16位校验和--------------||----------------16位紧急指针--------------|

  |-----------------------------------TCP选项-------------------------------------|

  |-----------------------------------TCP数据-------------------------------------|

--------------------------------------------------------------------------------------

                    图1.TCP报头结构              

2.TCP建立连接和断开连接

  tcp连接的建立需要经过三次握手:

1.客户--SYN j-->服务器,客户状态:主动打开SYN_SENT,服务器状态:SYN_RCVD。

2.服务器--SYN k,ack j+1-->客户,客户状态:ESTABLISHED,服务器状态:SYN_RCVD。

3.客户--ack k+1-->服务器, 客户状态:ESTABLISHED,服务器状态:ESTABLISHED。

  tcp连接终止需要经过四次握手:

1.客户--FIN m-->服务器,客户状态:FIN_WAIT_1,服务器状态:CLOSE_WAIT。

2.服务器--ack m+1-->客户,客户状态:FIN_WAIT_2,服务器状态:CLOSE_WAIT。

3.服务器--FIN n-->客户, 客户状态:TIME_WAIT,服务器状态:LAST_ACK。

4.客户--ack n+1-->服务器,客户状态:TIME_WAIT或closed,服务器状态:closed。

  主动关闭的TCP一端会经历TIME_WAIT状态,从TIME_WAIT状态到closed状态经历2倍MSL的时间。MSL:报文最大生存时间,它是任何报文段被丢弃前在网络内的最长时间。

  另外TCP头部的 flags包括{S-SYN、F-FIN、R-RST、P-PSH、.-其他},SYN是同步序号,FIN是发送方完成数据发送,RST复位连接,PSH尽可能快的将数据送往接收进程,. 以上四个标志比特均为0。

3.呼入连接请求队列

  等待连接请求的一端有一个固定长度的连接队列,该队列中的连接已经被TCP接受,但还没有被应用层接受。

区分:TCP接受一个连接是将其放入连接请求队列,而应用层接受连接是将其从该队列中移除。

4.交互数据流和nagle算法

  交互数据总是以小于报文长度的分组发送。广域网环境,大量小分组的传输会导致网络拥塞,受延时的确认nagle算法用来减少广域网络传输的小分组的数目。

  受延时的确认:TCP接收端接收到数据时并不立即发送ACK;相反,它推迟发送,以便将ACK与需要沿该方向发送的数据一起发送。大多数实现采用时延为200ms。受时延的确认在接收端减少网络传输小分组的数目。

  nagle算法:TCP连接上的发送方最多只能有一个未被确认的未完成的小分组,在该分组的确认到达之前不能发送其他的小分组,TCP发送方收集这些少量的分组,并在确认到来时以一个分组的方式发送出去。nagle算法在发送端减少网络上小分组传输的数量。

对于交互用户而言,nagle算法会产生明显的时延。

5.滑动窗口协议

   滑动窗口协议是TCP流量控制的一种方式,与之相对的是停止等待协议(TFTP使用)。滑动窗口协议允许发送端在停止等待确认前,可以发送多个分组,与停止等待协议相比,滑动窗口协议加速了数据的传输,接收方看到的滑动窗口结构如图2所示。

------------------------------------------------------------------------------------

|----接收方通告,提供的窗口-----|

                      |-可用的窗口-|

|-----1------2-----3-----4------5-----6-----7------8-----9-----10------11----.....

    |-发送被确认-|     |-发送未确认-|     |-能够发送的-|     |-不能发送

------------------------------------------------------------------------------------

                     图2.滑动窗口接口   

  发送方根据接收方通告的窗口大小,计算可用的窗口大小,该窗口表明多少数据可以立即被发送出去。随着分组的发送以及被确认,窗口的两个边沿会不断右移:

  1.窗口左边右移,窗口合拢,导致原因:数据被发送并且被确认时。

  2.窗口右边右移,窗口张开,导致原因:接收方接收进程读取了接收缓冲区的数据,释放了接收缓存,并且发送了新的窗口通告给发送方。

  从上面可以看出,导致滑动窗口张开是接收方产生新的窗口通告,因此滑动窗口是接收方流量控制的措施。

6.紧急方式

  通过设置TCP首部的两个字段来发出紧急通知:从一端到另一端的紧急数据已经被放置在数据流中。URG比特被置1,并且16比特的紧急指针被置为一个正的偏移量。可以利用tcp的紧急方式实现tcp通信双方的心搏。

7.带宽时延积

  带宽时延积用来描述一个tcp管道的容量:

    capcity(bit) = bandwidth(b/s) * round-trip time(s)

只有当管道被填满时,才能达到最大的吞吐量。对于高延迟和大带宽的肥胖管道,增加tcp发送和接收缓冲区,才能填满tcp管道,达到最大的吞吐量。

7.慢启动和拥塞避免算法

  慢启动:为发送方tcp增加了另外一个窗口-拥塞窗口,cwnd。当tcp连接建立时,拥塞窗口大小被初始化为一个报文段长度,每收到一个ack,cwnd就增加一个报文段的长度,发送方取拥塞窗口与通告窗口的最小值作为发送上线。拥塞窗口cwnd是发送方的流量控制方式,另外cwnd在开始阶段指数方式增长,慢启动是在一个连接上发起数据流的方法

  拥塞避免算法是一种处理分组丢失的方法,与慢启动是不同,当处于拥塞避免阶段时每收到一个ack,cwnd增加cwnd/1,拥塞避免阶段cwnd呈线性方式增长。

  慢启动算法和拥塞避免算法通常一起工作,这两个算法需要对每一个连接维护两个变量:cwnd和慢启动门限ssthresh。大致的工作过程:

  1.对于一个给定的连接,初始cwnd为1个报文段,ssthresh为65535个字节。首先是当前窗口没有达到65535时,采用慢启动的方式进行分组的传输。

  2.当拥塞发生时(超时或者收到重复的确认),ssthresh被设置成当前窗口大小的一半。此外,如果是阻塞引起的超时,则cwnd被设置成1个报文段。

  3.当有新的ack到达时,就增加cwnd,增加的方法依赖于是否是慢启动或者拥塞避免。如果cwnd小于或等于ssthresh,则执行慢启动,否则拥塞避免。慢启动时,指数方式增加cwnd,拥塞避免时,线性方式增加cwnd。

  关于分组的传输,还存在快速重传快速恢复的算法。所谓的快速重传,即当连续收到3个重复的ack时,就确认对应分组丢失,不等待超时定时器溢出,而直接重传对应分组。当确认分组丢失,执行快速重传后,不是去执行慢启动将cwnd的值置为1,而是执行拥塞避免算法,这就是快速恢复算法。

8.TCP坚持定时器和糊涂窗口综合症

  当发送方tcp接收到窗口大小为0的窗口通告时,发送方将停止发送数据,并且设定一个坚持定时器来周期性的像接受发查询,以便发现窗口是否已经增大,这些从发送方发出的报文段成为窗口探查。坚持定时器使用tcp 500ms定时器,并采用了tcp指数退避,但是坚持定时器总是在5~60S之间。窗口探查会一直持续,直到窗口被打开,或者tcp连接被关闭

  糊涂窗口综合征:少量的数据将通过连接进行交换,而不是满长度的报文段。糊涂窗口综合征,降低了tcp的有效吞吐量。避免糊涂窗口综合征,可以在发送方或者接收方的任何一方采取措施:1.接收方不通告小窗口,2.发送方才一般情形下避免发送小的报文段。

9.keepalive定时器

  如果一个给定的tcp连接在两个小时之内没有任何动作,则服务器就向客户发送一个探查报文段。客户可能处于一下状态:

  1.客户主机依然正常运行,并从服务器可达:客户的tcp响应正常。

  2.客户主机已经崩溃,并且关闭或者正在重新启动:服务器探查报文段收不到响应,75s后超时,一直持续发送共10个探查,间隔75s,如果仍然没有收到响应,则认为客户主机已经关闭。

  3.客户主机崩溃并已经重新启动:服务器将收到一个复位,使得服务器终止这个连接。

  4.客户机正常运行,但从服务器不可达:和1中情形类似。

0.关于TCP协议的一些总结的更多相关文章

  1. TCP协议调试工具TcpEngine V1.3.0使用教程

    简介   这里说的TCP协议调试定义是在开发长连接TCP协议应用时,为了验证代码流程或查找bug,需要与对端交互数据过来,当需要时可以暂停发送:单条发送:跳过发送:正常发送:发送时修改数据等.   T ...

  2. 【转】TCP协议

    TCP是什么? TCP(Transmission Control Protocol 传输控制协议)是一种面向连接(连接导向)的.可靠的. 基于IP的传输层协议.TCP在IP报文的协议号是6.TCP是一 ...

  3. TCP协议的三次握手和四次挥手

    暂时需要的信息有: ACK : TCP协议规定,只有ACK=1时有效,也规定连接建立后所有发送的报文的ACK必须为1 SYN(SYNchronization) : 在连接建立时用来同步序号.当SYN= ...

  4. ZeroMQ接口函数之 :zmq_tcp – 使用TCP协议的ØMQ网络单播协议

    ZeroMQ 官方地址 :http://api.zeromq.org/4-1:zmq-tcp zmq_tcp(7)          ØMQ Manual - ØMQ/4.1.0 Name zmq_t ...

  5. TCP协议与UDP协议的区别

    TCP协议与UDP协议的区别(转) 首先咱们弄清楚,TCP协议和UCP协议与TCP/IP协议的联系,很多人犯糊涂了,一直都是说TCP/IP协议与UDP协议的区别,我觉得这是没有从本质上弄清楚网络通信! ...

  6. tcp协议头窗口,滑动窗口,流控制,拥塞控制关系

    参考文章 TCP 的那些事儿(下) http://coolshell.cn/articles/11609.html tcp/ip详解--拥塞控制 & 慢启动 快恢复 拥塞避免 http://b ...

  7. 采用TCP协议的PIC32MZ ethernet bootloader

    了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 趁热打铁,在上一PIC ...

  8. 采用TCP协议实现PIC18F97J60 ethernet bootloader

    了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). TCP/IP Stac ...

  9. TCP协议疑难杂症全景解析

    说明: 1).本文以TCP的发展历程解析容易引起混淆,误会的方方面面2).本文不会贴大量的源码,大多数是以文字形式描述,我相信文字看起来是要比代码更轻松的3).针对对象:对TCP已经有了全面了解的人. ...

随机推荐

  1. JS笔记 入门第一

    WHY? 一.你知道,为什么JavaScript非常值得我们学习吗? 1. 所有主流浏览器都支持JavaScript. 2. 目前,全世界大部分网页都使用JavaScript. 3. 它可以让网页呈现 ...

  2. IOS 表视图(UITableVIew)的使用方法(8)表视图的编辑功能(多选)

    在表视图的删除操作中,每次只能够对其中一个单元进行删除,如果想要同时删除多条记录,不得不挨个地进行标准的删除操作 所以如果能够实现多选的机制,无论是删除还是其他功能的嫁接,都会变得更加方便 当UITa ...

  3. C++ 面向对象学习2 构造方法

    Date.h #ifndef DATE_H #define DATE_H class Date{ public: Date(,,);//自定义了构造方法 会覆盖掉默认的无参构造方法 void setD ...

  4. C# 读书笔记之访问关键字this和base

    this 关键字引用类的当前实例.静态成员方法中不能使用this关键字,this关键字只能在实例构造函数.实例方法或实例访问器中使用. base 关键字用于从派生类中访问基类的成员. 指定创建派生类实 ...

  5. 浅谈RFID电子标签封装技术

    1RFID技术概述 1.1RFID技术概念 RFID是RadioFrequencyIdentification的缩写,即射频识别技术,俗称电子标签.RFID射频识别是一种非接触式的自动识别技术,它通过 ...

  6. 关于Delphi中二维数组的声明和大小调整(对非基本类型数据,小心内存泄漏)

    这是一个实例: procedure TMainForm.Button1Click(Sender: TObject);var  arr:array of array of string;begin  s ...

  7. android使用全局变量的两种方法

         在我们使用android编写程序的时候,少不了想利用全局变量,但是面向对象语言和过程语言区别很大,不再是include就可以的.这里我写了使用全局变量的两种方法: 1.使用applicati ...

  8. Network of Schools(强连通分量+缩点) (问添加几个点最少点是所有点连接+添加最少边使图强连通)

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 13801   Accepted: 55 ...

  9. Sql缓存依赖--数据库缓存

    •依赖于文件内容CacheDependency cDep = new CacheDependency(filePath); •依赖于数据库内容(轮询机制/通知机制)一:轮询机制 1.在数据库新建版本表 ...

  10. MVC3 验证码

    public ActionResult GetValidateCode()        {                         string code = CreateValidateC ...