套接字的多种可选项(修改IO缓冲区大小及TCP_NODELAY)

2024-01-28 13:52

本文主要是介绍套接字的多种可选项(修改IO缓冲区大小及TCP_NODELAY),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

标题套接字的多种可选项

我们进行套接字编程时往往只关注数据通信,而忽略了套接字具有的不同特性。但是,理解这些特性并根据实际需要进行更改也十分重要。
在这里插入图片描述
从上表可以看出,套接字可选项是分层的。IPPROTOIP层可选项是IP协议相关事项,IPPROTO_TCP层可选项是TCP协议相关的事项,SOL_SOCKET层是套接字相关的通用可选项。

我们几乎可以针对上表中的所有可选项进行读取(Get)和设置(Set)(当然,有些可选项只能进行一种操作)。可选项的读取和设置通过如下2个函数完成。

#include<sys/socket.h>
#include<sys/socket.h>int getsockopt(int sock, int level,int optname, void *optval, socklen_t *optlen);int setsockopt(int sock, int level, int optname, const void*optval, socklen_t optlen);

查看设置I/O缓冲大小以及查看SO_TYPE

void demo() {int tcp_sock, udp_sock;int optval = 0;socklen_t len = sizeof(optval);tcp_sock = socket(PF_INET, SOCK_STREAM, 0);udp_sock = socket(PF_INET, SOCK_DGRAM, 0);std::cout << "tcp_sock:" << SOCK_STREAM << std::endl;std::cout << "udp_sock:" << SOCK_DGRAM << std::endl;// 查看SO_TYPEgetsockopt(tcp_sock, SOL_SOCKET, SO_TYPE, (void*)&optval, &len);std::cout << "tcp_sock type:" << optval << std::endl;optval = 0;getsockopt(udp_sock, SOL_SOCKET, SO_TYPE, (void*)&optval, &len);std::cout << "udp_sock type:" << optval << std::endl;//查看\设置缓冲区getsockopt(tcp_sock, SOL_SOCKET, SO_SNDBUF, (void*)&optval, &len);std::cout << "tcp_sock buffer:" << optval << std::endl;optval = 1024 * 1024;setsockopt(tcp_sock, SOL_SOCKET, SO_SNDBUF, (void*)&optval, len);getsockopt(tcp_sock, SOL_SOCKET, SO_SNDBUF, (void*)&optval, &len);std::cout << "after set tcp_sock buffer:" << optval << std::endl;close(udp_sock);close(tcp_sock);
}

TCP_NODELAY

“什么是Nagle算法?使用该算法能够获得哪些数据通信特性?”

Nagle算法是以他的发明人John Nagle的名字命名的,它用于自动连接许多的小缓冲器消息;这一过程(称为nagling)通过减少必须发送包的个数来增加网络软件系统的效率。
在这里插入图片描述
从上图中可以得到如下结论:
“只有收到前一数据的ACK消息时,Nagle算法才发送下一数据。”

TCP套接字默认使用Nagle算法交换数据,因此最大限度地进行缓冲,直到收到ACK。上图左侧正是这种情况。为了发送字符串"Nagle",将其传递到输出缓冲。这时头字符"N"之前没有其他数据(没有需接收的ACK),因此立即传输。之后开始等待字符"N"的ACK消息,等待过程中,剩下的"agle"填入输出缓冲。接下来,收到字符"N"的ACK消息后,将输出缓冲的"agle"装入一个数据包发送。也就是说,共需传递4个数据包以传输1个字符串。

接下来分析未使用Nagle算法时发送字符串"Nagle"的过程。假设字符"N"到"e"依序传到输出缓冲。此时的发送过程与ACK接收与否无关,因此数据到达输出缓冲后将立即被发送出去。从上图右侧可以看到,发送字符串"Nagle"时共需10个数据包。由此可知,不使用Nagle算法将对网络流量产生负面影响。即使只传输1个字节的数据,其头信息都有可能是几十个字节。因此,为了提高网络传输效率,必须使用Nagle算法。

在程序中将字符串传给输出缓冲时并不是逐字传递的,故发送字符串"Nagle"的实际情况并非如上图 所示。但如果隔一段时间再把构成字符串的字符传到输出缓冲(如果存在此类数据传递)的话,则有可能产生类似上图的情况。上图中就是隔一段时间向输出缓冲传递待发送数据的。

但Nagle算法并不是什么时候都适用。根据传输数据的特性,网络流量未受太大影响时,不使用Nagle算法要比使用它时传输速度快。最典型的是"传输大文件数据"。将文件数据传入输出缓冲不会花太多时间,因此,即便不使用Nagle算法,也会在装满输出缓冲时传输数据包。这不仅不会增加数据包的数量,反而会在无需等待ACK的前提下连续传输,因此可以大大提高传输速度。
一般情况下,不适用Nagle算法可以提高传输速度。但如果无条件放弃使用Nagle算法,就会增加过多的网络流量,反而会影响传输。因此,未准确判断数据特性时不应禁用Nagle算法。

刚才说过的"大文件数据"应禁用Nagle算法。换言之,如果有必要,就应禁用Nagle算法。"Nagle算法使用与否在网络流量上差别不大,使用Nagle算法的传输速度更慢"禁用方法非常简单。
从下列代码也可看出,只需将套接字可选项TCP_NODELAY改为1(真)即可。

演示代码

int opt_val=1;
setsockopt(sock, IPPROTO_TCP,TCP_NODELAY,(void*)&opt_val, sizeof(opt_val));//可以通过TCP_NODELAY的值查看Nagle算法的设置状态。
int opt_val;socklen_t opt_len;
opt_len=sizeof(opt_val);
getsockopt(sock,IPPROTO_TCP,TCP_NODELAY,(void*)&opt_val,&opt_len);

这篇关于套接字的多种可选项(修改IO缓冲区大小及TCP_NODELAY)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

如何解决Druid线程池Cause:java.sql.SQLRecoverableException:IO错误:Socket read timed out的问题

《如何解决Druid线程池Cause:java.sql.SQLRecoverableException:IO错误:Socketreadtimedout的问题》:本文主要介绍解决Druid线程... 目录异常信息触发场景找到版本发布更新的说明从版本更新信息可以看到该默认逻辑已经去除总结异常信息触发场景复

Python函数返回多个值的多种方法小结

《Python函数返回多个值的多种方法小结》在Python中,函数通常用于封装一段代码,使其可以重复调用,有时,我们希望一个函数能够返回多个值,Python提供了几种不同的方法来实现这一点,需要的朋友... 目录一、使用元组(Tuple):二、使用列表(list)三、使用字典(Dictionary)四、 使

使用Python获取JS加载的数据的多种实现方法

《使用Python获取JS加载的数据的多种实现方法》在当今的互联网时代,网页数据的动态加载已经成为一种常见的技术手段,许多现代网站通过JavaScript(JS)动态加载内容,这使得传统的静态网页爬取... 目录引言一、动态 网页与js加载数据的原理二、python爬取JS加载数据的方法(一)分析网络请求1

SpringBoot项目Web拦截器使用的多种方式

《SpringBoot项目Web拦截器使用的多种方式》在SpringBoot应用中,Web拦截器(Interceptor)是一种用于在请求处理的不同阶段执行自定义逻辑的机制,下面给大家介绍Sprin... 目录一、实现 HandlerInterceptor 接口1、创建HandlerInterceptor实

Nginx 413修改上传文件大小限制的方法详解

《Nginx413修改上传文件大小限制的方法详解》在使用Nginx作为Web服务器时,有时会遇到客户端尝试上传大文件时返回​​413RequestEntityTooLarge​​... 目录1. 理解 ​​413 Request Entity Too Large​​ 错误2. 修改 Nginx 配置2.1

电脑提示Winmm.dll缺失怎么办? Winmm.dll文件丢失的多种修复技巧

《电脑提示Winmm.dll缺失怎么办?Winmm.dll文件丢失的多种修复技巧》有时电脑会出现无法启动程序,因为计算机中丢失winmm.dll的情况,其实,winmm.dll丢失是一个比较常见的问... 在大部分情况下出现我们运行或安装软件,游戏出现提示丢失某些DLL文件或OCX文件的原因可能是原始安装包

Python对PDF书签进行添加,修改提取和删除操作

《Python对PDF书签进行添加,修改提取和删除操作》PDF书签是PDF文件中的导航工具,通常包含一个标题和一个跳转位置,本教程将详细介绍如何使用Python对PDF文件中的书签进行操作... 目录简介使用工具python 向 PDF 添加书签添加书签添加嵌套书签Python 修改 PDF 书签Pytho

Python文件操作与IO流的使用方式

《Python文件操作与IO流的使用方式》:本文主要介绍Python文件操作与IO流的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、python文件操作基础1. 打开文件2. 关闭文件二、文件读写操作1.www.chinasem.cn 读取文件2. 写

SpringBoot快速搭建TCP服务端和客户端全过程

《SpringBoot快速搭建TCP服务端和客户端全过程》:本文主要介绍SpringBoot快速搭建TCP服务端和客户端全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录TCPServerTCPClient总结由于工作需要,研究了SpringBoot搭建TCP通信的过程

python获取网页表格的多种方法汇总

《python获取网页表格的多种方法汇总》我们在网页上看到很多的表格,如果要获取里面的数据或者转化成其他格式,就需要将表格获取下来并进行整理,在Python中,获取网页表格的方法有多种,下面就跟随小编... 目录1. 使用Pandas的read_html2. 使用BeautifulSoup和pandas3.