当前位置: 首页 > news >正文

套接字属性的获取与设置

文章目录

  • 套接字属性
  • 套接字选项的核心级别
    • SOL_SOCKET的常用选项
    • IPPROTO_IP的常用选项
  • 核心函数
    • 参数
    • 返回值
  • 应用场景
  • demo

套接字属性

  • 套接字选项即套接字属性,用于对套接字的行为、功能进行精细化控制
  • 选项的操作分为获取和设置,部分选项仅可获取(如套接字状态、类型),部分选项既可获取也可设置(如缓冲区大小、保活机制)
  • 选项按协议 / 作用范围划分不同级别,不同级别下包含专属的选项,操作时需指定对应级别

套接字选项的核心级别

  • 级别是选项的作用域标识,操作选项时必须指定,核心常用级别及作用如下:
级别作用范围适用场景
SOL_SOCKET套接字本身(通用级别)所有类型套接字的基础属性控制
IPPROTO_IPIPv4 协议层IPv4 相关的网络属性配置
IPPROTO_IPV6IPv6 协议层IPv6 相关的网络属性配置
IPPROTO_TCPTCP 协议(流式套接字)TCP 专属属性控制
IPPROTO_UDPUDP 协议(数据报套接字)UDP 专属属性控制
其他(如 SOL_LRLMP)特定协议(如 IrDA)小众协议的专属配置

SOL_SOCKET的常用选项

  • 最常用的基础级别,包含套接字的核心通用属性,重点选项如下(区分获取 / 设置权限):
选项名说明操作权限核心用途
SO_ACCEPTCONN套接字是否处于监听状态仅获取判断 listen 是否调用成功
SO_BROADCAST允许发送广播数据获取 / 设置UDP 广播通信开启
SO_KEEPALIVE保活连接获取 / 设置TCP 长连接保活,检测断连
SO_LINGER延迟关闭连接获取 / 设置控制 close 时的连接关闭行为
SO_RCVBUF/SO_SNDBUF接收 / 发送缓冲区大小获取 / 设置调整套接字读写缓冲区,优化 I/O
SO_REUSEADDR允许重用本地地址和端口获取 / 设置解决端口占用问题(如重启服务)
SO_TYPE获得套接字类型仅获取判断是 TCP(SOCK_STREAM)/UDP(SOCK_DGRAM)
SO_ERROR获得套接字错误码仅获取排查套接字运行中的错误

IPPROTO_IP的常用选项

  • 针对 IPv4 协议的专属配置,常用选项:
选项名说明操作权限
IP_ADD_MEMBERSHIP加入多播组仅设置
IP_OPTIONS设置 / 获取 IP 头部选项获取 / 设置
IP_HDRINCL自定义 IP 头部(原始套接字)获取 / 设置
IP_TTL设置 / 获取 IP 生存时间获取 / 设置

核心函数

#include<sys/socket.h>//获取选项:getsockoptintgetsockopt(intsockfd,intlevel,intoptname,void*optval,socklen_t*optlen);//设置选项:setsockoptintsetsockopt(intsockfd,intlevel,intoptname,constvoid*optval,socklen_toptlen);

参数

参数名类型作用
sockfdint要操作的套接字描述符(socket 创建的返回值)
levelint选项的级别(如 SOL_SOCKET、IPPROTO_IP)
optnameint要操作的具体选项名(如 SO_REUSEADDR、IP_TTL)
optvalvoid*存放选项值的缓冲区:getsockopt:内核将选项值写入该缓冲区;setsockopt:将待设置的值传入内核
optlensocklen_t*getsockopt:传入缓冲区大小,返回实际读取的大小;
setsockopt:直接传入缓冲区的实际大小(非指针)

返回值

  • 成功:返回0
  • 失败:返回-1,错误码存入errno,常见错误码:
    • EBADF:无效的套接字描述符
    • EINVAL:未知的级别 / 选项名
    • ENOTSOCK:描述符不是套接字(是普通文件 / 设备)
    • ENOPROTOOPT:协议不支持该选项

应用场景

  • 服务端重启时,设置SO_REUSEADDR解决端口占用问题

需在bind前设置,否则端口重用失效,是服务端开发的必设选项

  • 高并发 / 大流量场景,调整SO_RCVBUF/SO_SNDBUF扩大读写缓冲区,减少 I/O 次数
  • TCP 长连接(如 IM、物联网),设置SO_KEEPALIVE开启保活机制,自动检测断连
  • UDP 广播通信,设置SO_BROADCAST允许发送广播包
  • 排查问题时,通过SO_ERROR获取套接字错误码,通过SO_TYPE判断套接字类型
  • 多播开发时,通过IP_ADD_MEMBERSHIP让套接字加入多播组

demo

#ifndef_NET_H_#define_NET_H_#include<stdio.h>#include<stdlib.h>#include<sys/socket.h>#include<netinet/in.h>#include<netinet/tcp.h>#include<arpa/inet.h>#include<unistd.h>#include<strings.h>#include<errno.h>typedefstructsockaddrAddr;typedefstructsockaddr_inAddr_in;#defineBACKLOG5#defineErrExit(msg)do{perror(msg);exit(EXIT_FAILURE);}while(0)voidArgment(intargc,char*argv[]);intCreateSocket(char*argv[]);intDataHandle(intfd);#endif
#include"net.h"voidArgment(intargc,char*argv[]){if(argc<3){fprintf(stderr,"%s<addr><port>\n",argv[0]);exit(0);}}intCreateSocket(char*argv[]){/*创建套接字*/intfd=socket(AF_INET,SOCK_STREAM,0);if(fd<0)ErrExit("socket");/*允许地址快速重用*/intflag=1;if(setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&flag,sizeof(flag)))perror("setsockopt");/*设置通信结构体*/Addr_in addr;bzero(&addr,sizeof(addr));addr.sin_family=AF_INET;addr.sin_port=htons(atoi(argv[2]));/*绑定通信结构体*/if(bind(fd,(Addr*)&addr,sizeof(Addr_in)))ErrExit("bind");/*设置套接字为监听模式*/if(listen(fd,BACKLOG))ErrExit("listen");returnfd;}intDataHandle(intfd){charbuf[BUFSIZ]={};Addr_in peeraddr;socklen_tpeerlen=sizeof(Addr_in);if(getpeername(fd,(Addr*)&peeraddr,&peerlen))perror("getpeername");intret=recv(fd,buf,BUFSIZ,0);if(ret<0)perror("recv");if(ret>0){printf("[%s:%d]data: %s\n",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port),buf);}returnret;}
#include"net.h"#include<sys/select.h>#defineMAX_SOCK_FD1024voidsetKeepAlive(intsockfd,intattr_on,socklen_tidle_time,socklen_tinterval,socklen_tcnt){setsockopt(sockfd,SOL_SOCKET,SO_KEEPALIVE,(constchar*)&attr_on,sizeof(attr_on));setsockopt(sockfd,SOL_TCP,TCP_KEEPIDLE,(constchar*)&idle_time,sizeof(idle_time));setsockopt(sockfd,SOL_TCP,TCP_KEEPINTVL,(constchar*)&interval,sizeof(interval));setsockopt(sockfd,SOL_TCP,TCP_KEEPCNT,(constchar*)&cnt,sizeof(cnt));}intmain(intargc,char*argv[]){inti,ret,fd,newfd;fd_set set,tmpset;Addr_in clientaddr;socklen_tclientlen=sizeof(Addr_in);/*检查参数,小于3个 直接退出进程*/Argment(argc,argv);/*创建已设置监听模式的套接字*/fd=CreateSocket(argv);FD_ZERO(&set);FD_ZERO(&tmpset);FD_SET(fd,&set);while(1){tmpset=set;if((ret=select(MAX_SOCK_FD,&tmpset,NULL,NULL,NULL))<0){perror("select");getchar();}if(FD_ISSET(fd,&tmpset)){/*接收客户端连接,并生成新的文件描述符*/if((newfd=accept(fd,(Addr*)&clientaddr,&clientlen))<0){perror("accept");getchar();}#if1intkeepAlive=1;//设定KeepAliveintkeepIdle=5;//开始首次KeepAlive探测前的TCP空闭时间intkeepInterval=5;//两次KeepAlive探测间的时间间隔intkeepCount=3;//判定断开前的KeepAlive探测次数setKeepAlive(newfd,keepAlive,keepIdle,keepInterval,keepCount);#endifprintf("[%s:%d]已建立连接\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));FD_SET(newfd,&set);}else{//处理客户端数据for(i=fd+1;i<MAX_SOCK_FD;i++){if(FD_ISSET(i,&tmpset)){if(DataHandle(i)<=0){if(getpeername(i,(Addr*)&clientaddr,&clientlen))perror("getpeername");printf("[%s:%d]断开连接\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));FD_CLR(i,&set);close(i);}}}}}close(fd);return0;}
http://www.jsqmd.com/news/401597/

相关文章:

  • 导师推荐!风靡全网的AI论文平台 —— 千笔·专业论文写作工具
  • AI写教材技巧大揭秘,低查重方法让教材生成不再困难!
  • 广播与组播
  • 基于Agent实现智能客服:从架构设计到生产环境避坑指南
  • Agent实习模拟面试之vLLM:大模型推理加速的核心引擎与工程实践
  • 学长亲荐!一键生成论文工具,千笔AI VS 灵感ai
  • ChatTTS 对接实战:从零构建高可靠语音合成服务
  • 定稿前必看!千笔,抢手爆款的AI论文工具
  • ChatTTS案例实战:如何通过语音合成技术提升客服系统效率
  • Agent实习模拟面试之NL2SQL:从零构建自然语言到SQL的智能桥梁
  • Agent实习模拟面试之Benchmark:如何科学评估智能体的真实能力?
  • 深度测评 10个降AIGC软件:专科生降AI率必备工具全对比
  • 基于神经网络的毕设实战:从模型选型到部署落地的完整路径
  • ChatTTS 生产环境部署实战:从零搭建到高可用架构
  • ChatGPT内容转Word的高效实现:Python自动化方案与避坑指南
  • 【信息科学与工程学】【解决方案体系】 第二十篇 互联网行业收入和支出、利润抽成
  • 2026最新!王者级的降AI率工具 —— 千笔·专业降AI率智能体
  • 260219
  • 智能客服在金融领域的应用:从架构设计到生产环境避坑指南
  • n皇后算法
  • 一行代码实现数组去重与排序
  • AI专著撰写新突破!揭秘高效工具,轻松完成学术专著创作
  • 实测对比后AI论文工具,千笔AI VS speedai,研究生写作神器!
  • ChatTTS v3 技术解析:从语音合成原理到生产环境部署实战
  • ChatTTS Colab 实战:如何高效部署与优化语音合成工作流
  • AMD Windows平台下CosyVoice AI辅助开发实战:从环境配置到性能优化
  • 筑牢企业“防火墙”:奋飞咨询助力企业构建系统化反腐败体系 - 奋飞咨询ecovadis
  • AI 辅助开发实战:高效完成计算机毕业设计附源码的全流程指南
  • 2026年知名的环保家具板/耐磨防划家具板高评价直销厂家采购指南推荐(高评价) - 行业平台推荐
  • 微信客服API与飞书AI智能客服集成实战:从架构设计到避坑指南