Linux/Project/新建文件夹/Server_Cursor.c

138 lines
4.2 KiB
C
Raw Normal View History

2025-06-10 23:43:56 +08:00
// server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <netinet/in.h>
#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;
}