Socket some functions

setsockopt 简介

setsockopt 是用于设置套接字(socket)选项的系统调用函数,允许用户对套接字的行为进行精细控制。通过调整选项参数,可以优化网络通信性能、修改超时设置、启用特殊功能等。该函数在 POSIX 系统和 Windows 平台均有支持,但部分选项可能因操作系统而异。

函数原型

int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);

  • sockfd:目标套接字的文件描述符。
  • level:选项的协议层级(如 SOL_SOCKETIPPROTO_TCP)。
  • optname:具体选项名称(如 SO_REUSEADDRTCP_NODELAY)。
  • optval:指向选项值的指针,类型取决于选项。
  • optlen:选项值的长度。

常用选项及用法

地址复用(SO_REUSEADDR)

允许绑定到处于 TIME_WAIT 状态的地址,适用于服务器快速重启。

int reuse = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));

禁用 Nagle 算法(TCP_NODELAY)

减少小数据包的延迟,适用于实时性要求高的场景。

int nodelay = 1;
setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay));

设置接收超时(SO_RCVTIMEO)

指定套接字接收数据的超时时间。

struct timeval timeout;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));

错误处理

函数返回值为 0 表示成功,-1 表示失败,可通过 errno 获取具体错误原因。例如:

if (setsockopt(sockfd, SOL_SOCKET, optname, &value, sizeof(value)) == -1) {perror("setsockopt failed");exit(EXIT_FAILURE);
}

注意事项

  • 不同操作系统支持的选项可能不同,需查阅文档确认兼容性。
  • 部分选项需在特定时机设置(如绑定前或连接前)。
  • 选项值的类型和含义需严格匹配,否则可能导致未定义行为。

SO_REUSEPORT 概述

SO_REUSEPORT 是一个套接字选项,允许多个套接字绑定到相同的 IP 地址和端口组合。该特性最初在 Linux 3.9 内核中引入,旨在提高多核系统的网络性能,尤其是在高并发场景下。通过允许多个进程或线程同时监听同一端口,可以更高效地分配连接负载。

工作原理

当启用 SO_REUSEPORT 时,内核会使用哈希算法将传入的连接请求均匀分配到所有绑定到同一地址和端口的套接字上。这种方式避免了传统的单一监听套接字可能成为性能瓶颈的问题。哈希算法通常基于源 IP 地址、源端口和目标 IP 地址的组合,确保同一客户端连接始终被分配到同一套接字。

使用方法

在 Linux 系统中,可以通过 setsockopt 函数设置 SO_REUSEPORT 选项。以下是一个简单的 C 代码示例:

int sockfd = socket(AF_INET, SOCK_STREAM, 0);
int optval = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));

适用场景

  • 负载均衡:多个进程或线程可以同时监听同一端口,内核自动分配连接请求。
  • 无缝重启:新启动的服务实例可以绑定到同一端口,而旧实例仍在处理连接,实现零停机重启。
  • 多协议支持:不同协议的服务可以绑定到同一端口,例如 TCP 和 UDP 服务。

注意事项

  • 内核版本要求:SO_REUSEPORT 需要 Linux 3.9 或更高版本的支持。
  • 权限问题:所有绑定到同一端口的套接字必须具有相同的有效用户 ID,防止权限滥用。
  • 连接分配:哈希算法可能导致连接分配不均匀,尤其是在客户端数量较少时。

与 SO_REUSEADDR 的区别

SO_REUSEADDR 是另一个套接字选项,主要用于解决端口占用问题,例如在服务重启时快速重用端口。两者的主要区别在于:

  • SO_REUSEADDR 允许多个套接字绑定到同一地址和端口,但只有一个套接字可以处于监听状态。
  • SO_REUSEPORT 允许多个套接字同时监听同一地址和端口,内核负责连接分配。

性能优势

在高并发场景下,SO_REUSEPORT 可以显著提升性能:

  • 减少锁竞争:传统单一监听套接字可能导致多核系统上的锁竞争。
  • 更好的 CPU 亲和性:连接请求被分配到不同的套接字,可以更好地利用多核 CPU。

示例:多进程服务器

以下是一个使用 SO_REUSEPORT 的多进程服务器示例:

#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>int main() {int sockfd = socket(AF_INET, SOCK_STREAM, 0);int optval = 1;setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(8080);addr.sin_addr.s_addr = INADDR_ANY;bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));listen(sockfd, 10);for (int i = 0; i < 4; ++i) {if (fork() == 0) {while (1) {int client_fd = accept(sockfd, NULL, NULL);printf("Process %d handling connection\n", getpid());close(client_fd);}}}pause();return 0;
}

限制与挑战

  • 连接分配不均:哈希算法可能导致某些进程或线程处理更多连接。
  • 调试复杂性:多监听套接字可能增加调试难度,尤其是在连接分配异常时。
  • 兼容性问题:某些旧版操作系统或网络设备可能不支持 SO_REUSEPORT。

TCP_NODELAY 概述

TCP_NODELAY 是 TCP 协议的一个套接字选项(通过 setsockopt 设置),用于禁用 Nagle 算法。Nagle 算法旨在减少小数据包的传输,通过合并缓冲区中的小数据包并等待确认(ACK)后再发送,但会增加延迟。启用 TCP_NODELAY 后,数据会立即发送,适合低延迟场景。


适用场景

  • 实时应用:如在线游戏、视频会议、远程桌面等对延迟敏感的场景。
  • 交互式协议:如 SSH、Telnet,用户输入需即时反馈。
  • 高频交易系统:金融领域需最小化网络延迟。

使用方法

在代码中通过 setsockopt 启用 TCP_NODELAY(以 C 为例):

int enable = 1;
setsockopt(socket_fd, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable));


与 Nagle 算法的关系

  • Nagle 算法:默认启用,合并小数据包,提高带宽利用率,但增加延迟。
  • TCP_NODELAY:禁用 Nagle 算法,牺牲带宽效率换取低延迟。

注意事项

  • 带宽影响:禁用 Nagle 可能导致小包增多,占用更多带宽。
  • 与延迟确认(Delayed ACK)的交互:延迟确认机制可能加剧延迟问题,需结合调整。
  • 默认行为:多数系统默认启用 Nagle,需显式设置 TCP_NODELAY 关闭。

替代方案

  • TCP_QUICKACK:临时禁用延迟确认,适合单次低延迟需求(需每次接收后重置)。
  • 应用层缓冲:手动合并数据包,平衡延迟与效率。

代码示例(Python)

import sockets = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)

Socket的Write、Read和Shutdown操作解释

在网络编程中,Socket是用于进程间通信(如TCP/IP协议)的基础工具。writeread操作用于数据传输,而shutdown操作用于优雅地关闭部分连接。结构如下:

  1. Socket的Write操作:发送数据。
  2. Socket的Read操作:接收数据。
  3. Shutdown操作:特别是关闭写入端(SHUT_WR)。
  4. 整体作用与示例:为什么需要这些操作,并给出Python代码演示。

1. Socket的Write操作(发送数据)
  • write操作(或send)用于将数据从应用程序发送到网络。
  • 在TCP Socket中,它保证数据的可靠传输(基于TCP的可靠性)。
  • 例如,在客户端发送请求时使用:
    • 函数形式:socket.write(data)socket.send(data)
    • 数据可以是字节序列,如字符串编码后的结果。
    • 如果发送失败,会返回错误(如连接中断)。
2. Socket的Read操作(接收数据)
  • read操作(或recv)用于从网络接收数据到应用程序。
  • 它读取对方发送的数据,并返回字节流。
  • 例如,在服务器接收请求时使用:
    • 函数形式:data = socket.read(buffer_size)data = socket.recv(buffer_size)
    • buffer_size指定最大读取字节数。
    • 如果连接关闭或出错,返回空数据或错误。
3. Shutdown操作(关闭写入端:SHUT_WR
  • shutdown操作用于部分关闭Socket,而不完全关闭连接。
  • 关键参数:
    • SHUT_WR:关闭写入端(write side),表示本端不再发送数据,但可以继续接收数据。
    • 其他选项:SHUT_RD(关闭读取端)或SHUT_RDWR(关闭读写两端)。
  • 为什么需要shutdown(SHUT_WR)
    • 在TCP通信中,一方完成数据发送后,调用shutdown(SHUT_WR)通知对方“不会再发送新数据”。
    • 对方可以通过read操作检测到EOF(文件结束符),从而知道数据已完整接收。
    • 这避免了“半关闭”状态问题:例如,如果直接关闭Socket,对方可能无法优雅结束接收。
    • 典型场景:客户端发送完请求后关闭写入端,服务器接收完数据后关闭连接。
  • 函数形式:socket.shutdown(how),其中how指定关闭方式(如socket.SHUT_WR)。
4. 整体作用与示例
  • 作用总结
    • writeread实现双向数据传输。
    • shutdown(SHUT_WR)用于优雅终止发送端,确保数据完整性,常用于协议如HTTP(客户端发送请求后关闭写入)。
    • 这比直接close()更安全,因为它允许对方完成接收。
  • Python代码示例
    • 以下是一个简单的TCP客户端和服务器演示,展示writereadshutdown(SHUT_WR)的使用。
    • 服务器接收数据后,检测EOF并回复。
# 服务器端代码(接收数据,检测写入端关闭)
import socketdef run_server():server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server_socket.bind(('localhost', 8080))server_socket.listen(1)print("服务器启动,等待连接...")client_socket, addr = server_socket.accept()print(f"连接来自: {addr}")# 循环读取数据,直到检测到EOF(对方关闭写入端)data = b''while True:chunk = client_socket.recv(1024)  # read操作if not chunk:break  # 检测到EOF,跳出循环data += chunkprint(f"接收数据: {data.decode()}")client_socket.send(b"ACK: 数据已接收")  # write操作回复client_socket.close()server_socket.close()if __name__ == '__main__':run_server()

# 客户端代码(发送数据后关闭写入端)
import socketdef run_client():client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)client_socket.connect(('localhost', 8080))# 发送数据(write操作)client_socket.send(b"Hello, Server! This is a test message.")# 关闭写入端(shutdown SHUT_WR),通知服务器不再发送数据client_socket.shutdown(socket.SHUT_WR)  # 关键步骤# 继续读取服务器回复response = client_socket.recv(1024)  # read操作print(f"服务器回复: {response.decode()}")client_socket.close()if __name__ == '__main__':run_client()

  • 示例说明
    • 客户端发送数据后调用shutdown(SHUT_WR),服务器通过recv返回空数据检测EOF。
    • 这确保了服务器知道数据已完整,并发送回复。
    • 如果没有shutdown,服务器可能无限等待数据,导致资源浪费。

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

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

相关文章

玩转深度学习数据填补!CNN-GRU组合模型数据填补(四个案例数据)

这两段MATLAB代码&#xff08;BABJ.m 和 CNN_GRUQSTB.m&#xff09;分别完成数据预处理与缺失值标识和基于CNN-GRU混合神经网络的缺失值预测填补任务。以下是详细分析&#xff1a; 一、主要功能 BABJ.m • 功能&#xff1a;从多个Excel文件中读取数据&#xff0c;匹配并合并多个…

基于开源AI智能名片链动2+1模式S2B2C商城小程序的营销创新研究——以“种草”实践践行“以人为本”理念

摘要&#xff1a;本文聚焦于营销本质&#xff0c;强调创造和维护与消费者有价值关系的重要性&#xff0c;指出企业需回归消费者视角提供有价值产品和服务。深入探讨“种草”作为科特勒“以人为本”理念在中国市场的最佳实践&#xff0c;分析其意义与价值。同时&#xff0c;引入…

基于SpringBoot+Vue的智能停车场管理系统 停车管理小程序

&#x1f525;作者&#xff1a;it毕设实战小研&#x1f525; &#x1f496;简介&#xff1a;java、微信小程序、安卓&#xff1b;定制开发&#xff0c;远程调试 代码讲解&#xff0c;文档指导&#xff0c;ppt制作&#x1f496; 精彩专栏推荐订阅&#xff1a;在下方专栏&#x1…

01数据结构-归并排序和计数排序

01数据结构-归并排序和计数排序1.归并排序1.1归并排序概述1.2归并排序的执行流程1.2.1递(分裂)的过程1.2.2归(合并)的过程1.3归并排序的代码实现2.计数排序2.1算法思想2.2计数排序的改进2.2.1优化12.2.2优化21.归并排序 1.1归并排序概述 归并排序&#xff0c;其排序的实现思想…

SQL注入2----(sql注入数据类型分类)

一.前言本章节我们来讲解一下sql注入的分类&#xff0c;主要分为四类&#xff0c;数字型、字符型、搜索型、xx型。二.数字型数字型注入的时候&#xff0c;是不需要考虑单\双引号闭合问题的&#xff0c;因为sql语句中的数字是不需要用引号括起来的&#xff0c;如下mysql> sel…

Elasticsearch Rails 实战全指南(elasticsearch-rails / elasticsearch-model)

一、背景与生态总览 elasticsearch-rails&#xff1a;面向 Rails 的“伴生库”&#xff0c;为 Rails 项目带来 Rake 任务、日志埋点、模板等特性。elasticsearch-model&#xff1a;把 ES 能力“混入”到 Ruby 模型&#xff08;ActiveRecord/Mongoid&#xff09;&#xff0c;提供…

第三阶段数据库-2:数据库中的sql语句

1_数据库操作&#xff08;1&#xff09;注释&#xff1a;-- 单行注释 /**/ 多行注释&#xff08;2&#xff09;创建数据库&#xff1a;create database 数据库名-- create database 数据库名 create database db_first;(3&#xff09;查询数据库&#xff1a;if exsists(select…

python中的filter函数

目录 定义与参数说明 特点 使用场景 常用操作 筛选偶数 去除空字符串 筛选正数 筛选字典 配合集合与元组 注意事项 定义与参数说明 filter函数是Python内置的高阶函数之一&#xff0c;用于筛选可迭代对象中的元素&#xff0c;根据返回值的布尔结果&#xff08;True 或…

BERT(Bidirectional Encoder Representations from Transformers)模型详解

一、BERT 简介BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;是由 Google 在 2018 年提出的一种预训练语言表示模型。它基于 Transformer 编码器结构&#xff0c;首次提出了 双向上下文建模 的方法&#xff0c;大幅度提升了自然语言处理…

【开题答辩全过程】以 基于Springboot+微信小程序的网上家教预约系统的设计与实现-开题为例,包含答辩的问题和答案

个人简介&#xff1a;一名14年经验的资深毕设内行人&#xff0c;语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧…

课小悦系列智能耳机上市,用硬核科技为教育赋能

在人工智能与教育深度融合的浪潮中&#xff0c;深圳课小悦科技有限公司以“智慧教育专家”的姿态崭露头角。这家深耕智能教育硬件的创新企业&#xff0c;于2025年8月正式推出革命性产品H360PRO系列教考耳机&#xff0c;为语言学习场景提供颠覆性解决方案。创新基因&#xff1a;…

[react] class Component and function Component

我对react的用法理解还一直停留在多年以前&#xff0c;说明这段时间我没有更新react的知识。我大脑中记得还是使用Class Component this.setState&#xff0c;可是今天看了看react的文档&#xff0c;发现怎么不一样了&#xff0c;用的都是function useState的方式了。你知道这…

以太坊智能合约地址派生方式:EOA、CREATE 和 CREATE2

1. 引言 在以太坊上&#xff0c;智能合约可以通过以下三种方式之一进行部署&#xff1a; 1&#xff09;由外部账户&#xff08;Externally Owned Account, EOA&#xff09;发起交易&#xff0c;其中 to 字段设为 null&#xff0c;而 data 字段包含合约的初始化代码。2&#x…

基于RISC-V架构的国产MCU在eVTOL领域的应用研究与挑战分析

摘要电动垂直起降飞行器&#xff08;eVTOL&#xff09;作为未来城市空中交通的重要组成部分&#xff0c;对嵌入式控制系统的性能、可靠性和安全性提出了极高的要求。RISC-V作为一种新兴的开源指令集架构&#xff0c;为国产微控制器&#xff08;MCU&#xff09;的研发和应用带来…

深度学习中的“集体智慧”:Dropout技术详解——不仅是防止过拟合,更是模型集成的革命

引言&#xff1a;从“过拟合”的噩梦说起 在训练深度学习模型时&#xff0c;我们最常遇到也最头疼的问题就是过拟合&#xff08;Overfitting&#xff09;。 想象一下&#xff0c;你是一位正在备考的学生&#xff1a; 欠拟合&#xff1a;你根本没学进去&#xff0c;所有题都做错…

在JavaScript中,比较两个数组是否有相同元素(交集)的常用方法

方法1&#xff1a;使用 some() includes()&#xff08;适合小数组&#xff09;function haveCommonElements(arr1, arr2) {return arr1.some(item > arr2.includes(item)); }// 使用示例 const arrA [1, 2, 3]; const arrB [3, 4, 5]; console.log(haveCommonElements(ar…

心路历程-Linux的系统破解详细解说

CentOS7系统密码破解 密码破解是分两种情况的&#xff1b;一种是在系统的界面内&#xff0c;一种就是不在系统的页面&#xff1b; 今天我们就来聊聊这个系统破解的话题&#xff1b; 1.为什么需要破解密码&#xff1f;–>那当然是忘记了密码&#xff1b;需从新设置密码 2.但是…

IDE和AHCI硬盘模式有什么区别

IDE&#xff08;Integrated Drive Electronics&#xff09;和 AHCI&#xff08;Advanced Host Controller Interface&#xff09;是硬盘控制器的工作模式&#xff0c;主要区别在于性能、功能兼容性以及对现代存储设备的支持程度。以下是详细对比和分析&#xff1a;一、本质区别…

【密码学实战】密码实现安全测试基础篇 . KAT(已知答案测试)技术解析与实践

KAT 测试技术解析 在密码算法的安全性验证体系中&#xff0c;Known Answer Test&#xff08;KAT&#xff0c;已知答案测试&#xff09;是一项基础且关键的技术。它通过 “已知输入 - 预期输出” 的确定性验证逻辑&#xff0c;为密码算法实现的正确性、合规性提供核心保障&…

如何用Redis作为消息队列

说明&#xff1a;以前背八股文&#xff0c;早就知道 Redis 可以作为消息队列&#xff0c;本文介绍如何实现用 Redis 作为消息队列。 介绍 这里直接介绍 yudao 框架中的实现。yudao 是一套现成的开源系统框架&#xff0c;里面集成了许多基础功能&#xff0c;我们可以在这基础上…