写socket发现的一个诡异现象,当时将多个小数据写操作合并成一个写操作,问题就没了。Chenshuo同学还建议我设置TCP_NODELAY,只是后来因为事情忙,也就没有再深究下去。

现在大概明白,是由于nagle算法在捣乱。
TCP/IP协议中,无论发送多少数据,总是要在数据前面加上协议头,同时,对方接收到数据,也需要发送ACK表示确认。为了尽可能的利用网络带宽,TCP总是希望尽可能的发送足够大的数据。(一个连接会设置MSS参数,因此,TCP/IP希望每次都能够以MSS尺寸的数据块来发送数据)。
Nagle算法就是为了尽可能发送大块数据,避免网络中充斥着许多小数据块。

Nagle算法的基本定义是任意时刻,最多只能有一个未被确认的小段。 所谓“小段”,指的是小于MSS尺寸的数据块,所谓“未被确认”,是指一个数据块发送出去后,没有收到对方发送的ACK确认该数据已收到。

举个例子,比如之前的blog中的实验,一开始client端调用socket的write操作将一个int型数据(称为A块)写入到网络中,由于此时连接是空闲的(也就是说还没有未被确认的小段),因此这个int型数据会被马上发送到server端,接着,client端又调用write操作写入‘/r/n’(简称B块),这个时候,A块的ACK没有返回,所以可以认为已经存在了一个未被确认的小段,所以B块没有立即被发送,一直等待A块的ACK收到(大概40ms之后),B块才被发送。整个过程如图所示:

这里还隐藏了一个问题,就是A块数据的ACK为什么40ms之后才收到?这是因为TCP/IP中不仅仅有nagle算法,还有一个ACK延迟机制 。当Server端收到数据之后,它并不会马上向client端发送ACK,而是会将ACK的发送延迟一段时间(假设为t),它希望在t时间内server端会向client端发送应答数据,这样ACK就能够和应答数据一起发送,就像是应答数据捎带着ACK过去。在我之前的时间中,t大概就是40ms。这就解释了为什么'/r/n'(B块)总是在A块之后40ms才发出。

如果你觉着nagle算法太捣乱了,那么可以通过设置TCP_NODELAY将其禁用 。当然,更合理的方案还是应该使用一次大数据的写操作,而不是多次小数据的写操作。

from: http://blog.csdn.net/historyasamirror/article/details/6423235

nagle算法和TCP_NODELAY的更多相关文章

  1. TCP/IP具体解释--nagle算法和TCP_NODELAY

    在client一直给server发送小数据的时候,接受到一个回应会在非常长的时间以后,可是将多个小数据写操作合并成一个写操作,问题就没了. 这个事件的缘由可能是TCP_NODELAY的原因 如今大概明 ...

  2. TCP_NODELAY和TCP_CORK nagle算法和cork算法

    TCP_NODELAY 默认情况下,发送数据採用Nagle 算法.这样尽管提高了网络吞吐量,可是实时性却减少了,在一些交互性非常强的应用程序来说是不同意的.使用TCP_NODELAY选项能够禁止Nag ...

  3. 最小生成树---Prim算法和Kruskal算法

    Prim算法 1.概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (gra ...

  4. 经典算法和OJ网站(开发者必备-转)

    一. Online Judge简介: Online Judge系统(简称OJ)是一个在线的判题系统.用户可以在线提交程序多种程序(如C.C++.Pascal)源代码,系统对源代码进行编译和执行,并通过 ...

  5. BM算法和Sunday快速字符串匹配算法

    BM算法研究了很久了,说实话BM算法的资料还是比较少的,之前找了个资料看了,还是觉得有点生涩难懂,找了篇更好的和算法更好的,总算是把BM算法搞懂了. 1977年,Robert S.Boyer和J St ...

  6. 台球游戏的核心算法和AI(2)

    前言: 最近研究了box2dweb, 觉得自己编写Html5版台球游戏的时机已然成熟. 这也算是圆自己的一个愿望, 一个梦想. 承接该序列的相关博文: • 台球游戏核心算法和AI(1) 同时结合htm ...

  7. mahout中kmeans算法和Canopy算法实现原理

    本文讲一下mahout中kmeans算法和Canopy算法实现原理. 一. Kmeans是一个很经典的聚类算法,我想大家都非常熟悉.虽然算法较为简单,在实际应用中却可以有不错的效果:其算法原理也决定了 ...

  8. 使用Apriori算法和FP-growth算法进行关联分析

    系列文章:<机器学习实战>学习笔记 最近看了<机器学习实战>中的第11章(使用Apriori算法进行关联分析)和第12章(使用FP-growth算法来高效发现频繁项集).正如章 ...

  9. 转载:最小生成树-Prim算法和Kruskal算法

    本文摘自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html 最小生成树-Prim算法和Kruskal算法 Prim算 ...

随机推荐

  1. Linux中断处理(一)

    最近在研究异步消息处理, 突然想起linux内核的中断处理, 里面由始至终都贯穿着"重要的事马上做, 不重要的事推后做"的异步处理思想. 于是整理一下~~第一阶段--获取中断号每个 ...

  2. 解决Android SDK下载和更新失败问题

    今天更新sdk报错如下: Failed to fetch URL http://dl-ssl.google.com/android/repository/addons_list-1.xml. 说dl- ...

  3. app中页面滑动,防止a链接误触

    问题 app中list列表,当我们用手滑动屏幕,屏幕上页面内容会快速滚动,不会因为手已经离开了屏幕而滚动停止,突然手触摸暂停,当手指是在a标签上面时,会跳转链接,这对客户体验及其不好 思路 先判断滚动 ...

  4. cf Queries on a String

    #include<iostream> #include<cstring> #include<cstdio> using namespace std; #define ...

  5. List遍历三种方法:1.for 2.增强性for 3.迭代器

    package chapter09; import java.util.ArrayList;import java.util.Iterator;import java.util.List; /* * ...

  6. ruby学习-字符串

    字符串 1.创建字符1:new用来创建新字符,empty?检验字符是否为空 title = String.new #=> "" title.empty? #=>true ...

  7. 关于jsp页面到页面传值

    很久没用这种传值了,一般都是一个.do请求到后台在跳转到前端:像有些只是展示数据功能,这样做就显得没有必要,闲话不说了,记录下来供下次参考. 用的是html的a标签,我这里只用这2种用法. 场景如下图 ...

  8. 《剑指offer》-二叉搜索树与双向链表

    输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 题目的描述不是很习惯.题目的意思是把二叉树从左到右遍历,相当于双向链表的遍历. 其实 ...

  9. .NetCore下利用Jenkins如何将程序自动打包发布到Docker容器中运行

    说道这一块纠结了我两天时间,感觉真的很心累,Jenkins的安装就不多说了 这里我们最好直接安装到宿主机上,应该pull到的jenkins版本是2.6的,里面很多都不支持,我自己试了在容器中安装的情况 ...

  10. python算法双指针问题:两个有序数组的合并

    最近在看<你也能看得懂的python算法书>, 自己来实现一下里面的算法吧. 有书里的有所不同. 比如这个题目,我的实现如下: from django.test import TestCa ...