套接字的多种可选项

套接字可选项和I/O缓冲大小

套接字的多种可选项

套接字可选项分为 IPPROTO_IPIPPROTO_TCPSOL_SOCKET 三层,各层的含义为:
IPPROTO_IP:IP 协议相关事项;
IPPROTO_TCP:TCP 协议相关事项;
SOL_SOCKET:套接字相关的通用可选项。
下表列出了其中部分可选项,这些可选项无需立即掌握,用到什么学什么即可。
在这里插入图片描述
在这里插入图片描述

函数 - getsockopt & setsockopt

可选项的读取和设置由如下两个函数来是实现:
getsockopt & setsockopt

#include <sys/socket.h>
int getsockopt(int sock, int level, int optname, void* optval, socklen_t* optlen);
// 功能:读取套接字可选项
// 参数:sock:套接字文件描述符;level:可选项所属协议层;optname:要查看的可选项名称;
// optval:用于保存查看结果的缓冲地址;optlen:调用函数后,optlen 会保存 optval 返回的可选信息项的字节数
// 返回值:成功时返回 0,失败时返回 -1。
int setsockopt(int sock, int level, int optname, void* optval, socklen_t optlen);
// 功能:更改套接字可选项
// 参数:sock:套接字文件描述符;level:可选项所属协议层;optname:要更改的可选项名称;
// optval:保存要更改的选项信息的缓冲地址;optlen:指明参数 optval 所指对象的大小
// 返回值:成功时返回 0,失败时返回 -1。

示例:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <winsock2.h>void error_handling(char *message);int main(int argc, char *argv[]) 
{WSADATA wsaData;int tcp_sock, udp_sock;int sock_type;int optlen;int state;if(WSAStartup(MAKEWORD(2, 2), &wsaData)!=0)error_handling("WSAStartup() error!"); optlen=sizeof(sock_type);tcp_sock=socket(PF_INET, SOCK_STREAM, 0);udp_sock=socket(PF_INET, SOCK_DGRAM, 0);	printf("SOCK_STREAM: %d \n", SOCK_STREAM);printf("SOCK_DGRAM: %d \n", SOCK_DGRAM);state=getsockopt(tcp_sock, SOL_SOCKET, SO_TYPE, (void*)&sock_type, &optlen);if(state)error_handling("getsockopt() error!");printf("Socket type one: %d \n", sock_type);state=getsockopt(udp_sock, SOL_SOCKET, SO_TYPE, (void*)&sock_type, &optlen);if(state)error_handling("getsockopt() error!");printf("Socket type two: %d \n", sock_type);WSACleanup();return 0;
}void error_handling(char *message)
{fputs(message, stderr);fputc('\n', stderr);exit(1);
}

选项 - SO_SNDBUF & SO_RCVBUF

创建套接字同时将生成 I/O 缓冲
SO_SNDBUF 可选项表示输出缓冲大小相关信息,SO_RCVBUF 可选项表示输入缓冲大小相关信息。
这两个选项都是可读可写的。默认的输入输出缓冲大小可能在几万字节(几十)左右。
可以修改缓冲区大小,但是系统并不一定会完全按照我们的要求进行修改,修改结果可能会有所出入。

示例:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <winsock2.h>void error_handling(char *message);int main(int argc, char *argv[])
{WSADATA wsaData;int sock;  int snd_buf, rcv_buf, state;int len;if(WSAStartup(MAKEWORD(2, 2), &wsaData)!=0)error_handling("WSAStartup() error!"); sock=socket(PF_INET, SOCK_STREAM, 0);	len=sizeof(snd_buf);state=getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (void*)&snd_buf, &len);if(state)error_handling("getsockopt() error");len=sizeof(rcv_buf);state=getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void*)&rcv_buf, &len);if(state)error_handling("getsockopt() error");printf("Input buffer size: %d \n", rcv_buf);printf("Outupt buffer size: %d \n", snd_buf);WSACleanup();return 0;
}void error_handling(char *message)
{fputs(message, stderr);fputc('\n', stderr);exit(1);
}

选项 - SO_REUSEADDR

time-wait状态

主动结束连接的一方(先发送 FIN 消息的)会经历 time-wait 状态。

地址分配错误(bind() error)

当使用 Ctrl+C 终止服务器程序时,服务器程序成为主动终止连接的一方,会经历 time-wait 状态。这时服务器之前所用的套接字是无法立即使用的(如果立即执行会发生 bind() error),只能等几分钟再执行或修改端口号(即修改套接字)。
客户端的 time-wait 状态无需关心,因为它的端口号是动态分配的。

地址再分配

有时需要立即重启服务器程序,这可以通过更改可选项 SO_REUSEADDR 的状态来实现。
SO_REUSEADDR 的默认值为 0,将其修改为 1 即可将 time-wait 状态下的套接字端口号重新分配给新的套接字。

使用方式:

int option = 1;
setsockopt(serv_sock, SOL_SOCKET, SO_REUSEADDR, (void*)&option, sizeof(option));

选项 - TCP_NODELAY

Nagle 算法是应用于 TCP 层的一个简单算法:只有收到前一数据的 ACK 消息时,Nagle 算法才会发送下一数据。
TCP 默认使用 Nagle 算法,因此会最大限度地进行缓冲,直到收到 ACK 才将数据发送出去。
在这里插入图片描述
Nagle 算法的优点:可以避免产生大量网络流量。如果不使用 Nagle 算法,数据到达输出缓冲后立即发送出去,会产生多个体积很小的包(如上图所示),增加网络负载。
Nagle 算法的缺点:很多时候会降低传输速度。不使用 Nagle 算法时,数据无需等待 ACK 报文就可以发送出去,没有等待时间。在发送大文件数据时尤其明显。因为传输大文件数据无论是否使用 Nagle 算法都不会产生大量的小数据包,而不使用 Nagle 算法则不用等待 ACK 报文,速度更快。
应根据情况选择是否禁用 Nagle 算法。

禁用Nagle算法

可选项 TCP_NODELAY 默认为 0,表示开启 Nagle 算法,将其修改为 1 即可禁用 Nagle 算法。
禁用 Nagle 算法的方式:

int opt_val = 1;
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&opt_val, sizeof(opt_val));

可以通过 TCP_NODELAY 的值查看 Nagle 算法的设置状态。

int opt_val = 1;
int opt_len = sizeof(opt_val);
getsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&opt_val, &opt_len);

如果正在使用 Nagle 算法,opt_val 变量中会保存 0;如果已禁用 Nagle 算法,则保存 1。

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

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

相关文章

苍穹外卖-day09

用户端历史订单模块 1. 查询历史订单 1.1 需求分析和设计 产品原型&#xff1a; 业务规则 分页查询历史订单可以根据订单状态查询展示订单数据时&#xff0c;需要展示的数据包括&#xff1a;下单时间、订单状态、订单金额、订单明细&#xff08;商品名称、图片&#xff09;…

如何设置静态代理IP切换电脑上网地址使用?

在当今的网络时代&#xff0c;代理IP已成为一种常见的网络访问方式。通过使用代理IP&#xff0c;我们可以隐藏自己的真实IP地址&#xff0c;从而保护自己的隐私和安全。但是&#xff0c;有时候我们需要切换代理IP来满足不同的上网需求。本文将介绍如何设置静态代理IP切换电脑上…

优秀智慧园区案例 - 珠海华发智慧园区,万字长文解析先进智慧园区建设方案经验

一、项目背景 珠海华发产业园运营管理有限公司&#xff08;简称“产业园公司”&#xff09;是2016年起连续五年跻身“中国企业500强”、国务院国企改革“双百企业”的珠海华发集团旗下的实体产业发展载体运营平台&#xff0c;依托“四园一基地”&#xff1a;中以国际产业园、信…

Java自学第11课:电商项目(4)重新建立项目

经过前几节的学习&#xff0c;我们已经找到之前碰到的问题的原因了。那么下面接着做项目学习。 1 新建dynamic web project 建立时把web.xml也生成下&#xff0c;省的右面再添加。 会询问是否改为java ee环境&#xff1f;no就行&#xff0c;其实改过来也是可以的。这个不重要。…

基于springboot实现福聚苑社区团购平台系统项目【项目源码】

基于springboot实现福聚苑社区团购平台系统演示 Javar技术 Java是一种网络脚本语言&#xff0c;广泛运用于web应用开发&#xff0c;可以用来添加网页的格式动态效果&#xff0c;该语言不用进行预编译就直接运行&#xff0c;可以直接嵌入HTML语言中&#xff0c;写成js语言&…

【KVM-4】硬件虚拟化技术(详)

前言 大家好&#xff0c;我是秋意零。 经过前面章节的介绍&#xff0c;已经知道KVM虚拟化必须依赖于硬件辅助的虚拟化技术&#xff0c;本节就来介绍一下硬件虚拟化技术。 &#x1f47f; 简介 &#x1f3e0; 个人主页&#xff1a; 秋意零&#x1f525; 账号&#xff1a;全平…

从替代走向引领,永洪科技迈向全球化

对于数据分析领域而言&#xff0c;这是一个最好的时代。 《全球数字经济白皮书&#xff08;2023年&#xff09;》介绍&#xff0c;2016年-2022年&#xff0c;中国数字经济年均复合增长率为14.2%&#xff0c;数字经济发展增速和规模兼具。随着数字基础实施持续夯实、数字应用不…

前端面试系列之工程化篇

如果对前端八股文感兴趣&#xff0c;可以留意公重号&#xff1a;码农补给站&#xff0c;总有你要的干货。 前端工程化 Webpack 概念 本质上&#xff0c;webpack 是一个用于现代 JavaScript 应用程序的静态模块打包工具。当 webpack 处理应用程序时&#xff0c;它会在内部从一个…

MyBatis 反射工具箱:带你领略不一样的反射设计思路

反射是 Java 世界中非常强大、非常灵活的一种机制。在面向对象的 Java 语言中&#xff0c;我们只能按照 public、private 等关键字的规范去访问一个 Java 对象的属性和方法&#xff0c;但反射机制可以让我们在运行时拿到任何 Java 对象的属性或方法。 有人说反射打破了类的封装…

企业微信开发教程一:添加企微应用流程图解以及常见问题图文说明

最近在前辈的基础上新添加了一个企微应用&#xff0c;过程中遇到了一些卡点&#xff0c;这里一一通过图片标注与注释的方式记录一下&#xff0c;希望能给后来人提供一些清晰明了的帮助&#xff0c;话不多说&#xff0c;大家直接看图吧。 &#xff08;文中包括一些本项目独有的配…

matlab背景部分最小化算法人脸检测

1、内容简介 略 18-可以交流、咨询、答疑 matlab背景部分最小化算法人脸检测 2、内容说明 matlab人脸检测 matlab人脸检测&#xff0c;背景部分最小化算法 3、仿真分析 略. 4、参考论文 略 链接&#xff1a;https://pan.baidu.com/s/1yQ1yDfk-_Qnq7tGpa23L7g 提取码&…

双H桥直流马达步进电机驱动芯片SS8833E

由工采网代理的率能SS8833E是一款适用于有刷直流或双极步进电机的集成电机驱动芯片&#xff1b;采用eTSSOP16封装&#xff1b;该器件集成了两个PNMOS H桥和电流调节电路&#xff1b;电机输出电流可以由外部脉宽调制器&#xff08;PWM&#xff09;或内部PWM电流控制器控制。 工…

家庭安全计划 挑战赛| 溺水预防

溺水预防 从了解到行动 家庭安全计划 | 少年急救官 地震避险逃生该怎么做&#xff1f; 起火了该如何应对&#xff1f; 哪些行为容易导致溺水&#xff1f; 家庭风险隐患有哪些&#xff1f; 家庭逃生演练四步骤你会吗&#xff1f; 国际救助儿童会&#xff08;英国&#xff…

虚拟化服务器+华为防火墙+kiwi_syslog访问留痕

一、适用场景 1、大中型企业需要对接入用户的访问进行记录时&#xff0c;以前用3CDaemon时&#xff0c;只能用于小型网络当中&#xff0c;记录的数据量太大时&#xff0c;本例采用破解版的kiwi_syslog。 2、当网监、公安查到有非法访问时&#xff0c;可提供基于五元组的外网访…

kubernetes--Pod进阶

目录 一、资源限制&#xff1a; 1. 资源限制的两种规范&#xff1a; 2. Pod 和 容器 的资源请求和限制&#xff1a; 3. CPU 资源单位&#xff1a; 4. 内存资源单位 &#xff1a; 5. 资源限制示例&#xff1a; 二、健康检查&#xff1a;探针&#xff08;Probe&#xff09; 1. 探…

Git Gui的使用及ssh协议-IEDA使用git

目录 一.Git Gui的使用 二.ssh协议 2.1 什么是ssh key 2.2 配置用户名和邮箱&#xff08;如果已经配置&#xff0c;就跳过&#xff09; 2.3 生成(或删除)秘钥 ​编辑 2.4 远程仓库绑定公钥 三.IEDA使用git 3.1 idea配置Git 3.2 项目上传Git 3.3 演示 一.Git Gu…

python打包部署脚本

linux可使用expect来实现自动交互&#xff0c;windows想要写出同样的功能脚本&#xff0c;只能使用python或者安装ActiveTcl 1、安装python Microsoft Store搜索python直接安装&#xff0c;默认会直接添加到环境变量https://www.python.org/官网下载&#xff0c;点击安装时会提…

lua 时间差功能概略

简介 在进行程序设计过程中&#xff0c;经常需要对某些函数、某些程序片断从开始运行到运行结束所耗费的时间进行一些量化。这种量化实际上就是计算时间差。 获取函数耗时情景如下&#xff1a; function time_used() --开始计时-- do something at here. --结束计时--时间差&…

tomcat下载与使用教程

1. tomcat下载 官网&#xff1a;https://tomcat.apache.org/ 镜像地址&#xff1a;https://mirrors.huaweicloud.com/apache/tomcat/ 1、选择一个版本下载&#xff0c;官网下载速度缓慢&#xff0c;推荐镜像 2、对压缩包进行解压&#xff0c;无需进行安装&#xff0c;解压放…

Java 算法篇-深入了解单链表的反转(实现:用 5 种方式来具体实现)

&#x1f525;博客主页&#xff1a; 小扳_-CSDN博客 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 单链表的反转说明 2.0 单链表的创建 3.0 实现单链表反转的五种方法 3.1 实现单链表反转 - 循环复制&#xff08;迭代法&#xff09; 3.2 实现单链表反转 - 头插法 3…