#include "server.h"
char client_usernames[MAX_CLIENTS][64];
sqlite3 *db;
// 全局用户登录状态数组
UserLoginStatus user_status[MAX_CLIENTS]; // 假设在 server.h 中定义
int handle_client(int client_idx, int client_fd) {
char buffer[BUFFER_SIZE];
int bytes_read = read(client_fd, buffer, sizeof(buffer) - 1);
if (bytes_read <= 0) {
printf("客户端断开链接 %d\n", client_fd);
// 清除登录状态
if (client_usernames[client_idx][0] != '\0') {
for (int i = 0; i < MAX_CLIENTS; i++) {
if (user_status[i].logged_in && strcmp(user_status[i].username, client_usernames[client_idx]) == 0) {
user_status[i].logged_in = 0;
user_status[i].username[0] = '\0';
break;
}
}
}
client_usernames[client_idx][0] = '\0';
return -1;
}
buffer[bytes_read] = '\0';
char cmd[16] = {0};
sscanf(buffer, "%15s", cmd); // 限制命令长度
if (strcmp(cmd, "F") == 0) { // 处理模糊查询命令
char *prefix = buffer + 2; // 跳过命令和空格
while (*prefix == ' ') prefix++;
char result[BUFFER_SIZE * 10]; // 结果缓冲区
fuzzy_search(prefix, result, sizeof(result));
write(client_fd, result, strlen(result)); // 发送匹配结果
write(client_fd, "END_FUZZY", strlen("END_FUZZY") + 1); // 发送结束标记
}
if (strcmp(cmd, "L") == 0) {
char username[64] = {0}, password[64] = {0};
sscanf(buffer + 2, "%63s %63s", username, password); // 去掉命令部分,限制长度
int user_id = login_user(db, username, password);
if (user_id > 0) {
// 检查是否已登录
int already_logged_in = 0;
for (int i = 0; i < MAX_CLIENTS; i++) {
if (user_status[i].logged_in && strcmp(user_status[i].username, username) == 0) {
already_logged_in = 1;
break;
}
}
if (already_logged_in) {
write(client_fd, "Already logged in", strlen("Already logged in") + 1);
return 0;
}
// 设置当前客户端登录状态
strncpy(client_usernames[client_idx], username, 63);
user_status[client_idx].logged_in = 1;
strncpy(user_status[client_idx].username, username, 63);
write(client_fd, "Login successful", strlen("Login successful") + 1);
} else {
write(client_fd, "Login failed", strlen("Login failed") + 1);
}
} else if (strcmp(cmd, "R") == 0) {
char username[64] = {0}, password[64] = {0};
sscanf(buffer + 2, "%63s %63s", username, password);
if (register_user(db, username, password)) {
strncpy(client_usernames[client_idx], username, 63);
write(client_fd, "Registration successful", strlen("Registration successful") + 1);
} else {
write(client_fd, "Username already exists", strlen("Username already exists") + 1);
}
} else if (strcmp(cmd, "Q") == 0) {
if (strlen(client_usernames[client_idx]) == 0) {
write(client_fd, "Please login first", strlen("Please login first") + 1);
return 0;
}
char *word_start = buffer + 2; // Skip "Q "
while (*word_start == ' ') word_start++; // Skip spaces
char word[64];
sscanf(word_start, "%63s", word); // 支持空格前跳过,但单词不能含空格
const char *meaning = search_meaning(word);
write(client_fd, meaning, strlen(meaning) + 1);
// 获取用户ID
sqlite3_stmt *stmt;
const char *sql = "SELECT id FROM users WHERE username = ?;";
if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, client_usernames[client_idx], -1, SQLITE_STATIC);
if (sqlite3_step(stmt) == SQLITE_ROW) {
int user_id = sqlite3_column_int(stmt, 0);
log_query(db, user_id, word, meaning);
}
sqlite3_finalize(stmt);
}
} else if (strcmp(cmd, "H") == 0) {
if (strlen(client_usernames[client_idx]) == 0) {
write(client_fd, "Please login first", strlen("Please login first") + 1);
return 0;
}
sqlite3_stmt *stmt;
const char *sql = "SELECT id FROM users WHERE username = ?;";
if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, client_usernames[client_idx], -1, SQLITE_STATIC);
if (sqlite3_step(stmt) == SQLITE_ROW) {
int user_id = sqlite3_column_int(stmt, 0);
send_history(db, client_fd, user_id);
}
sqlite3_finalize(stmt);
}
} else if (strcmp(cmd, "E") == 0) {
// 客户端主动退出,清除登录状态
if (client_usernames[client_idx][0] != '\0') {
for (int i = 0; i < MAX_CLIENTS; i++) {
if (user_status[i].logged_in && strcmp(user_status[i].username, client_usernames[client_idx]) == 0) {
user_status[i].logged_in = 0;
user_status[i].username[0] = '\0';
break;
}
}
client_usernames[client_idx][0] = '\0';
}
return 1;
} else {
write(client_fd, "Unknown command", strlen("Unknown command") + 1);
}
return 0;
}
请根据client_handlie模块代码修改main.c代码
#include "server.h"
char client_usernames[MAX_CLIENTS][64] = {0};
UserLoginStatus user_status[MAX_CLIENTS] = {0}; // 初始化为0
sqlite3 *db;
int main() {
init_clients();
if (init_database(&db) != 0) {
fprintf(stderr, "初始化数据库失败\n");
return 1;
}
if (load_dictionary() != 0) {
fprintf(stderr, "加载词典失败\n");
sqlite3_close(db);
return 1;
}
int server_fd = start_server(PORT);
accept_clients(server_fd);
sqlite3_close(db);
close(server_fd);
return 0;
}