TCP选项:TCP_NODELAY和TCP_CORK

From: http://blog.163.com/zhangjie_0303/blog/static/990827062012718316231/

 

Nagle算法 TCP_NODELAY和TCP_CORK

Nagle算法
根据创建者John Nagle命名。该算法用于对缓冲区内的一定数量的消息进行自动连接。该处理过程

(称为Nagling),通过减少必须发送的封包的数量,提高了网络应用 程序系统的效率。Nagle算法

,由Ford Aerospace And Communications Corporation Congestion Control in IP/TCP

internetworks(IETF RFC 896)(1984)定义,最初是用于缓冲Ford的私有TCP/IP网络拥塞情况,不

过被广泛传播开来。

Nagle的文档定义了一种他称之为小封包问题的解决方法。当某个应用程序每次只产生一字节的数

据,就会导致网络由于这样的小封包而过载(该情况通 常被称为“发送端SB窗口并发症”),从

而产生该问题。一个源自键盘的单一字符-1字节的数据-可能导致一个41字节的封包被传送,该

封包包含了1字节的 有用数据和40字节的头部数据。这种4000%过载的情况,在像APRANET这样只有

很轻负载的网络中是可以接受的,但在像Ford这样的负载很重的网 络中,可能强制重传,导致封

包丢失,并且通过过度拥挤交换节点和网关降低了传播速度。更进一步,当连接被丢弃时,吞吐量

可能被降低。Nagle算法-通常 的实现方法是在一个TCP程序中插入两行代码-在发送方,对标识

为没有回应的数据进行缓冲(存储)(这句怪怪的,其实应该是对未发送数据按顺序进行缓冲,在

发送时进行拼接)。顺序发送的数据将被保持到接收到被标识数据的回应或者一整包有价值的数据

需要被发送。

虽然Nagle算法用于解决Ford网络内产生的问题,但同样的问题也出现在APRANet。通过网络,

Nagling被广泛实现,包括 internet,并且产生了巨大的效用-虽然某些时候在高交互性环境如一

些C/S情况下不希望进行该处理。在这种情况下,可以通过 TCP_NODELAY套接字选项关闭Nagling。

注:Nagle虽然解决了小封包问题,但也导致了较高的不可预测的延迟,同时降低了吞吐量。


实际上这就的你动手来自己实现以下Nagle算法了。实际上Nagle算法并不是很复杂,他的主要职责

是数据的累积,实际上有两个门槛:一个就是缓 冲区中的字节数达到了一定量,另一个就是等待

了一定的时间(一般的Nagle算法都是等待200ms);这两个门槛的任何一个达到都必须发送数据了

。一般 情况下,如果数据流量很大,第二个条件是永远不会起作用的,但当发送小的数据包时,

第二个门槛就发挥作用了,防止数据被无限的缓存在缓冲区不是好事情哦。 了解了TCP的Nagle算

法的原理之后我们可以自己动手来实现一个类似的算法了,在动手之前我们还要记住一个重要的事

情,也是我们动手实现Nagle算 法的主要动机就是我想要紧急发送数据的时候就要发送了,所以对

于上面的两个门槛之外还的增加一个门槛就是紧急数据发送。现在可以开始工作了,我们这里主要

给出思路:

首先我们必须在SOCKET之上再建立一层,来定义我们的自己的传输控制,我们的Nagle算法也是在

这层里面实现的。 
Disable哪个TCP的Nagle算法,都自己动手写了,要它干吗 
使 用Select函数来查看是否可以发送数据,当然我们实质是否可写的fd_set的时候需要加入我们

的三个门槛,首先是按照字节和紧急数据来检查,一般情 况下这两个条件就搞定了,然后再按照

时间来决定。我们可是使用一个累积字节记数器和一个等待时间计时器。累积字节记数器在每次添

加数据到我们的控制层的时 候就累加一下,发送完毕的时候减去响应的字节数;而计时器在第一

次将数据提交给控制层的时候启动(可以使用Windows的GetTickcount来得 到当前的时间),然后

在每次发送数据完毕的时候重新复位一下。 
实际上这样就已经实现了Nagle算法,而且不需要经常调用GetTickCount而降低了系统的性能。

TCP_CORK

TCP链接的过程中,默认开启Nagle算法,进行小包发送的优化。优化网络传输,兼顾网络延时和网

络拥塞。这个时候可以置位TCP_NODELAY关闭Nagle算法,有数据包的话直接发送保证网络时效性。

在进行大量数据发送的时候可以置位TCP_CORK关闭Nagle算法保证网络利用性。尽可能的进行数据

的组包,以最大mtu传输,如果发送的数据包大小过小则如果在0.6~0.8S范围内都没能组装成一个

MTU时,直接发送。如果发送的数据包大小足够间隔在0.45内时,每次组装一个MTU进行发送。如果

间隔大于0.4~0.8S则,每过来一个数据包就直接发送。


下面摘自:http://blog.csdn.net/lin49940/archive/2009/07/26/4382303.aspx
TCP_NODELAY 选项

设置该选项: public void setTcpNoDelay(boolean on) throws SocketException 
读取该选项: public boolean getTcpNoDelay() throws SocketException 
     默认情况下, 发送数据采用Negale 算法. Negale 算法是指发送方发送的数据不会立即发出,

而是先放在缓冲区, 等缓存区满了再发出. 发送完一批数据后, 会等待接收方对这批数据的回应,

然后再发送下一批数据. Negale 算法适用于发送方需要发送大批量数据, 并且接收方会及时作出

回应的场合, 这种算法通过减少传输数据的次数来提高通信效率.

     如果发送方持续地发送小批量的数据, 并且接收方不一定会立即发送响应数据, 那么Negale

算法会使发送方运行很慢. 对于GUI 程序, 如网络游戏程序(服务器需要实时跟踪客户端鼠标的移

动), 这个问题尤其突出. 客户端鼠标位置改动的信息需要实时发送到服务器上, 由于Negale 算法

采用缓冲, 大大减低了实时响应速度, 导致客户程序运行很慢.


下面摘自http://hi.baidu.com/dirlt/blog/item/5ea4be1795d30b03c83d6d7f.html

TCP_NODELAY和TCP_CORK

这里了解一下问题的背景就好理解了[不考虑滑动窗口加入,只是说packet的组织]
1.历史上TCP是每发送一次包等待一个ACK然后下一个

2.但是在一些交互式应用下比如Telnet,结果就是我们每按一次键就会发送一个packet.每一个字

符配一个TCP头效率不高,那个Nagle算法出来了。发送方法送数据A时然后再等待接受方的ACK时,

积累本地收集到的所有TCP数据包然后一次性发送。但是很明显Nagle算法不利于交互式情景

3.但是现代应用下面还是存在交互式应用的,所以有时候我们需要关闭Nagle那么可以设置

TCP_NODELAY

4.但是Nagle组织包的长度是由系统决定的,有时候我们知道我们会每个1分钟产生1字节,共1000

字节。如果完全由Nagle算法来发送的话,可能还是会1字节1字节发送[这是一种极端情况,假设返

回ACK时间不是很长]。这个时候首先设置TCP_CORK能够阻塞住TCP[尽量阻塞住],等我们write完

1000字节之后,取消TCP_CORK,这个时候就能够将1000字节一次发出
TCP_NODELAY和TCP_CORK都是禁用Nagle算法,只不过NODELAY完全关闭而TCP_CORK完全由自己决定

发送时机。Linux文档上说两者不要同时设置。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/403764.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

loop 伪设备 挂在文件系统

dd if/dev/zero of./test.img bs1M count512 losetip /dev/loop1 test.img mkfs.ext3 -L ingben /dev/loop1 dumpe2fs /dev/loop1 tune2fs -l /dev/loo1 mount /dev/loop1 /mnt hexdump -C /dev/loop1 > /dumptext.log1

mysql导入导出数据

用以下命令,导入导出Mysql几百M,几G的数据库都没有问题。注意“--default-character-setutf8”是设置编码的。 1,数据库备份命令: mysqldump -h localhost -u root -p --default-character-setutf8 dbname >backup.sq…

修改复选框样式

//默认input[type"checkbox"] {margin-top: 7px;cursor: pointer;position: relative;width: 14px;height: 14px;font-size: 14px;margin-right: 8px;background-color:#fff;}//选中后修改input[type"checkbox"]::after {position: absolute;top: 0;//修改…

java jni ubuntu 环境搭建时遇到的坑

1:版本不一致遇到的坑 javah的版本需要同javac的版本一致。如果版本的问题搞不定,直接用andorid source build之后的环境即可 2:javah使用遇到的坑 jni中字段描述符可以使用javah生成 javah -jni -classpath . JNIdemo 其中 -classpath…

linux 内核配置过程中遇到的问题

大家都知道在修改内核需要两步 配置和编译 在配置过程中 用到的命令 make config、make menuconfig、make xconfig 前两个是文本界面 最后一个是图形界面 不建议用最后一个 因为占用的资源太多 有点卡 但如果你的硬件配置极高 我也不否定 你来用 转入正题 我在配置时 make menu…

c如何返回数组给java

jintArray c_hello(JNIEnv *env, jobject cls, jintArray arr) { jint a[4]{12,13,14,15}; jintArray arry; arry (*env)->NewIntArray(env,4); (*env)->SetIntArrayRegion(env,arry,0,4,a); return arry; } 实际上也…

JNDI的XML相关配置(context.xml和web.xml)

1. 在tomcat目录下conf/context.xml文件中 加入一下代码   <Resource name"jdbc/sqlconnpool" auth"Container" type"javax.sql.DataSource" driverClassName"com.microsoft.sqlserver.jdbc.SQLServerDriver" …

Vue 作用域插槽

原博出处&#xff1a; 作者&#xff1a;SentMes 链接&#xff1a;SentMes作者书写的作用于插槽链接 https://www.jianshu.com/p/0c9516a3be80 来源&#xff1a;简书 ** ** ** 十分感谢原作者&#xff0c;写的十分详细&#xff0c;原作者辛苦了&#xff01; 深入理解vue中的s…

nuc972的ramfs的配置yaffs2,ubi文件系统

按照技术支持的推荐&#xff0c;使用ramfs文件系统。那么就可以在uboot的nuc970_evb.h中将JEFS yaffs ubi 的相关支持去掉就可以了。这样理应能减少很大部分的uboot大小。剩下就是配置内核中的ramfs配置。 General setup ---> [ ] Initial RAM filesystem and RAM disk (i…

I/O多路复用之epoll

2019独角兽企业重金招聘Python工程师标准>>> 在上一章&#xff0c;我们对select进行了大致的描述&#xff0c;知道了它相对传统的阻塞式服务提高了并发度&#xff0c;但是它也由于轮询而导致效率底下。本文对epoll进行讲解&#xff0c;相比select它的并发度更高&…

关于24点游戏的编程思路与基本算法

From: http://blog.csdn.net/wangqiulin123456/article/details/8145545 24点游戏的算法&#xff0c;其中最主要的思想就是穷举法。所谓穷举法就是列出4个数字加减乘除的各种可能性&#xff0c;包括括号的算法。我们可以将表达式分成以下几种&#xff1a;首先我们将4个数设为a…

Xtreme TaskPanel

原文来自方案网 http://www.fanganwang.com/Product-detail-item-1230.html&#xff0c;欢迎转载。 关键字&#xff1a;TaskPanel Codejock Xtreme TaskPanel为Windows开发者提供了一个非常熟悉的任务栏&#xff0c;与Windows资源管理器类似。该任务面板可以像VS.NET工具一样被…

linux设备驱动之按键外部中断

老习惯先贴一波代码再仔细分析消化。 #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/delay.h> #include <linux/irq.h> #include <asm/uaccess.h> #includ…

C语言实现ICMP协议Ping命令

From: http://www.360doc.com/content/12/0429/19/1317564_207540510.shtml 大部分人用ping命令只是作为查看另一个系统的网络连接是否正常的一种简单方法。在这篇文章中&#xff0c;作者将介绍如何用C语言编写一个模拟ping命令功能的程序。ping命令是用来查看网络上另一个主机…

Ubuntu 时间同步

1. 安装ntpdate工具# sudo apt-get install ntpdate2. 设置系统时间与网络时间同步# ntpdate cn.pool.ntp.org

vscode tab键快捷生成元素html标签

按照上图在设置中找到对应的文件夹&#xff0c; 直接加上"emmet.triggerExpansionOnTab": true,这段代码保存 重新打开vscode即可

Linux用ICMP协议实现简单Ping网络监测功能

From: http://www.linuxidc.com/Linux/2012-05/61073.htm ICMP是&#xff08;Internet Control Message Protocol&#xff09;Internet控制报文协议。它是TCP/IP协议族的一个子协议&#xff0c;用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路…

解决vscode格式化代码html属性换行问题; ctrl+s格式化去除分号,格式化自动单引号;解决js格式化换行问题;mac上的settings.json完整配置

右键格式化文档或者ctrl s保存 html不换行 1.安装两个插件①vetur ②Prettier - Code formatter 2.在vetur的settings.json中设置 配置ctrls触发格式化去除分号和单引号&#xff1b;配置格式化js换行&#xff1b;配置解决html属性换行 将最后一部分的设置&#xff0c;修改…

微信分享接口

看着微信分享的 demo 好纠结啊。。。不知道怎么去触发他。哪位大神可以指点一下。。。点击按钮弹出分享js不太懂。。搞了半天也没搞出来。。请教大家。wx.ready(function () {wx.onMenuShareTimeline({title: window.shareData.tTitle,link: window.shareData.timeLineLink,img…