TCP_NODELAY 和 TCP_CORK,
这两个选项都对网络连接的行为具有重要的作用。许多UNIX系统都实现了TCP_NODELAY选项,但是,TCP_CORK则是Linux系统所独有的 而且相对较新;它首先在内核版本2.4上得以实现。此外,其他UNIX系统版本也有功能类似的选项,值得注意的是,在某种由BSD派生的系统上的 TCP_NOPUSH选项其实就是TCP_CORK的一部分具体实现。
TCP_NODELAY和TCP_CORK基本上控制了包的“Nagle化”,Nagle化在这里的含义是采用Nagle算法把较小的包组装为更大的帧。 John Nagle是Nagle算法的发明人,后者就是用他的名字来命名的,他在1984年首次用这种方法来尝试解决福特汽车公司的网络拥塞问题(欲了解详情请参 看IETF RFC 896)。他解决的问题就是所谓的silly window syndrome ,中文称“愚蠢窗口症候群”,具体含义是,因为普遍终端应用程序每产生一次击键操作就会发送一个包,而典型情况下一个包会拥有一个字节的数据载荷以及40 个字节长的包头,于是产生4000%的过载,很轻易地就能令网络发生拥塞,。 Nagle化后来成了一种标准并且立即在因特网上得以实现。它现在已经成为缺省配置了,但在我们看来,有些场合下把这一选项关掉也是合乎需要的。
现在让我们假设某个应用程序发出了一个请求,希望发送小块数据。我们可以选择立即发送数据或者等待产生更多的数据然后再一次发送两种策略。如果我们马上发 送数据,那么交互性的以及客户/服务器型的应用程序将极大地受益。例如,当我们正在发送一个较短的请求并且等候较大的响应时,相关过载与传输的数据总量相 比就会比较低,而且,如果请求立即发出那么响应时间也会快一些。以上操作可以通过设置套接字的TCP_NODELAY选项来完成,这样就禁用了Nagle 算法。
另外一种情况则需要我们等到数据量达到最大时才通过网络一次发送全部数据,这种数据传输方式有益于大量数据的通信性能,典型的应用就是文件服务器。应用 Nagle算法在这种情况下就会产生问题。但是,如果你正在发送大量数据,你可以设置TCP_CORK选项禁用Nagle化,其方式正好同 TCP_NODELAY相反(TCP_CORK 和 TCP_NODELAY 是互相排斥的)。下面就让我们仔细分析下其工作原理。
假设应用程序使用sendfile()函数来转移大量数据。应用协议通常要求发送某些信息来预先解释数据,这些信息其实就是报头内容。典型情况下报头很 小,而且套接字上设置了TCP_NODELAY。有报头的包将被立即传输,在某些情况下(取决于内部的包计数器),因为这个包成功地被对方收到后需要请求 对方确认。这样,大量数据的传输就会被推迟而且产生了不必要的网络流量交换。
但是,如果我们在套接字上设置了TCP_CORK(可以比喻为在管道上插入“塞子”)选项,具有报头的包就会填补大量的数据,所有的数据都根据大小自动地 通过包传输出去。当数据传输完成时,最好取消TCP_CORK 选项设置给连接“拔去塞子”以便任一部分的帧都能发送出去。这同“塞住”网络连接同等重要。
总而言之,如果你肯定能一起发送多个数据集合(例如HTTP响应的头和正文),那么我们建议你设置TCP_CORK选项,这样在这些数据之间不存在延迟。能极大地有益于WWW、FTP以及文件服务器的性能,同时也简化了你的工作。示例代码如下:
intfd, on = 1;
…
/* 此处是创建套接字等操作,出于篇幅的考虑省略*/
…
setsockopt (fd, SOL_TCP, TCP_CORK, &on, sizeof (on)); /* cork */
write (fd, …);
fprintf (fd, …);
sendfile (fd, …);
write (fd, …);
sendfile (fd, …);
…
on = 0;
setsockopt (fd, SOL_TCP, TCP_CORK, &on, sizeof (on)); /* 拔去塞子 */
不幸的是,许多常用的程序并没有考虑到以上问题。例如,Eric Allman编写的sendmail就没有对其套接字设置任何选项。
Apache HTTPD是因特网上最流行的Web服务器,它的所有套接字就都设置了TCP_NODELAY选项,而且其性能也深受大多数用户的满意。这是为什么呢?答 案就在于实现的差别之上。由BSD衍生的TCP/IP协议栈(值得注意的是FreeBSD)在这种状况下的操作就不同。当在TCP_NODELAY 模式下提交大量小数据块传输时,大量信息将按照一次write()函数调用发送一块数据的方式发送出去。然而,因为负责请求交付确认的记数器是面向字节而 非面向包(在Linux上)的,所以引入延迟的概率就降低了很多。结果仅仅和全部数据的大小有关系。而 Linux 在第一包到达之后就要求确认,FreeBSD则在进行如此操作之前会等待好几百个包。
在Linux系统上,TCP_NODELAY的效果同习惯于BSD TCP/IP协议栈的开发者所期望的效果有很大不同,而且在Linux上的Apache性能表现也会更差些。其他在Linux上频繁采用TCP_NODELAY的应用程序也有同样的问题。
分享到:
相关推荐
Nagle算法 TCP_NODELAY和TCP_CORK.zip
SO_REUSEADDR配置 & TCP_NODELAY1
NODELAY如何影响小包延时, 如何增加小包传输的实时性
Echo service using TCP sockets between two systems with socket options SO_REUSEADDR, SO_KEEPALIVE, TCP_NODELAY and SO_LINGER
client_body_timeout 3m; send_timeout 3m; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65;
ffmpeg win版,用于测试rtmp
tcp_nodelay 超时 解析器 resolver_timeout 允许 否定 访问日志 方向对齐 client_body_buffer_size lua_code_cache lua_package_path lua_package_cpath process_by_lua process_by_lua_file lua_socket_...
Nagle算法规定,一个tcp链接上最多只能有一个未被确认的小分组。 如果ack响应到达前,tcp暂时收集待发数据,等到响应ack到达后使用一个分组将待发数据发送出去。 Nagle算法启动的条件,...Tcp提供TCP_NODELAY关闭nag
#设定mime类型,类型由mime.type文件定义 ... tcp_nodelay on; #开启gzip压缩 gzip on; gzip_disable "MSIE [1-6]."; #设定请求缓冲 client_header_buffer_size 128k; large_client_header_buffers 4 128k;
* TCP_NODELAY set * Connected to localhost (127.0.0.1) port 8000 (#0) > GET / HTTP/1.1 > Host: localhost:8000 > User-Agent: curl/7.61.0 > Accept: */* , 14 Nov 2023 14:35:10 GMT Hello, Falcon!
## Wakanda软件包管理器## 要查看简单的演示,请点击此链接 ###预安装Linux(作业系统... tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; # server_tokens off; # server_names_hash_bucket_size 64
tcp_nodelay on; } } 【注】 1.项目代码均经过功能验证ok,确保稳定可靠运行。欢迎下载使用体验! 2.主要针对各个计算机相关专业,包括计算机科学、信息安全、数据科学与大数据技术、人工智能、通信、物联网等...
LwIP协议栈源码详解LwIP协议栈源码详解
TcpNoDelayMod 我的世界1.7.2、1.7.10和1.8的伪造mod,将TCP_NODELAY设置为true,而不是常规的false。 这样可以减少游戏延迟,并提供更流畅的游戏体验。 在1.8.1及更高版本中不需要此mod,因为minecraft已经进行了...
proxy-istio-demo ...* TCP_NODELAY set * Connected to localhost (::1) port 8888 (#0) > GET / HTTP/1.1 > Host: localhost:8888 > User-Agent: curl/7.64.1 > Accept: */* > < HTTP>: java < respon
默认启用TCP_NODELAY 无障碍 用法 npm i fetch-enhanced node-fetch const nodeFetch = require ( "node-fetch" ) ; const fetch = require ( "fetch-enhanced" ) ( nodeFetch ) ; await fetch ( ...
然后为这个 socket 设置 TCP_NODELAY 属性,禁用 Nagle 算法 然后创建一个可读的文件事件用于监听这个客户端 socket 的数据发送 最大连接数 在 Redis2.4 中,最大连接数是被直接硬编码在代码里面的,而在2.6版本中...
* TCP_NODELAY set * Connected to localhost (127.0.0.1) port 8000 ( # 0) > GET / ? url=https://marcusnoble.co.uk/ HTTP/1.1 > Host: localhost:8000 > User-Agent: curl/7.64.1 > Accept: * / * > < ...
警告:正在进行中入门启动zuul服务器./src/test/java/rocks/devmesh/spring/cloud/zuul/Application#main请求到'/ healthcheck'端点$ curl http://localhost:7001/healthcheck -v* Trying ::1...* TCP_NODELAY set*...
客户端设置套接字选项TCP_NODELAY=true以防止写入小消息时出现多毫秒延迟。 对 1.4.0 的更改 SDK 支持 StreamManager 客户端。 对 1.3.1 的更改 改进的日志级别粒度。 对 1.3.0 的更改 SDK 支持 SecretsMa