计算机网络是现代IT技术的基石,而Linux系统凭借其稳定性和开放性,成为网络编程的首选平台。本文将带你从零开始,理解Linux网络编程的核心概念,并手把手实现基于Socket套接字的TCP协议与UDP协议通信程序。即使你只有C语言基础,也能轻松跟上!
在开始编程前,我们需要了解数据如何通过网络传输。国际标准化组织(ISO)提出了OSI七层模型,但实际工业标准是简化的TCP/IP四层模型:应用层、传输层、网络层、网络接口层。其中传输层主要有两大协议:TCP协议(传输控制协议)和UDP协议(用户数据报协议)。
Socket套接字是应用层与传输层之间的抽象接口,它封装了复杂的网络通信细节。在Linux中,一切皆文件,Socket也是一种文件描述符,通过标准的read()/write()或专用的send()/recv()进行操作。常见的Socket类型有:SOCK_STREAM(面向连接的TCP)和SOCK_DGRAM(无连接的UDP)。
TCP协议提供面向连接的、可靠的字节流服务。它通过三次握手建立连接,确保数据无差错、不丢失、不重复,且按序到达。适合文件传输、网页浏览等场景。UDP协议则是无连接的,尽最大努力交付,但不保证可靠性。它实时性高、开销小,适合视频直播、DNS查询等场景。理解两者的区别是Linux网络编程的基本功。
以下代码演示了TCP和UDP的最简通信过程。所有函数均可在Linux man pages中查阅。
#include #include #include #include #include #define PORT 8888int main() { int server_fd, client_fd; struct sockaddr_in address; int opt = 1; int addrlen = sizeof(address); char buffer[1024] = {0}; // 1. 创建Socket套接字 if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); return -1; } // 2. 绑定端口 address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("bind failed"); return -1; } // 3. 监听连接 if (listen(server_fd, 3) < 0) { perror("listen"); return -1; } // 4. 接受客户端连接 if ((client_fd = accept(server_fd, (struct sockaddr )&address, (socklen_t)&addrlen)) < 0) { perror("accept"); return -1; } // 5. 读写数据 read(client_fd, buffer, 1024); printf("收到消息: %s", buffer); send(client_fd, buffer, strlen(buffer), 0); printf("回显完成"); close(client_fd); close(server_fd); return 0;} #include #include #include #include #include #define PORT 8888int main() { int sock; struct sockaddr_in serv_addr; char *hello = "Hello from client"; char buffer[1024] = {0}; // 1. 创建Socket if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket error"); return -1; } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); // 将服务器IP地址转换为二进制 if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) { perror("inet_pton error"); return -1; } // 2. 连接服务器 if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { perror("connect failed"); return -1; } // 3. 发送数据 send(sock, hello, strlen(hello), 0); printf("消息已发送"); read(sock, buffer, 1024); printf("服务器回显: %s", buffer); close(sock); return 0;} #include #include #include #include #include #define PORT 8888int main() { int sockfd; char buffer[1024]; struct sockaddr_in servaddr, cliaddr; // 1. 创建UDP Socket if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket creation failed"); return -1; } memset(&servaddr, 0, sizeof(servaddr)); memset(&cliaddr, 0, sizeof(cliaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = INADDR_ANY; servaddr.sin_port = htons(PORT); // 2. 绑定端口 if (bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) { perror("bind failed"); return -1; } int len = sizeof(cliaddr); int n = recvfrom(sockfd, (char *)buffer, 1024, MSG_WAITALL, (struct sockaddr *)&cliaddr, &len); buffer[n] = " "; printf("收到客户端消息: %s", buffer); sendto(sockfd, (const char *)buffer, strlen(buffer), MSG_CONFIRM, (const struct sockaddr *)&cliaddr, len); printf("回显完成"); close(sockfd); return 0;} 以上代码展示了最基础的Socket套接字编程流程。实际项目中还需处理多线程、错误重传等细节,但掌握这些就迈出了Linux网络编程的第一步。
本文从计算机网络模型出发,介绍了Socket套接字的作用,对比了TCP协议与UDP协议的特性,并给出了完整的C语言编程实例。希望你能动手编译运行这些代码,加深对Linux网络编程的理解。记住,理论结合实践才是最好的学习方式!
本文由主机测评网于2026-03-12发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://vpshk.cn/20260330767.html