C语言实现三线程TCP/IP通信:含数据包组合解析与心跳机制
以下是一个使用 C 语言实现的 TCP/IP 通信程序示例,包含了您要求的功能: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> // 数据包结构体 typedef struct { unsigned char header; unsigned char functionCode; unsigned char subFunctionCode; unsigned char placeholder; unsigned char dataLength; unsigned char data[4]; unsigned short checksum; unsigned char tail; } Packet; // 组合数据包函数 void composePacket(Packet *packet, unsigned char functionCode, unsigned char subFunctionCode, unsigned char *data) { packet->header = 0x00; packet->functionCode = functionCode; packet->subFunctionCode = subFunctionCode; packet->placeholder = 0x00; packet->dataLength = 4; memcpy(packet->data, data, 4); packet->checksum = 0xAAAA; packet->tail = 0xFF; } // 解析数据包函数 void parsePacket(Packet *packet, unsigned char *buffer) { packet->header = buffer[0]; packet->functionCode = buffer[1]; packet->subFunctionCode = buffer[2]; packet->placeholder = buffer[3]; packet->dataLength = buffer[4]; memcpy(packet->data, buffer + 5, 4); packet->checksum = *((unsigned short *)(buffer + 9)); packet->tail = buffer[11]; } // TCP1 服务器线程函数 void *tcp1ServerThread(void *arg) { int server_fd, new_socket; struct sockaddr_in address; int addrlen = sizeof(address); unsigned char buffer[12]; // 创建 TCP 套接字 if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("Socket creation failed"); pthread_exit(NULL); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(8080); // 绑定套接字 if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("Bind failed"); pthread_exit(NULL); } // 监听连接 if (listen(server_fd, 5) < 0) { perror("Listen failed"); pthread_exit(NULL); } printf("TCP1 Server is listening...\n"); while (1) { if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0) { perror("Accept failed"); continue; } // 接收数据 if (recv(new_socket, buffer, 12, 0) < 0) { perror("Receive failed"); close(new_socket); continue; } Packet packet; parsePacket(&packet, buffer); // 根据功能码和子功能码处理数据 if (packet.functionCode == 0x33 && packet.subFunctionCode == 0x27) { printf("Received valid data: %d\n", packet.data[0]); } // 处理心跳包 if (buffer[0] == 0x00 && buffer[1] == 0x00 && buffer[2] == 0xAA && buffer[3] == 0xFF) { send(new_socket, buffer, 4, 0); } close(new_socket); } close(server_fd); pthread_exit(NULL); } // TCP2 服务器线程函数 void *tcp2ServerThread(void *arg) { int server_fd, new_socket; struct sockaddr_in address; int addrlen = sizeof(address); unsigned char buffer[12]; // 创建 TCP 套接字 if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("Socket creation failed"); pthread_exit(NULL); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(8081); // 绑定套接字 if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("Bind failed"); pthread_exit(NULL); } // 监听连接 if (listen(server_fd, 5) < 0) { perror("Listen failed"); pthread_exit(NULL); } printf("TCP2 Server is listening...\n"); while (1) { if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0) { perror("Accept failed"); continue; } // 发送数据 Packet packet; unsigned char data[] = {0x01, 0x02, 0x03, 0x04}; composePacket(&packet, 0x33, 0x27, data); if (send(new_socket, (unsigned char *)&packet, 12, 0) < 0) { perror("Send failed"); close(new_socket); continue; } // 接收数据 if (recv(new_socket, buffer, 12, 0) < 0) { perror("Receive failed"); close(new_socket); continue; } // 处理心跳包 if (buffer[0] == 0x00 && buffer[1] == 0x00 && buffer[2] == 0xAA && buffer[3] == 0xFF) { send(new_socket, buffer, 4, 0); } close(new_socket); } close(server_fd); pthread_exit(NULL); } // UDP 服务器线程函数 void *udpServerThread(void *arg) { int sockfd; struct sockaddr_in servaddr, cliaddr; socklen_t len; unsigned char buffer[12]; // 创建 UDP 套接字 if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("Socket creation failed"); pthread_exit(NULL); } memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = INADDR_ANY; servaddr.sin_port = htons(8082); // 绑定套接字 if (bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) { perror("Bind failed"); pthread_exit(NULL); } printf("UDP Server is listening...\n"); while (1) { len = sizeof(cliaddr); // 接收数据 if (recvfrom(sockfd, buffer, 12, 0, (struct sockaddr *)&cliaddr, &len) < 0) { perror("Receive failed"); continue; } Packet packet; parsePacket(&packet, buffer); // 发送数据 Packet responsePacket; unsigned char responseData[] = {0x05, 0x06, 0x07, 0x08}; composePacket(&responsePacket, 0x33, 0x27, responseData); if (sendto(sockfd, (unsigned char *)&responsePacket, 12, 0, (struct sockaddr *)&cliaddr, len) < 0) { perror("Send failed"); continue; } } close(sockfd); pthread_exit(NULL); } int main() { pthread_t tcp1Thread, tcp2Thread, udpThread; // 创建线程 if (pthread_create(&tcp1Thread, NULL, tcp1ServerThread, NULL)!= 0) { perror("TCP1 thread creation failed"); return 1; } if (pthread_create(&tcp2Thread, NULL, tcp2ServerThread, NULL)!= 0) { perror("TCP2 thread creation failed"); return 1; } if (pthread_create(&udpThread, NULL, udpServerThread, NULL)!= 0) { perror("UDP thread creation failed"); return 1; } // 等待线程结束 pthread_join(tcp1Thread, NULL); pthread_join(tcp2Thread, NULL); pthread_join(udpThread, NULL); return 0; } ``` 这只是一个基本的示例程序,实际应用中可能需要更多的错误处理和优化。网络编程需要在适当的环境中进行测试和运行,确保服务器和客户端之间的网络连接正常。 ######[AI写代码神器 | 2157点数解答 | 2024-11-17 23:51:05]
- Python 实现 DES 加密算法编程实验:从原理到单步调试全解析(字节豆包 | 4096点数解答 | 2025-11-09 22:06:30)90
- 揭秘软件工程师视角:域名与 IP 一对多关系,一个 IP 能否对应多个域名? (百度文心 | 61点数解答 | 2023-11-09 18:19:12)391
- 车载系统 UML 类图设计:涵盖 Car、Engine、娱乐系统等的完整类定义与关系解析 (字节豆包 | 760点数解答 | 2024-08-15 22:51:04)332
- Python 实现球类:精准计算半径、表面积与体积,附输入验证与异常处理!(阿里通义 | 261点数解答 | 2024-11-28 21:19:39)384
- Java 状态模式:模拟 TCP 连接多种状态及行为转换(GPT | 2147点数解答 | 2024-12-19 22:19:37)314
- Java实现状态模式:模拟TCP连接状态管理及行为处理(GPT | 1541点数解答 | 2024-12-19 22:19:57)294
- Golang开发:解析JSON数据时数值默认类型及示例解析(百度文心 | 393点数解答 | 2023-11-09 18:13:06)312
- Python 字典基本操作全解析:创建、查找与遍历示例( | 313点数解答 | 2024-05-06 09:52:01)394
- SQL Working Areas Sizing: Manual vs. Automatic Policy - A Comprehensive Analysis(阿里通义 | 530点数解答 | 2024-05-13 10:55:58)331
- 贵州鑫盛科技:人才现状、困境与未来发展之路(字节豆包 | 851点数解答 | 2025-09-28 15:57:57)111
- C++ 实现正方形黑白瓦片图案最小转换方法求解(字节豆包 | 817点数解答 | 2025-11-25 19:03:09)85
- 51 单片机:定时器 0 实现 8 个 LED 循环点亮,附代码及优化建议(字节豆包 | 1193点数解答 | 2024-12-27 15:10:29)354