2026/3/14 22:01:59
网站建设
项目流程
武清做网站的,自己做发卡网站支付接口,做我女朋友的表白句的网站,企业云服务Linux 网络编程必知#xff1a;setsockopt、缓冲区、地址重用、多播端口一次讲透关键词#xff1a;setsockopt、SO_RECVBUF、SO_SNDBUF、SO_REUSEADDR、多播端口、UDP 组播、TCP_NODELAY一、setsockopt 到底能改什么#xff1f;
setsockopt 只能改 内核套接字缓冲区 及相关行…Linux 网络编程必知setsockopt、缓冲区、地址重用、多播端口一次讲透关键词setsockopt、SO_RECVBUF、SO_SNDBUF、SO_REUSEADDR、多播端口、UDP 组播、TCP_NODELAY一、setsockopt 到底能改什么setsockopt只能改 内核套接字缓冲区 及相关行为改不到 你read/recv时自己传的那块用户空间数组。常见误区把“内核接收缓冲区”和“用户空间 buf”混为一谈——两者不在一层。缓冲区位置 控制方式 默认大小来源内核接收缓冲区setsockopt(fd, SOL_SOCKET, SO_RCVBUF, …)/proc/sys/net/core/rmem_default内核发送缓冲区setsockopt(fd, SOL_SOCKET, SO_SNDBUF, …)/proc/sys/net/core/wmem_default用户空间缓冲区read/recv/recvfrom调用时你自己传的数组 代码里写多大就是多大二、地址重用 SO_REUSEADDR 的真实作用一句话让新进程可以立刻bind到“刚刚被关闭、仍处于 TIME_WAIT 的同一 IP:端口”重启服务不再报 “Address already in use”。UDP立竿见影多播/广播接收器常用无需等待。TCP仅解决 “TIME_WAIT 拖延复用”不能 创建真正重复的四元组。代码模板TCP/UDP 通用intfdsocket(AF_INET,SOCK_STREAM,0);/* 或 SOCK_DGRAM */inton1;setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,on,sizeof(on));三、多播组播到底该用哪个端口技术上 没有硬性限制只要避开系统/已知服务端口即可。推荐范围1024–65535 里任意空闲 UDP 端口。场景 常用端口示例路由协议 224.0.0.5:89OSPF车载、音视频 239.x.x.x 30000 以上局域网测试 8888、9999、22334防火墙/云主机注意安全组需放行 UDP 协议 你选定的端口部分云厂商把 135、445、5900 等列为高危端口避开即可。四、Linux UDP 多播最小可运行示例多播地址范围224.0.0.0–239.255.255.255本例用 224.1.1.1:8888。发送端 multicast_send.c#includestdio.h#includestring.h#includestdlib.h#includeunistd.h#includearpa/inet.h#includesys/socket.h#defineMULTICAST_IP224.1.1.1#defineMULTICAST_PORT8888#defineBUF_SIZE1024intmain(void){intsocksocket(AF_INET,SOCK_DGRAM,0);if(sock0){perror(socket);return-1;}structsockaddr_indst{.sin_familyAF_INET,.sin_porthtons(MULTICAST_PORT),.sin_addr.s_addrinet_addr(MULTICAST_IP)};unsignedcharttl2;/* 允许跨路由器 */setsockopt(sock,IPPROTO_IP,IP_MULTICAST_TTL,ttl,sizeof(ttl));charbuf[BUF_SIZE];while(fgets(buf,sizeof(buf),stdin)){sendto(sock,buf,strlen(buf),0,(structsockaddr*)dst,sizeof(dst));if(strncmp(buf,quit,4)0)break;}close(sock);return0;}接收端 multicast_recv.c#includestdio.h#includestring.h#includestdlib.h#includeunistd.h#includearpa/inet.h#includesys/socket.h#includenetinet/in.h#defineMULTICAST_IP224.1.1.1#defineMULTICAST_PORT8888#defineBUF_SIZE1024intmain(void){intsocksocket(AF_INET,SOCK_DGRAM,0);if(sock0){perror(socket);return-1;}intreuse1;setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,reuse,sizeof(reuse));structsockaddr_inlocal{.sin_familyAF_INET,.sin_porthtons(MULTICAST_PORT),.sin_addr.s_addrINADDR_ANY};if(bind(sock,(structsockaddr*)local,sizeof(local))0){perror(bind);return-1;}structip_mreqmreq{.imr_multiaddr.s_addrinet_addr(MULTICAST_IP),.imr_interface.s_addrINADDR_ANY};if(setsockopt(sock,IPPROTO_IP,IP_ADD_MEMBERSHIP,mreq,sizeof(mreq))0){perror(IP_ADD_MEMBERSHIP);return-1;}charbuf[BUF_SIZE];structsockaddr_insender;socklen_tsender_lensizeof(sender);while(1){ssize_tnrecvfrom(sock,buf,sizeof(buf)-1,0,(structsockaddr*)sender,sender_len);if(n0){perror(recvfrom);break;}buf[n]0;printf(recv from %s:%d %s,inet_ntoa(sender.sin_addr),ntohs(sender.sin_port),buf);if(strncmp(buf,quit,4)0)break;}setsockopt(sock,IPPROTO_IP,IP_DROP_MEMBERSHIP,mreq,sizeof(mreq));close(sock);return0;}编译与运行gcc multicast_send.c-osend gcc multicast_recv.c-orecv# 终端 1./recv# 终端 2./send同一网段可启动多个recv实例都能收到数据包。五、setsockopt 函数原型速查intsetsockopt(intsockfd,intlevel,/* SOL_SOCKET / IPPROTO_IP / IPPROTO_TCP … */intoptname,/* SO_REUSEADDR / SO_RCVBUF / TCP_NODELAY … */constvoid*optval,socklen_toptlen);示例一次把地址重用、接收缓冲区、TCP_NODELAY 全设好intfdsocket(AF_INET,SOCK_STREAM,0);inton1;setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,on,sizeof(on));intrcvbuf64*1024;setsockopt(fd,SOL_SOCKET,SO_RCVBUF,rcvbuf,sizeof(rcvbuf));setsockopt(fd,IPPROTO_TCP,TCP_NODELAY,on,sizeof(on));注意TCP_NODELAY仅限 TCPUDP 会返回-1。六、Linux 默认接收缓冲区到底多大查看当前系统值cat/proc/sys/net/core/rmem_default# 常见输出212992 约 208 KB不调用SO_RCVBUF时新建套接字的初始接收缓冲区 rmem_default现代主流发行版均为 208 KB不同内核可能略有差异。