当前位置: 首页 > 编程日记 > 正文

重读TCP协议(3)

重读TCP协议(3) 

TCP 的数据流

       TCP的数据流大致可以分为两类,交互数据流与成块的数据流。交互数据流就是发送控制命令的数据流,比如relogintelnetftp命令等等;成块数据流是用来发送数据的包,网络上大部分的TCP包都是这种包。

       很明显,TCP在传输这两种类型的包时的效率是不一样的,因此为了提高TCP的传输效率,应该对这两种类型的包采用不同的算法。

       总之,TCP的传输原则是尽量减少小分组传输的数量。

TCP的交互式数据流

Ø         经受时延的确认技术

TCP的交互式数据流通常使用“经过时延的确认”技术。通常Server在接收到从Client发送过来的数据时,并不马上发送ACK,而是等一小段时间,看看本机是否有数据要反馈给Client,如果有,就将数据包含在此ACK包中,以前发送给Client。一般情况下这个时延为200ms。需要注意的时这个200ms的定时器时相对于内核的时钟滴答的,也就是jeffs的。加入一个数据分组到达后,此定时器已经pass100ms,那么再过100ms ACK才会被发送,如果在这100ms内有数据要反馈,则在100msACK会和数据一起发送。

      

Ø         Nagle算法分析。

Nagle算法主要用来预防小分组的产生。在广域网上,大量TCP小分组极有可能造成网络的拥塞。

       Nagle时针对每一个TCP连接的。它要求一个TCP连接上最多只能有一个未被确认的小分组。在改分组的确认到达之前不能发送其他小分组。TCP会搜集这些小的分组,然后在之前小分组的确认到达后将刚才搜集的小分组合并发送出去。

       有时候我们必须要关闭Nagle算法,特别是在一些对时延要求较高的交互式操作环境中,所有的小分组必须尽快发送出去。

       我们可以通过编程取消Nagle算法,利用TCP_NODELAY选项来关闭Nagle算法。

 

TCP成块数据流

       TCP成块数据流相关的东西有很多,比如流量控制,紧急数据传输,数据窗口大小调整等等。

Ø         正常数据流

TCP通常不会对每个到达的数据分段进行确认操作,通常一个ACK报文可以确认多个成块数据段报文,通常情况下是两个成块数据报文段需要一个ACK报文确认。通常是由下面的原有造成的 :当收到一个报文后,此TCP连接被标识未一个未完成的时延确认,当再次收到一个数据报文后,此连接有两个未确认的报文段,TCP马上发送一个ACK,当第三个数据报文到达后,第四个报文到达前,通常此TCP连接已经经过了200ms延时,因此一个ACK被发送,这样的循环周而复始,从而出现了一个ACK确认两个数据报文的情况。当然,ACK的产生很大程度上和其接收数据报文段的时间紧密相关,也就是和Client段发送数据的频率相关,和网络拥塞程度相关,和ClientServer两端的处理能力相关,总是是一个多因素决定的结果。

 

Ø         TCP的滑动窗口协议

TCP使用滑动窗口协议来进行流量控制。特别需要注意的是,滑动窗口是一个抽象的概念,它是针对每一个TCP连接的,而且是有方向的,一个TCP连接应该有两个滑动窗口,每个数据传输方向上有一个,而不是针对连接的每一端的。

窗口左边沿向右边滑动叫做窗口合拢,表示发送方发送了数据或者接收到了确认;窗口右边沿向右边滑动叫做窗口的张开,表示数据已经被用户空间进程接收并且释放了缓存;窗口左边沿向左移动则表明此ACK是重复ACK,应该丢弃;窗口右边沿向左移动叫做窗口收缩,一般不会有人这样做。

当左边沿和右边沿重合的时候表明窗口大小是0,此时发送方不应该在发送数据了,因为接收方的接收缓冲区已满,用户进程还没以接收。当用户进程接收完成后,接收方应该发送一个ACK,表明此时的接收窗口已经恢复,此ACK的序号同前一个win0ACK相同。

同样,在实现中,发送方不必发送一个全窗口的数据,但是它当然可以这样做。ACK总是将窗口向右边滑动,窗口的大小可以减小,接收方在发送ACK之前不必等待窗口被填满(即变为0),很多实现是收到两个数据报文段后立刻发送ACK

 

Ø         TCP窗口大小的调整

TCP窗口的大小通常由接收端来确认,也就是在TCP建立连接的第二个SYN+ACK报文的Win字段来确认。

当然,程序可以随时改变这个窗口(缓存)的大小。默认的窗口大小是4096字节,但是对于文件传输来说这并不是一个理想的数字,如果程序的主要目的是传输文件,那么最好将这个缓存设置到最大,但是这样可能会造成发送端连续发送多个数据报文段后,接收方才反馈一个ACK的情况,当然,这也没有什么不可以的,只要不超时,就不算错。

Ø         TCPPUSH

PUSHTCP报头中的一个标志位,发送方在发送数据的时候可以设置这个标志位。该标志通知接收方将接收到的数据全部提交给接收进程。这里所说的数据包括与此PUSH包一起传输的数据以及之前就为该进程传输过来的数据。

Server端收到这些数据后,它需要立刻将这些数据提交给应用层进程,而不再等待是否还有额外的数据到达。

那么应该合适设置PUSH标志呢?实际上现在的TCP协议栈基本上都可以自行处理这个问题,而不是交给应用层处理。如果待发送的数据会清空发送缓存,那么栈就会自动为此包设置PUSH标志,源于BSD的栈一般都会这么做,而且,BSD TCP STACK也从来不会将收到的数据推迟提交给应用程序,因此,在BSD TCP STACK中,PUSH位是被忽略的,因为根本就没有用。

 

Ø         TCP的慢启动(拥塞窗口)

TCP在局域网环境中的效率是很高的,但是到了广域网的环境中情况就不同了,在发送方和接收方之间可能存在多个Router以及一些速率比较慢的链路,而且一些中继路由器必须缓存分组,还可能分片,所以在广域网的环境中,TCP的效率可能出现问题。

为了解决这个问题,现在的TCP栈都支持“慢启动”算法,即拥塞窗口控制算法。该算法通过观察到新分组进入网络的速率与另一端返回ACK的速率相同而工作。其实,拥塞窗口是发送方使用的一种流量控制算法。

慢启动为TCP的发送方增加了一个拥塞窗口,当连接建立时,拥塞窗口被初始化为一个报文段大小,每收到一个ACK,拥塞窗口就会增加一个报文段,发送方取拥塞窗口与通过窗口的最小值作为发送的上限。

 

Ø         TCP成块数据吞吐量

TCP窗口大小,窗口流量控制,慢启动对TCP的成块数据传输综合作用,可能对TCP的数据传输有意想不到的影响。

       RTTRound-Trip Time :往返时间。是指一个报文段从发出去到收到此报文段的ACK所经历的时间。通常一个报文段的RTT与传播时延和发送时延两个因素相关。

       在发送的过程中有可能发生这样的情况,即TCP两端的传输“管道”被填满,即整个管道上都有数据在跑,此时不管拥塞窗口和通告窗口是多少,管道上都不能在容纳更多的数据了。此时每当接收方从网络上移去一个报文段,发送方就发送一个,但是管道上的ACK总是固定的,这种情况就是连接的理想稳定状态。

       一般情况下带宽*时延就是一条线路的容量,因此吧RTT减小可以增加一条线路的容量,注意RTT加大的意思时传输时间减小!

       当数据由一个大的管道向一个小的管道传输时,就有可能发生拥塞,例如,当若干输入流到达一个路由器,而此路由器的输出带宽小于这些输入流的带宽总和时,就会发生拥塞。这种情况普遍见于局域网与广域网的接口处。如果发送方处于局域网,而且不使用慢启动,使用局域网的带宽尽快的发送报文,那么返回的ACK之间的间隔与最慢的广域网链路一致。而且,由于路由器转发包速度慢,所以路由器就有可能主动丢失分组包。

 

Ø         TCP的紧急方式

TCP提供了一种“紧急方式”的数据传输方式,TCP的一端可以告诉另一端有些具有某种方式的紧急数据被放在了普通的数据流中,接收方可以自行选择处理。紧急方式客厅通过设置TCPURG标识位与紧急指针的偏移量来设置。这个紧急指针指向紧急数据的最后一个字节(也有可能是最后一个字节的下一个字节)。

现在有许多实现将紧急方式叫做“带外数据”,其实这是不正确的。

       目前紧急指针被用来禁止停止FTP的数据传输。不过总的来说,用的不多。

       对于数据传输来说,如果用紧急数据来传输大量数据,这种方法显然是不可取的,再建立一个TCP连接不是更简单有效吗?

转载于:https://www.cnblogs.com/yd1227/archive/2011/06/29/2092953.html

相关文章:

拥有2000家门店,他如何晋升为服装界的新宠?

—— iwarm3.0加热组件、碳纳米管膜炎、管状石墨结构体...你看到并不是一款高科技电子产品,这是快鱼服饰在这个冬天推出的黑科技产品 - 智能温控羽绒服。 在竞争激烈的服装行业,快鱼(Fast Fish)将“快时尚”的理念推广至全国&…

navicat连接云数据库报错2003,2005

一开始报2003,好吧,是Mysql挂掉了, 然后重启Mysql服务 systemctl restart mysqld.service #重启 mysql然后再连接,报错2005, 好吧,是复制ip的时候多了一个空格,再输入一次即可 我服了。

基础学习总结(四)--SQLite

1. SQLiteDatabase操作SQLite数据库的类。可以执行SQL语句,对数据库进行增、删、查、改的操作。也可以进行transaction的控制。很多类对数据库的操作最终都是通过SQLiteDatabase实例来调用执行的。需要注意的是,数据库对于一个应用来说是私有的&#xff…

用node实现websocket协议

协议 WebSocket是一种基于TCP之上的客户端与服务器全双工通讯的协议,它在HTML5中被定义,也是新一代webapp的基础规范之一。 它突破了早先的AJAX的限制,关键在于实时性,服务器可以主动推送内容 到客户端!可能的应用有&a…

反向春运成为新趋势 客流年增9%

资料图:春运。殷立勤 摄 中新社北京1月18日电 (记者 周音)近年来,反向春运成为新趋势。中国铁路总公司18日披露,反向春运客流以年增9%左右的速度增长。 传统春运是大城市返乡回家过年。反向春运是年轻人选择将老家的父母和孩子接来自己工作的…

把.sql文件上传到服务器上

使用xftp工具,在root文件夹下新建myProject文件夹,然后把.sql文件拖拽过去即可。 进入xshell, 进入到mysql: mysql -u root -p输入密码: create database 数据库名;use 数据库名;source ~/新…

最先进的开源游戏引擎KlayGE 3.12.0发布

转载请注明出处为KlayGE游戏引擎,本文地址为http://www.klayge.org/2011/06/30/%e6%9c%80%e5%85%88%e8%bf%9b%e7%9a%84%e5%bc%80%e6%ba%90%e6%b8%b8%e6%88%8f%e5%bc%95%e6%93%8eklayge-3-12-0%e5%8f%91%e5%b8%83/ KlayGE 3.12.0在上半年的最后一天发布了&#xff01…

如何防止博客文章被窃取

写文章的优点: 1.整理自己的学习过程,思想心得。 2.看到自己的文章被别人转载了,心理愉悦,说明作者写的文章有价值,可以帮助他人。 缺点: 1.花费时间和精力。 2.说是抄袭别人。明明自己是原创,别…

js中的装饰器执行顺序

/*** 执行顺讯* [(property)...]->[(parameter->method)...]->constructor->class* [属性...]->[((方法参数...)->方法)...]->[constructor...]->class* 声明周期 property|parameter|method|constructor|class* 声明周期 [始化完毕]init->[属性添加…

关于springboot vue前后端分离项目部署到阿里云轻量服务器(前后端分开部署)

0.购买阿里云服务器 1.安装jdk 使用yml安装 2.安装mysql 3.安装nginx 4.打包后端项目 后端项目更改: 在pom.xml文件中,增加打包成jar包的配置文件 application.properties配置文件中更改数据库信息,端口号:(所使…

.NET泛型解析(下)

上一篇对.NET中的泛型进行了详细的介绍以及使用泛型的好处是什么,这篇将更加深入的去了解泛型的其他的知识点,重头戏. 【1】泛型方法 上一篇我们也说过了,泛型可以是类,结构,接口,在这些泛型类型中定义的方法都可以叫做泛型方法,都可以引用由泛型类型本身指定的一个类型参数例如…

spark集群使用hanlp进行分布式分词操作说明

本篇分享一个使用hanlp分词的操作小案例,即在spark集群中使用hanlp完成分布式分词的操作,文章整理自【qq_33872191】的博客,感谢分享!以下为全文:分两步:第一步:实现hankcs.hanlp/corpus.io.IIO…

让VirtualBox的虚拟机器在电脑开机时自动启动

当你安装很多套Virtualbox的虚拟机器系统后,希望能在开机后自动启动虚拟机器的系统。 Linux (Host OS):在你的/etc/rc.local中加入下列几行VBoxVRDP -startvm WinXP & VBoxVRDP -startvm Win2003 & VBoxVRDP -startvm LinuxFC6 & Windows (Host OS): 开…

L1-025 正整数A+B

不确定的点: 1.数据用什么类型输入,如果用字符串类型输入,怎么判断它是不是正整数 2.怎么判断哪部分是A,哪部分是B 解析 c语言’\0’ 意思: 字符常量占一个字节的内存空间。字符串常量占的内存字节数等于字符串中字节…

制作显示欢迎信息的脚本程序

终端程序恐怕是Linux用户使用最为频繁的了。我的Debian系统启动后便是直接进入的终端界面。为了在每次登录时或者是在X视窗环境下打开终端程序时显示一些欢迎信息,比如当前的日期、名人警句等,从而可以增加一些生活情趣,就可以创建一个脚本程…

文章分页浏览(二)

分页的方法: View Code publicstringOutputBySize(stringp_strContent, stringbType) { stringm_strRet ""; intm_intPageSize 500;//文章每页大小 intm_intCurrentPage 1;//设置第一页为初始页 intm_intTotalPage 0; intm_intArticlelengt…

云计算时代,如何选择适合自己的云服务器厂商?

据百科定义,云服务器是一种处理能力可弹性伸缩的计算服务,帮助您快速构建更稳定、安全的应用,降低开发运维的难度和整体IT成本,使您能够更专注于核心业务的创新。云服务器相对传统服务器有些优势:按国内市场上云服务器…

解决mysql建立的数据库名字不能带大写字母

1、在安装目录下,找到 my.ini文件 2、找到 [mysqId]节点 3、在它下面添加 lower_case_table_names2如果设置为0的话,我的Mysql服务不能重启 4、重启Mysql 直接手动重启即可,在服务中,找到Mysql服务,先停止&#xff0c…

CSS position财产

CSS在position位置信息要素用于表示属性。 有三个起飞值:static, absolute, relative。假设元件不显式配置position财产,该元素默认position 值至static。 1、static:这是表示该元素依照排列和嵌套的顺序和规则应该在的位置,此时设…

通过产品ID得到collection!!!

You can do as following for filtering products id 10 and 12$products->addAttributeToFilter(entity_id, array(in>array(10,12)));当然这种方式的上面,必须用 ->addAttributeToSelect();下面这种方式比较实用的,如果想按照名字排序&#…

jupyter notebook出现cannot import name 'create_prompt_application'问题(Died Kernel)

应该是在安装其它python第三方库时更新了prompt-toolkit版本,降级到下面的版本即可: sudo pip install prompt-toolkit1.0.15 转载于:https://www.cnblogs.com/darklights/p/10302706.html

导入sql时出现Invalid default value for ‘create_time‘报错处理方法

(上图是初始的sql文件的内容) 在开发微信小程序时,需要导入.sql文件,但是最一开始导入的时候没有任何改动进行了导入,报错如下 PS E:\weichatApp\my-project\server> node tools/initdb.js 开始初始化数据库... 准…

Python相关机器学习

Python机器学习库 Python的机器学习库汇总与梳理 机器学习之开源库大总结 转载于:https://www.cnblogs.com/SFMing/p/4590261.html

Django 图片上传upload_to路径指定失效的问题记录

为什么80%的码农都做不了架构师?>>> 初始方法一: 疑虑:model使用upload_to自定义路径方法失效,指定路径也失效。最后以Views中指定MEDIA_URL和MEDIA_ROOT做拼接,并且自行判断并建立文件夹,手动…

javascript tab切换类LixTabs最新版

javascript Tab切换类LixTabs,更新至0.5版: 受snandy的“读jquery”系列的启发,改进了代码,现在调用LixTabs时不用加new了。即可以这样写:var tab Tabs();把原来的参数evt,改成了易理解的event(我的疏忽)总代码量&…

linux虚拟机文件挂载

把U盘中的文件上传到linux虚拟机中,可以采用挂载的方式。 (1)启动虚拟机 (2)把U盘插入电脑中 (3)输入命令 fdisk -l可以查看新的分区 (4) cd /mnt mkdir usb mount /d…

HDU 1757 A Simple Math Problem

Problem Description Lele now is thinking about a simple function f(x).If x < 10 f(x) x.If x > 10 f(x) a0 * f(x-1) a1 * f(x-2) a2 * f(x-3) …… a9 * f(x-10);And ai(0<i<9) can only be 0 or 1 .Now, I will give a0 ~ a9 and two positive intege…

mariadb 内存占用优化

本文由云社区发表 作者&#xff1a;工程师小熊 摘要&#xff1a;我们在使用mariadb的时候发现有时候不能启动起来&#xff0c;在使用过程中mariadb占用的内存很大&#xff0c;在这里学习下mariadb与内存相关的配置项&#xff0c;对mariadb进行调优。 查询最高内存占用 使用以下…

windows程序设计之对话框简介1

这里先介绍下wParam和lParam&#xff0c;对于鼠标而言&#xff0c;LOWORD(wParam)和HIWORD(wParam)代表鼠标位置x,y坐标&#xff0c;对于菜单和控件而言&#xff0c;两者wParam的低字节都是各自的ID&#xff0c;即LOWORD(wParam)都是ID。两者的高字节对菜单而言是0&#xff0c;…

linux虚拟机下安装Tomcat

&#xff08;1&#xff09;首先通过挂载的方式把 tomcat的安装包从U盘上传到虚拟机中 我上传的路径是 &#xff1a;usr/tomcat &#xff08;2&#xff09; cd /usr/tomcat tar xzvf 压缩包的名字 ##进行解压&#xff08;3&#xff09;进到tomcat安装目录下的bin文件夹 ./…