0.关于TCP协议的一些总结
接触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协议的一些总结的更多相关文章
- TCP协议调试工具TcpEngine V1.3.0使用教程
简介 这里说的TCP协议调试定义是在开发长连接TCP协议应用时,为了验证代码流程或查找bug,需要与对端交互数据过来,当需要时可以暂停发送:单条发送:跳过发送:正常发送:发送时修改数据等. T ...
- 【转】TCP协议
TCP是什么? TCP(Transmission Control Protocol 传输控制协议)是一种面向连接(连接导向)的.可靠的. 基于IP的传输层协议.TCP在IP报文的协议号是6.TCP是一 ...
- TCP协议的三次握手和四次挥手
暂时需要的信息有: ACK : TCP协议规定,只有ACK=1时有效,也规定连接建立后所有发送的报文的ACK必须为1 SYN(SYNchronization) : 在连接建立时用来同步序号.当SYN= ...
- 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 ...
- TCP协议与UDP协议的区别
TCP协议与UDP协议的区别(转) 首先咱们弄清楚,TCP协议和UCP协议与TCP/IP协议的联系,很多人犯糊涂了,一直都是说TCP/IP协议与UDP协议的区别,我觉得这是没有从本质上弄清楚网络通信! ...
- tcp协议头窗口,滑动窗口,流控制,拥塞控制关系
参考文章 TCP 的那些事儿(下) http://coolshell.cn/articles/11609.html tcp/ip详解--拥塞控制 & 慢启动 快恢复 拥塞避免 http://b ...
- 采用TCP协议的PIC32MZ ethernet bootloader
了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 趁热打铁,在上一PIC ...
- 采用TCP协议实现PIC18F97J60 ethernet bootloader
了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). TCP/IP Stac ...
- TCP协议疑难杂症全景解析
说明: 1).本文以TCP的发展历程解析容易引起混淆,误会的方方面面2).本文不会贴大量的源码,大多数是以文字形式描述,我相信文字看起来是要比代码更轻松的3).针对对象:对TCP已经有了全面了解的人. ...
随机推荐
- js+jquery+css3
(原生js+jquery+css3) 前言 项目需求要弄个瀑布流的页面,用的是waterfall这个插件,感觉还是可以的,项目赶就没自己的动手写.最近闲来没事,就自己写个.大致思路理清楚,还是挺好实现 ...
- Protel 99SE PCB 打印技巧
1. 打开 Protel99SE PCB 设计文档.从菜单File 下单击Print/Preview 打印预览菜单.出现PCB 打印预览介面. 2.从File 下单击 Setup Printer 设置 ...
- MVC模式已死
MVC模式:Model模型 View试图 Control控制器,是目前主流模式,被当作服务器软件入门基本模式学习和掌握,主流框架Struts 1/2 JSF Wicket基本都顺理成章支持MVC模式. ...
- golang ODBC 访问access数据库(问题解决之心理路程)
最近项目需要,需要操作access,以前是用VC++ OLE访问,网络用ACE库,感觉很庞大...决定用go试试 网上用的最多的就是这个https://github.com/weigj/go-odbc ...
- HashMap和HashTable 学习
1. HashMap 1) hashmap的数据结构 Hashmap是一个数组和链表的结合体(在数据结构称“链表散列“),如下图示: 当我们往hashmap中put元素的时候,先根据key的hash ...
- jsp 声明类的使用
能够在"<%!"和"%>"之间声明一个类,该类在JSP页面内有效,即在JSP页面的Java程序片部分能够使用该类创建对象.在以下的样例中,我们定义了 ...
- HttpWebRequest和WebClient的区别
HttpWebRequest和WebClient的区别(From Linzheng): 1,HttpWebRequest是个抽象类,所以无法new的,需要调用HttpWebRequest.Creat ...
- 也谈.NET MVC 2 + ExtJS的部署问题
由于业务需要,笔者刚进到一个项目组,由于没有美工,前台采用ExtJs + MVC 2 ,迭代1的项目做的还算比较顺利,至少在本机上是运行没有任何问题的, 但是为了给客户演示,我兴高采烈的将网站部署在I ...
- Xcode - 内存分析
内存分析工具 1. ARC中的内存泄露 1. 一般内存分析, 主要是看看有没有内存泄露 2. 内存泄露: 创建了对象, 使用完毕没有释放, 将来就可能造成内存泄露 3. 内存泄露: 主要用于MRC的内 ...
- javascripts小结
1 NAN-isNaN():判断是否数值 2 数值转换 Number()-任何数据类型,parseInt(),parseFloat()-字符串 3数组转字符串 var a=["red&quo ...