锐捷交换机DNS Proxy配置实战:手把手教你用CLI搞定内网域名加速与安全过滤
2026/3/20 15:01:11
套接字(Socket)是网络通信的基础抽象,它就像是网络世界中的"电话插座"🔌,允许不同主机上的进程进行数据交换。在Linux系统中,套接字是应用层与TCP/IP协议族通信的中间软件抽象层,它提供了一组API,使得网络编程变得简单而统一。
套接字的核心特点:
| 类型 | 协议 | 可靠性 | 连接性 | 数据边界 | 典型应用 |
|---|---|---|---|---|---|
| 流式套接字(SOCK_STREAM) | TCP | 可靠 | 面向连接 | 无边界 | Web服务、SSH |
| 数据报套接字(SOCK_DGRAM) | UDP | 不可靠 | 无连接 | 有边界 | DNS、视频流 |
| 原始套接字(SOCK_RAW) | ICMP等 | - | - | - | 网络诊断工具 |
在Linux中创建套接字的基本流程:
socket()系统调用bind()(服务端必需)listen()(TCP服务端)accept()(TCP服务端)connect()(TCP客户端)send()/recv()或write()/read()close()// 创建TCP套接字示例intsockfd=socket(AF_INET,SOCK_STREAM,0);if(sockfd<0){perror("socket creation failed");exit(EXIT_FAILURE);}套接字编程中最重要的数据结构是sockaddr,Linux中常用的变体是sockaddr_in(IPv4)和sockaddr_in6(IPv6)。
structsockaddr_in{sa_family_tsin_family;// 地址族,如AF_INETin_port_tsin_port;// 端口号structin_addrsin_addr;// IP地址charsin_zero[8];// 填充字节};structin_addr{uint32_ts_addr;// IPv4地址(网络字节序)};网络通信需要使用网络字节序(大端序),而主机可能是小端序,因此需要进行转换:
// 主机序转网络序uint32_thtonl(uint32_thostlong);// 32位uint16_thtons(uint16_thostshort);// 16位// 网络序转主机序uint32_tntohl(uint32_tnetlong);uint16_tntohs(uint16_tnetshort);当需要同时处理多个套接字时,可以使用select/poll/epoll等I/O多路复用技术。
// epoll使用示例intepfd=epoll_create1(0);structepoll_eventev,events[MAX_EVENTS];ev.events=EPOLLIN;ev.data.fd=sockfd;epoll_ctl(epfd,EPOLL_CTL_ADD,sockfd,&ev);intnfds=epoll_wait(epfd,events,MAX_EVENTS,-1);for(intn=0;n<nfds;++n){if(events[n].data.fd==sockfd){// 处理事件}}通过setsockopt()可以设置各种套接字选项:
// 设置SO_REUSEADDR选项示例intoptval=1;setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&optval,sizeof(optval));常用选项:
SO_REUSEADDR:允许重用本地地址SO_KEEPALIVE:启用TCP保活机制TCP_NODELAY:禁用Nagle算法SO_RCVBUF/SO_SNDBUF:接收/发送缓冲区大小// 创建监听套接字intcreate_server_socket(intport){intsockfd=socket(AF_INET,SOCK_STREAM,0);structsockaddr_inserv_addr;memset(&serv_addr,0,sizeof(serv_addr));serv_addr.sin_family=AF_INET;serv_addr.sin_addr.s_addr=INADDR_ANY;serv_addr.sin_port=htons(port);bind(sockfd,(structsockaddr*)&serv_addr,sizeof(serv_addr));listen(sockfd,5);returnsockfd;}// 处理HTTP请求voidhandle_http_request(intclient_sock){charbuffer[1024];read(client_sock,buffer,sizeof(buffer)-1);// 解析HTTP请求charresponse[]="HTTP/1.1 200 OK\r\n""Content-Type: text/html\r\n""\r\n""<html><body><h1>Hello World!</h1></body></html>";write(client_sock,response,strlen(response));close(client_sock);}缓冲区大小调优:
intbufsize=64*1024;// 64KBsetsockopt(sockfd,SOL_SOCKET,SO_RCVBUF,&bufsize,sizeof(bufsize));使用sendfile()零拷贝:
sendfile(client_sock,file_fd,NULL,file_size);TCP_CORK/NODELAY选择:
TCP_NODELAY:禁用Nagle算法,适合实时性要求高的场景TCP_CORK:启用数据包聚合,适合批量发送场景| 工具 | 用途 |
|---|---|
| netstat | 查看套接字状态 |
| tcpdump | 抓包分析 |
| strace | 跟踪系统调用 |
| lsof | 查看进程打开的文件描述符 |
| ss | 更现代的套接字统计工具 |
INADDR_ANY,可能暴露所有接口// 设置连接数限制示例structrlimitlim={.rlim_cur=1000,.rlim_max=1000};setrlimit(RLIMIT_NOFILE,&lim);Linux套接字是网络编程的基石,掌握套接字编程需要理解:
通过本文的介绍和示例,希望读者能够建立起对Linux套接字编程的全面认识,并能够在实际项目中灵活应用这些知识。网络编程的世界广阔而精彩,套接字只是你探索之旅的起点!🚀
延伸阅读建议:
man 7 socket