定义一些常量和数据结构来存储用户信息和消息。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #define MAX_USERS 100 // 最大用户数 #define MAX_MESSAGE_LENGTH 256 // 最大消息长度 #define SERVER_PORT 8888 // 服务器端口 // 用户信息结构体 typedef struct { int id; struct sockaddr_in addr; int is_online; } User; // 消息结构体 typedef struct { User user; char message[MAX_MESSAGE_LENGTH]; } Message; // 用户数组 User users[MAX_USERS]; int user_count = 0; // 添加用户 void add_user(User user) { users[user_count++] = user; } // 移除用户 void remove_user(int id) { int i; for (i = 0; i < user_count; i++) { if (users[i].id == id) { users[i].is_online = 0; break; } } } // 发送消息给所有用户(除了发送者) void send_message_to_all(Message msg, int sender_id) { int i; for (i = 0; i < user_count; i++) { if (users[i].id != sender_id && users[i].is_online) { sendto(sockfd, &msg, sizeof(msg), 0, (struct sockaddr*)&users[i].addr, sizeof(users[i].addr)); } } }
服务器端的代码:
int main() { int sockfd; struct sockaddr_in server_addr, client_addr; socklen_t addr_len = sizeof(client_addr); Message msg; // 创建UDP socket if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("socket creation failed"); exit(EXIT_FAILURE); } // 设置服务器地址和端口 memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = htons(SERVER_PORT); // 绑定socket到服务器地址和端口 if (bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) { perror("bind failed"); exit(EXIT_FAILURE); } printf("Server is listening on port %d\n", SERVER_PORT); // 主循环接收消息 while (1) { // 接收客户端消息 if (recvfrom(sockfd, &msg, sizeof(msg), 0, (struct sockaddr*)&client_addr, &addr_len) == -1) { perror("recvfrom failed"); continue; } // 处理消息 // ... // 发送消息给所有用户(除了发送者) send_message_to_all(msg, msg.user.id); } close(sockfd); return 0; }
客户端的代码:
int main() { int sockfd; struct sockaddr_in server_addr; Message msg; // 创建UDP socket if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("socket creation failed"); exit(EXIT_FAILURE); } // 设置服务器地址和端口 memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = htons(SERVER_PORT); // 用户登录,发送登录消息给服务器 // ... // 创建接收消息的线程 // ... // 主循环发送消息 while (1) { // 读取用户输入的消息 // ... // 发送消息给服务器 sendto(sockfd, &msg, sizeof(msg), 0, (struct sockaddr*)&server_addr, sizeof(server_addr)); } close(sockfd); return 0; }