server.c
// server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>
#define MAX_CLIENTS 5
#define BUFFER_SIZE 1024
typedef struct dict_entry {
char word[64];
char meaning[256];
struct dict_entry *next;
} DictEntry;
DictEntry *dictionary = NULL;
void load_dictionary(const char *filename) {
FILE *fp = fopen(filename, "r");
if (!fp) {
perror("无法打开词典文件");
exit(EXIT_FAILURE);
}
char line[BUFFER_SIZE];
while (fgets(line, sizeof(line), fp)) {
// 去除换行符
line[strcspn(line, "\n")] = '\0';
char *word = strtok(line, " \t"); // 支持 tab 分隔
char *meaning = strtok(NULL, "\0"); // 剩余部分作为释义
if (word && meaning) {
DictEntry *entry = (DictEntry *)malloc(sizeof(DictEntry));
if (!entry) {
fprintf(stderr, "内存分配失败\n");
fclose(fp);
exit(EXIT_FAILURE);
}
strncpy(entry->word, word, sizeof(entry->word) - 1);
entry->word[sizeof(entry->word) - 1] = '\0';
strncpy(entry->meaning, meaning, sizeof(entry->meaning) - 1);
entry->meaning[sizeof(entry->meaning) - 1] = '\0';
entry->next = dictionary;
dictionary = entry;
}
}
fclose(fp);
printf("词典加载完成\n");
}
// 查找单词
const char *lookup_word(const char *word) {
DictEntry *current = dictionary;
while (current) {
if (strcmp(current->word, word) == 0) {
return current->meaning;
}
current = current->next;
}
return "Not found";
}
// 处理客户端请求
void *handle_client(void *arg) {
int client_socket = *((int *)arg);
char buffer[BUFFER_SIZE];
int bytes_read;
while ((bytes_read = recv(client_socket, buffer, sizeof(buffer) - 1, 0)) > 0) {
buffer[bytes_read] = '\0';
char *command = strtok(buffer, " ");
if (strcmp(command, "REGISTER") == 0) {
char *username = strtok(NULL, " ");
char *password = strtok(NULL, "\n");
printf("注册: 用户名=%s 密码=%s\n", username, password);
send(client_socket, "注册成功", strlen("注册成功"), 0);
} else if (strcmp(command, "LOGIN") == 0) {
char *username = strtok(NULL, " ");
char *password = strtok(NULL, "\n");
printf("登录: 用户名=%s 密码=%s\n", username, password);
send(client_socket, "登录成功", strlen("登录成功"), 0);
} else if (strcmp(command, "QUERY") == 0) {
char *word = strtok(NULL, "\n");
const char *response = lookup_word(word);
send(client_socket, response, strlen(response), 0);
}
}
close(client_socket);
pthread_exit(NULL);
}
int main() {
load_dictionary("dict.txt"); // <<< 关键:加载词典文件
int server_socket, client_socket;
struct sockaddr_in server_addr, client_addr;
socklen_t client_len = sizeof(client_addr);
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket < 0) {
perror("socket 创建失败");
exit(EXIT_FAILURE);
}
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(8080);
if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("bind 失败");
close(server_socket);
exit(EXIT_FAILURE);
}
listen(server_socket, MAX_CLIENTS);
printf("服务器启动,等待连接...\n");
while (1) {
client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_len);
if (client_socket < 0) {
perror("accept 失败");
continue;
}
pthread_t thread;
pthread_create(&thread, NULL, handle_client, &client_socket);
pthread_detach(thread);
}
close(server_socket);
return 0;
}
client.c
// client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define BUFFER_SIZE 1024
int main() {
int sock;
struct sockaddr_in server_addr;
char buffer[BUFFER_SIZE];
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("Socket 创建失败");
exit(EXIT_FAILURE);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080);
inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr);
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("连接失败");
close(sock);
exit(EXIT_FAILURE);
}
int is_logged_in = 0;
while (1) {
printf("请选择操作 (%s): ", is_logged_in ? "3.查询 4.退出" : "1.注册 2.登录 4.退出");
int choice;
scanf("%d", &choice);
getchar(); // 清除换行符
if (!is_logged_in && choice == 1) {
char username[64], password[64];
printf("请输入用户名: ");
fgets(username, sizeof(username), stdin);
username[strcspn(username, "\n")] = '\0';
printf("请输入密码: ");
fgets(password, sizeof(password), stdin);
password[strcspn(password, "\n")] = '\0';
char request[BUFFER_SIZE];
snprintf(request, sizeof(request), "REGISTER %s %s", username, password);
send(sock, request, strlen(request), 0);
int bytes_read = recv(sock, buffer, sizeof(buffer) - 1, 0);
if (bytes_read > 0) {
buffer[bytes_read] = '\0';
printf("响应: %s\n", buffer);
}
} else if (!is_logged_in && choice == 2) {
char username[64], password[64];
printf("请输入用户名: ");
fgets(username, sizeof(username), stdin);
username[strcspn(username, "\n")] = '\0';
printf("请输入密码: ");
fgets(password, sizeof(password), stdin);
password[strcspn(password, "\n")] = '\0';
char request[BUFFER_SIZE];
snprintf(request, sizeof(request), "LOGIN %s %s", username, password);
send(sock, request, strlen(request), 0);
int bytes_read = recv(sock, buffer, sizeof(buffer) - 1, 0);
if (bytes_read > 0) {
buffer[bytes_read] = '\0';
printf("响应: %s\n", buffer);
is_logged_in = 1;
}
} else if (is_logged_in && choice == 3) {
char word[64];
printf("请输入要查询的单词: ");
fgets(word, sizeof(word), stdin);
word[strcspn(word, "\n")] = '\0';
char request[BUFFER_SIZE];
snprintf(request, sizeof(request), "QUERY %s", word);
send(sock, request, strlen(request), 0);
int bytes_read = recv(sock, buffer, sizeof(buffer) - 1, 0);
if (bytes_read > 0) {
buffer[bytes_read] = '\0';
printf("释义: %s\n", buffer);
}
} else if (choice == 4) {
printf("退出\n");
break;
} else {
printf("无效选项\n");
}
}
close(sock);
return 0;
}
Makfile
CC = gcc
CFLAGS = -Wall -Wextra -g -pthread # -pthread 支持线程
SRC = main.c
OBJ = $(SRC:.c=.o)
BIN = dictionary_server
all: $(BIN)
$(BIN): $(OBJ)
$(CC) $(CFLAGS) $(OBJ) -o $@
clean:
rm -f $(OBJ) $(BIN)
run: $(BIN)
./$(BIN)
install:
cp $(BIN) /usr/local/bin/
检查一下