// server.c #include #include #include #include #include #include #include "protocol.h" #include "user.h" #define PORT 8888 #define MAX_USERS 100 #define MAX_CLIENTS 100 typedef struct { int sockfd; char username[MAX_NAME_LEN]; } Client; User users[MAX_USERS]; int user_count = 0; Client clients[MAX_CLIENTS]; int client_count = 0; pthread_mutex_t user_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t client_mutex = PTHREAD_MUTEX_INITIALIZER; // 查找在线客户端 int find_client(const char *username) { for (int i = 0; i < client_count; i++) { if (strcmp(clients[i].username, username) == 0) return i; } return -1; } // 处理客户端请求 void *client_handler(void *arg) { int sockfd = *(int *)arg; char curr_user[MAX_NAME_LEN] = ""; Message msg, reply; while (1) { int n = recv(sockfd, &msg, sizeof(msg), 0); if (n <= 0) break; memset(&reply, 0, sizeof(reply)); switch (msg.type) { case MSG_REGISTER: pthread_mutex_lock(&user_mutex); if (add_user(users, &user_count, msg.from, msg.data)) { save_users(users, user_count); reply.type = MSG_OK; } else { reply.type = MSG_FAIL; strcpy(reply.data, "用户名已存在"); } pthread_mutex_unlock(&user_mutex); send(sockfd, &reply, sizeof(reply), 0); break; case MSG_LOGIN: pthread_mutex_lock(&user_mutex); if (check_password(users, user_count, msg.from, msg.data)) { strcpy(curr_user, msg.from); pthread_mutex_lock(&client_mutex); strcpy(clients[client_count].username, curr_user); clients[client_count++].sockfd = sockfd; pthread_mutex_unlock(&client_mutex); reply.type = MSG_OK; } else { reply.type = MSG_FAIL; strcpy(reply.data, "用户名或密码错误"); } pthread_mutex_unlock(&user_mutex); send(sockfd, &reply, sizeof(reply), 0); break; case MSG_ADD_FRIEND: pthread_mutex_lock(&user_mutex); if (add_friend(users, user_count, curr_user, msg.to)) { save_users(users, user_count); reply.type = MSG_OK; } else { reply.type = MSG_FAIL; strcpy(reply.data, "添加好友失败"); } pthread_mutex_unlock(&user_mutex); send(sockfd, &reply, sizeof(reply), 0); break; case MSG_PRIVATE_CHAT: pthread_mutex_lock(&client_mutex); int idx = find_client(msg.to); if (idx != -1) { send(clients[idx].sockfd, &msg, sizeof(msg), 0); reply.type = MSG_OK; } else { reply.type = MSG_FAIL; strcpy(reply.data, "对方不在线"); } pthread_mutex_unlock(&client_mutex); send(sockfd, &reply, sizeof(reply), 0); break; default: break; } } // 客户端断开,移除 pthread_mutex_lock(&client_mutex); for (int i = 0; i < client_count; i++) { if (clients[i].sockfd == sockfd) { clients[i] = clients[--client_count]; break; } } pthread_mutex_unlock(&client_mutex); close(sockfd); return NULL; } int main() { int listenfd = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in servaddr = {0}; servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = INADDR_ANY; servaddr.sin_port = htons(PORT); bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); listen(listenfd, 5); user_count = load_users(users, MAX_USERS); printf("服务器启动,监听端口%d\n", PORT); while (1) { struct sockaddr_in cliaddr; socklen_t len = sizeof(cliaddr); int connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &len); pthread_t tid; pthread_create(&tid, NULL, client_handler, &connfd); pthread_detach(tid); } close(listenfd); return 0; }