套接字的多种可选项

news2024/12/24 9:59:31

套接字可选项和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.coloradmin.cn/o/1205676.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HCIE-灾备技术和安全服务

灾备技术 灾备包含两个概念&#xff1a;容灾、备份 备份是为了保证数据的完整性&#xff0c;数据不丢失。全量备份、增量备份&#xff0c;备份数据还原。 容灾是为了保证业务的连续性&#xff0c;尽可能不断业务。 快照&#xff1a;保存的不是底层块数据&#xff0c;保存的是逻…

算法笔记—第五章-最大公约数与最小公倍数

算法笔记-最大公约数与最小公倍数 最大公约数最小公倍数最大公约数 2最小公倍数2互质互质2 最大公约数 //最大公约数与最小公倍数#include <cstdio> int gcd(int a, int b) {if (b 0) //截止的条件{return a; }else {return gcd(b, a % b);//这里是a与b和b&#xff…

车载通信与DDS标准解读系列(1):DDS-RPC

▎RPC & DDS-RPC RPC&#xff1a;Remote Procedure Call&#xff0c;远程过程调用。 远程过程调用是一种进程间通信&#xff0c;它允许计算机程序在另一个地址空间中执行子程序&#xff0c;就好像用别人的东西像用自己的一样&#xff0c;常用于分布式系统。 远程过程调用…

GCN代码讲解

这里写的有点抽象&#xff0c;所以具体的可以参照下面代码块中的注释&#xff1a; def load_data(path"../data/cora/", dataset"cora"):"""Load citation network dataset (cora only for now)"""print(Loading {} datase…

Spark数据倾斜优化

1 数据倾斜现象 1、现象 绝大多数task任务运行速度很快&#xff0c;但是就是有那么几个task任务运行极其缓慢&#xff0c;慢慢的可能就接着报内存溢出的问题。 2、原因 数据倾斜一般是发生在shuffle类的算子&#xff0c;比如distinct、groupByKey、reduceByKey、aggregateByKey…

U-Mail邮件中继有效解决海外邮件发送不畅难题

相信不少企业都经历过类似的问题&#xff0c;在跟国外客户发送电子邮件的过程中&#xff0c;经常会遇到邮件发不过去、邮件隔了很久对方才收到&#xff0c;或者是邮件退信等情况出现。对此&#xff0c;U-Mail技术专家李工解释到&#xff0c;导致海外通邮不畅主要有以下三个原因…

ubuntu18.04安装google浏览器

下载google安装包 wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb 安装google浏览器 sudo dpkg -i google-chrome-stable_current_amd64.deb 执行安装 sudo apt-get -f install 启动浏览器 在应用程序中找到google图标点击运行

密钥安全存储方案探讨与实践

随着信息技术的迅猛发展和应用范围的不断扩大&#xff0c;我们日常生活中的许多方面已经与信息技术密不可分。而在信息安全领域中&#xff0c;密钥的安全存储显得尤为重要。本文将探讨密钥安全存储的必要性、相关技术和实践方案&#xff0c;并提出一些解决方案。 一、密钥安全存…

11-13 spring整合web

spring注解 把properties文件中的key注入到属性当中去 xml配置文件拆分 -> import标签 注解开发中 import 实现 搞一个主配置类&#xff0c;其他配置类全部导入进来这个这个主配置类 而且其他配置类不需要 加上configuration注解 之前这个注解用于表示这是一个配置文件 …

Vmware虚拟机重装 虚拟机能ping通主机,而主机不能ping通虚拟机的问题

CClean&#xff0c;用它把你电脑上已经卸载的软件但是注册表还没删干净的把注册表删干净&#xff0c;之前说的那种情况&#xff08;虚拟网络编辑器打不上勾&#xff09;就迎刃而解了。 Ps&#xff1a;CClean&#xff1a;再网上百度就可以查到&#xff0c;软件对用户也很友好&a…

【cfeng-work】架构演进和漫谈

架构漫谈和入门 内容管理 intro分层架构MVC模式分层架构大数据时代的复杂架构 前端架构后端架构运维端架构持续演进变化 本文主要是自己接触架构的一些输出漫谈 cfeng 在work中某次负责了后端一个服务的上线&#xff0c;多个模块一起上&#xff0c;结果上线失败&#xff0c;幸运…

GWAS全基因组关联分析实战——基于Plink转换vcf数据为二进制

vcf数据是保存变异信息的主要数据格式&#xff0c;plink是进行全基因组关联分析&#xff08;GWAs&#xff09;分析的常用工具包&#xff0c;同时提供一系列数据转换、裁剪和遗传统计量计算工具。本文以实际数据提供基因组关联分析方法。 1 数据准备 首先&#xff0c;使用plin…

微信小程序_02

能够使用WXML模版语法渲染页面结构 数据绑定 1、数据绑定的基本原则 在data中定义数据在WXML中使用数据 2、在data中定义页面的数据 ​ 在页面对应的.js文件中&#xff0c;把数据定义到data对象中即可&#xff1a; Page({data:{//字符串类型的数据info:init data,//数组类…

EXTI (2)

增强版实验简介 EXTI5和EXTI9共享一个中断源 下面的类似 EXTI0到4各自拥有一个中断源 改变引脚 PA0和PA1改变为PA5 和PA6 EXTI的重映射 之前是把PA0映射到EXTI0 PA1映射到EXTI1上 现在是要把PA5和PA6分别映射到EXTI5和6上 EXTI进行初始化 NVIC初始化 编写中断函数 因为EXTI…

STM32与RTOS的整合:实时操作系统在嵌入式开发中的应用

随着各种嵌入式系统应用的日益复杂和对实时性要求的提高&#xff0c;使用实时操作系统&#xff08;RTOS&#xff09;成为嵌入式开发中的一种重要选择。STM32微控制器作为一种强大的嵌入式处理器&#xff0c;与各种RTOS相结合&#xff0c;能够提供更高效、可靠并且易于维护的系统…

【仿真动画】双机器人协作完成一个任务(切割)

场景 动画 两个机器人协同工作完成一个任务需要解决以下几个关键问题&#xff1a; 通信&#xff1a;两个机器人需要能够相互通信&#xff0c;以共享信息&#xff0c;例如位置、姿态、状态等。规划&#xff1a;需要对两个机器人的运动轨迹进行规划&#xff0c;确保两个机器人不会…

老胡的周刊(第115期)

老胡的信息周刊[1]&#xff0c;记录这周我看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。 &#x1f3af; 项目 draw-a-ui[2] 利用 tldraw gpt-4-vision ap…

MATLAB算法实战应用案例精讲-【数模应用】漫谈机器学习(二)

目录 几个高频面试题目 机器学习中的模型评价、模型选择与算法选择 基本的模型评估项和技术 Bootstrapping 和不确定性 交叉验证和超参数优化 机器学习的发展历程 知识储备 机器学习常用术语 算法原理 1. 什么是机器学习&#xff1f; 机器学习和人工智能的关系 机…

机器视觉行业,日子不过了吗?都进入打折潮,双11只是一个借口,打广告出新招,日子不好过是真的

我就不上图了&#xff0c;大家注意各个机器视觉公司公众号&#xff0c;为什么打折&#xff1f;打广告也只是宣传手段&#xff0c;进入打折潮&#xff0c;内卷严重&#xff0c;价格战变成白刃战&#xff0c;肯定日子不好过了。

代码随想录 Day44 动规12 LeetCode T300 最长递增子序列 T674 最长连续递增序列 T718 最长重复子数组

前言 本期我们来解决动规的经典题型------ 子数组问题 我们还是会使用动规五部曲来解决问题,下面我们仍然列出动规五部曲 1.明确dp数组含义 2.明确dp数组如何推导-递推公式 3.初始化dp数组 4.确定遍历顺序 5.打印dp数组排错 LeetCode T300 最长递增子序列 题目链接:300. 最长…