套接字的多种可选项(修改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);

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

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

相关文章

【JavaSE篇】——数组的定义与使用

目录 本章的目标&#xff1a; &#x1f388;数组的基本概念 &#x1f36d;创建数组 &#x1f36d;数组的初始化 &#x1f36d;数组的使用 &#x1f449;数组中元素访问 &#x1f449;遍历数组 &#x1f388;数组是引用类型 &#x1f36d;初始JVM的内存分布 &#x1f…

2024017期传足14场胜负前瞻

2024017期赛事由亚洲杯2场、英总杯2场、德甲2场、意甲4场、西甲4场组成。售止时间为1月28日&#xff08;周日&#xff09;19点00分&#xff0c;敬请留意&#xff1a; 本期深盘场次同样适中&#xff0c;1.5以下赔率3场&#xff0c;1.5-2.0赔率6场&#xff0c;其他场次基本皆是平…

Java复习系列之阶段二:数据库

1. 基础语法 1.1 DQL&#xff08;数据查询语句&#xff09; 执行顺序&#xff1a; from、join 、on、where、group by、having、select、distinct、order by、limit 1.2 DML&#xff08;数据修改语言&#xff09; 对数据表的增删改 insert into update set delete form 1.…

javax.servlet.http包

javax.servlet.http包 javax.srvlet.http包是对javax.servlet包的扩展。该包的类和接口处理使用HTTP进行通信的servlet。这些servlet也称为HTTP Servlet。您需要扩展HttpServlet类来开发HTTP Servlet。javax.servlet.http包经常使用的接口包括: HttpServletRequest接口HttpSe…

Java 基础 - 反射

Java 基础 - 反射 文章目录 Java 基础 - 反射1 什么是类对象2 获取类对象的方法3 反射通用操作【重点】3.1 常见方法3.2 通用操作 4 内省 1 什么是类对象 类的对象&#xff1a;基于某个类 new 出来的对象&#xff0c;也称为实例对象。 类对象&#xff1a;类加载的产物&#x…

第9章 多线程

第9章 多线程 学习目标 了解进程和线程的区别 能够理解并发与并行的区别 能够使用继承类的方式创建多线程 能够使用实现接口的方式创建多线程 能够说出实现接口方式的好处 能够解释安全问题的出现的原因 能够使用同步代码块解决线程安全问题 能够使用同步方法解决线程安全问题…

滴水逆向三期笔记与作业——02C语言——10 Switch语句反汇编

滴水逆向三期笔记与作业——02C语言——10 Switch语句反汇编 一、Switch语句1、switch语句 是if语句的简写2、break加与不加有什么特点?default语句可以省略吗&#xff1f;3、游戏中的switch语句&#xff08;示例&#xff09;4、添加case后面的值&#xff0c;一个一个增加&…

Java笔记 --- 二、Stream流

二、Stream流 结合Lambda表达式&#xff0c;简化集合、数组的操作 获取Stream流对象 单列集合获取Stream流 双列集合获取Stream流 数组获取Stream流 一堆零散的数据获取Stream流 Stream流的静态方法of的形参是一个可变参数&#xff0c;可以传递零散数据&#xff0c;也可以传递…

记录一道ctf web题

0x00 前言 某同学发在群里一道不知道什么ctf的web题 0x01 bypass open_basedir 开始没想那么多&#xff0c;看到了可以执行phpinfo&#xff0c;直接先eval一个一句话上去看看什么情况&#xff1a; 接着发现了没有权限去读取/var/www/html以外的目录&#xff0c;那么我开始想的…

基于51单片机智能电子秤

实物显示效果&#xff1a; https://www.bilibili.com/video/BV1Wb4y1A7Aw/?vd_source6ff7cd03af95cd504b60511ef9373a1d 功能介绍&#xff1a; &#xff08;1&#xff09;用键盘设计单价&#xff1b; &#xff08;2&#xff09;称重后同时显示该物品的重量、单价和总额&…

sqlx的初体验

sqlx的介绍和优点 sqlx 是一个用于 Go 语言的数据库工具&#xff0c;它在标准库的 database/sql 包的基础上提供了一些额外的功能&#xff0c;使得数据库操作更加方便和灵活。 优点&#xff1a; 查询构建器&#xff1a; sqlx 提供了更强大的查询构建器&#xff0c;使得在 Go…

Ubuntu添加AppImage到桌面及应用程序菜单

将AppImage添加到桌面&#xff0c;以PicGo为例 效果&#xff1a; 在桌面创建PicGo.desktop文件&#xff0c;输入以下内容&#xff1a; [Desktop Entry] EncodingUTF-8 TypeApplication #应用名称 NamePicGo #图标路径 Icon/usr/local/AppImage/icons/PicGo.png #启动是否开启…