基于socket的电子词典

1.介绍

这是一个没有图形界面的电子词典,以下是实现的功能

1.服务器多线程同时连接多个客户端
2.用户注册
3.用户登录
4.查询单词
5.收藏单词
6.查询当前用户的历史搜索记录
7.查询当前用户的收藏记录
8.退出电子辞典

记得创建以下三个数据表

表格结构如下

哦对,词典的话网上找个txt文档就好了

附上服务器端与客户端代码

2.服务器端代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sqlite3.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/time.h>
#define MAX_CLIENTS 10
#define MAX_WORD_SIZE 100
#define MAX_DEFINITION_SIZE 512


void *handle_client(void *arg);


int clients[MAX_CLIENTS];
int client_count = 0;
char definition[MAX_DEFINITION_SIZE];
sqlite3* mydb = NULL; 
char user_id[20];//登陆了的账户密码
char user_pwd[16];
int falg;

/**
 * 功能:接收注册的账号密码
*/
void recv_register(int newSocket)
{
    char** resultp;
    int row; 
    int column;
    char id[20];//注册时的账户密码
    char password[16];
    //接收账号
    memset(id,0,sizeof(id));
    recv(newSocket,id, sizeof(id), 0);
    //接收密码
    memset(password,0,sizeof(password));
    recv(newSocket,password, sizeof(password), 0);
    //检测账号是否重复
    char regbuffer[256] = "select * from dict_user;";
    sqlite3_get_table(mydb,regbuffer,&resultp,&row,&column,NULL);
    memset(regbuffer,0,sizeof(regbuffer));
    for(int i=0;i<(row+1)*column;i++){

        if(strcmp(id,resultp[i])==0){//账号重复
            char a[6] = "-1";
            send(newSocket,a,strlen(a),0);
            return;
        }
    }
    memset(regbuffer,0,256);
    snprintf(regbuffer,256,"insert into dict_user(id,password)values('%s','%s');",id,password); 
    if(strlen(id)<16 && strlen(regbuffer) <7)
    {
        char b[6] = "-2";
        send(newSocket,b,strlen(b), 0);
        return ;
    }
    sqlite3_get_table(mydb,regbuffer,&resultp,&row,&column,NULL);
    char c[6] = "1";
    send(newSocket,c,strlen(c), 0);
    memset(regbuffer,0,sizeof(regbuffer));
}

/**
 * 功能:登录
*/
void recv_user_log(int newSocket)
{
    char** resultp;
    int row; 
    int column;
    int id_count=0;//用于判断用户名是否正确
    int pwd_count = 0;//密码
    //接收账号
    memset(user_id,0,sizeof(user_id));
    recv(newSocket,user_id, sizeof(user_id), 0);
    //接收账号
    memset(user_pwd,0,sizeof(user_pwd));
    recv(newSocket,user_pwd, sizeof(user_pwd), 0);
    //检测账号是否存在
    char regbuffer[256];
    snprintf(regbuffer,sizeof(regbuffer),"select * from dict_user where id='%s' and password='%s';",user_id,user_pwd);
    sqlite3_get_table(mydb,regbuffer,&resultp,&row,&column,NULL);
    memset(regbuffer,0,sizeof(regbuffer));
    for(int i=0;i<(row+1)*column;i++){
        if(strcmp(user_id,resultp[i])==0){//账号存在
            id_count += 1;
        }
        if(strcmp(user_pwd,resultp[i])==0)//密码正确
        {
            pwd_count += 1;
        }
    }
    if(id_count == 1 && pwd_count == 1)
    {
        char a[6] = "1";
        send(newSocket,a,strlen(a),0);
        return;
    }   
    if(id_count != 1)
    {
        char b[6] = "-1";
        send(newSocket,b,strlen(b), 0);
        return ;
    }
    if(id_count != 1 && pwd_count != 1)
    {
        char c[6] = "-2";
        send(newSocket,c,strlen(c), 0);
    }
    memset(regbuffer,0,sizeof(regbuffer));
}
/**
 * 功能;收藏单词
*/

void searchWord(const char *filename,char *targetWord,int newSocket) {
    char** resultp;
    int row; 
    int column;
    char buffer[1024];
    char input[6];//是否收藏
    FILE *file = fopen(filename, "r");
    if (file == NULL) {
        perror("Error opening file");
        return;
    }

    char currentWord[MAX_WORD_SIZE];
    
    memset(buffer,0,sizeof(buffer));
    memset(currentWord,0,sizeof(currentWord));
    memset(definition,0,sizeof(definition));
    while (fscanf(file, "%s %[^\n]", currentWord, definition) == 2) {
        if (strcmp(currentWord, targetWord) == 0) {
            recv(newSocket, input, sizeof(input), 0);
            if(strcmp(input,"yes") == 0)
            {
                snprintf(buffer,sizeof(buffer),"insert into collect(id,word,definition)values('%s','%s','%s');",user_id,currentWord,definition);
                sqlite3_get_table(mydb,buffer,&resultp,&row,&column,NULL);
                memset(buffer,0,sizeof(buffer));
            }
            send(newSocket,definition,strlen(definition),0);

            snprintf(buffer,sizeof(buffer),"insert into record(id,word,definition)values('%s','%s','%s');",user_id,currentWord,definition);
            sqlite3_get_table(mydb,buffer,&resultp,&row,&column,NULL);
            printf("单词:%s\n解释:%s\n", currentWord, definition);
            fclose(file);
            memset(targetWord,0,sizeof(targetWord));
            return; // 找到了,可以选择退出循环或函数
        }
    }
    memset(targetWord,0,sizeof(targetWord));
    send(newSocket, "1",2, 0);//传输单词
    printf("单词 \"%s\" 未在字典中找到。\n", targetWord);

    fclose(file);
}

/**
 * 功能查询历史记录并返回
*/
void select_reword(int newSocket)
{
    char** resultp;
    int row; 
    int column;
    char buffer[124];
    char buffer1[4096];
    memset(buffer1,0,sizeof(buffer1));
    memset(buffer,0,sizeof(buffer));
    snprintf(buffer,sizeof(buffer),"select * from record where id = '%s'",user_id);
    sqlite3_get_table(mydb,buffer,&resultp,&row,&column,NULL);
    for(int i=0;i<(row+1)*column;i++)
	{
        strcat(buffer1, resultp[i]);//拼接字符串
        strcat(buffer1, "\t\t"); // 使用制表符分隔

        if((i+1)%column == 0)//这里是换行,每当下标i取模列为0的时候换行
        {
            strcat(buffer1, "\n");//换行
        }
	}
    send(newSocket,buffer1,sizeof(buffer1), 0);//传输单词
}


/**
 * 功能:查询收藏记录并返回
*/
void collect_word(int newSocket)
{
    char** resultp;
    int row; 
    int column;
    char buffer[124];
    char buffer1[4096];
    memset(buffer1,0,sizeof(buffer1));
    memset(buffer,0,sizeof(buffer));
    snprintf(buffer,sizeof(buffer),"select * from collect where id = '%s'",user_id);
    sqlite3_get_table(mydb,buffer,&resultp,&row,&column,NULL);
    for(int i=0;i<(row+1)*column;i++)
	{
        strcat(buffer1, resultp[i]);//拼接字符串
        strcat(buffer1, "\t\t"); // 使用制表符分隔

        if((i+1)%column == 0)//这里是换行,每当下标i取模列为0的时候换行
        {
            strcat(buffer1, "\n");//换行
        }
	}
    send(newSocket,buffer1,sizeof(buffer1), 0);//传输单词
}


int main(int argc, char **argv) {

    //打开数据库文件	
	int ret = sqlite3_open("./dict_select.db", &mydb);


	if(ret != 0)
	{
		perror("opendb failed");
		return -1;
	}
   
    int serverSocket, newSocket;

    
    struct sockaddr_in serverAddr, newAddr;
    socklen_t addr_size;
    

    // 创建服务器套接字
    serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (serverSocket < 0) {
        perror("服务器套接字创建失败");
        exit(1);
    }
    printf("服务器套接字创建成功\n");

    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port =htons(12345);//htons(atoi(argv[2]))
    serverAddr.sin_addr.s_addr = inet_addr("192.168.124.138");//INADDR_ANY;//inet_addr(argv[1])

    // 绑定服务器套接字
    if (bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
        perror("绑定失败");
        exit(1);
    }
    printf("绑定成功\n");

    // 监听连接
    if (listen(serverSocket, 10) == 0) {
        printf("监听中...\n");
    } else {
        printf("监听失败\n");
    }

    // 接受客户端连接并创建线程
    while (1) {
        
        addr_size = sizeof(newAddr);
        newSocket = accept(serverSocket, (struct sockaddr *)&newAddr, &addr_size);

        if (client_count < MAX_CLIENTS) {
            pthread_t tid;
            clients[client_count] = newSocket;
            pthread_create(&tid, NULL, handle_client, &newSocket);
            client_count++;
        } else {
            printf("客户端连接达到最大限制,拒绝连接\n");
            close(newSocket);
        }
    }

    return 0;
}

void *handle_client(void *arg) {
    int newSocket = *((int *)arg);
    char buffer[24];
    char regbuffer[4];  

    while (1) {
        memset(regbuffer,0,sizeof(regbuffer));
        recv(newSocket, regbuffer, sizeof(regbuffer), 0);
        falg = atoi(regbuffer);
        printf("执行:%d号操作\n",falg);
        switch(falg)
        {
            case 0:
            recv_register(newSocket);
            break;
            case 1:
            recv_user_log(newSocket);
            break;
            case 2:
            recv(newSocket, buffer, sizeof(buffer), 0);
            searchWord("dict.txt",buffer,newSocket);
            break;
            case 3:
            collect_word(newSocket);
            break;
            case 4:
            select_reword(newSocket);
            break;
        }
     if(falg == 5)
     {
        break;
     }
     
    }
}

3.客户端代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sqlite3.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/time.h>

int clientSocket;
struct sockaddr_in serverAddr;
char buffer[2048];

/**
 * 功能:登录注册菜单
*/
void menu(void)
{
    printf("*********************************************\n");
    printf("*                  0.注册                  *\n");
    printf("*                  1.登录                   *\n");
    printf("*********************************************\n");
    printf("*********************************************\n");
}

void menu2(void)
{
    printf("*********************************************\n");
    printf("2.查询单词释义                                \n");
    printf("3.查询收藏单词                                  \n");
    printf("4.查询搜索记录                               \n");
    printf("5.退出                                       \n");
    printf("*********************************************\n");
}
/**
 * 功能:用户注册
*/
void user_register(void)
{
    char id[20];
    char password[16];
    char regbuffer[20];
    memset(regbuffer,0,20);

    memset(id,0,sizeof(id));
    printf("请输入用户名:");
    scanf("%s",id);
    //发送账号
    send(clientSocket,id,strlen(id), 0);

    memset(password,0,sizeof(password));
    printf("请输入密码:");
    scanf("%s",password);
    //发送密码
    send(clientSocket, password, strlen(password), 0);
    
    recv(clientSocket, regbuffer, sizeof(regbuffer), 0);
    if(strcmp(regbuffer,"1") == 0)
        {
            printf("注册成功!\n");
        }
    if(strcmp(regbuffer,"-1") == 0)    
        {
            printf("注册失败,账户重复!\n");
        }
    if(strcmp(regbuffer,"-2") == 0)
    {
        printf("账户或密码长度不正确。请输入16位以下账户和7位以下密码\n");
    }
}

/**
 * 功能:用户登录
 * 
*/
int user_log(void)
{
    char id[20];
    char password[16];
    char regbuffer[20];
    memset(regbuffer,0,20);

    memset(id,0,sizeof(id));
    printf("请输入用户名:");
    scanf("%s",id);
    //发送账号
    send(clientSocket,id,strlen(id), 0);

    memset(password,0,sizeof(password));
    printf("请输入密码:");
    scanf("%s",password);
    //发送密码
    send(clientSocket, password, strlen(password), 0);
    
    recv(clientSocket, regbuffer, sizeof(regbuffer), 0);
    if(strcmp(regbuffer,"1") == 0)
        {
            printf("登录成功!\n");
            return 1;
        }
    if(strcmp(regbuffer,"-1") == 0)    
        {
            printf("登录失败,用户名不存在!\n");
        }
    if(strcmp(regbuffer,"-2") == 0)
    {
        printf("登录失败,用户名或密码错误\n");
    }
}
/**
 * 功能:查询单词
*/
void select_word(void)
{
    char buffer[24],definition[1024],input[6];
    printf("请输入你要查询的单词:");
    memset(buffer,0,sizeof(buffer));
    scanf("%s",buffer);
    send(clientSocket, buffer, strlen(buffer), 0);//传输单词
    printf("是否收藏该代词(yes/no):");
    scanf("%s",input);
    if(strcmp(input,"yes") == 0)
    {
        send(clientSocket, input, strlen(input), 0);
        printf("收藏成功!\n");
    }else
    {
        printf("收藏失败!");
    }

    memset(definition,0,sizeof(definition));
    int word_count = recv(clientSocket,definition, sizeof(definition), 0);
    if(strlen(definition) > 2)
    {
        printf("单词为:%s\n",buffer);
        printf("释义为:%s\n",definition);
    }
    else
    {
        printf("单词不存在\n");
    }
}

/**
 * 功能:历史记录
*/
void select_reword(void)
{
    char buffer[4096];
    memset(buffer,0,sizeof(buffer));
    recv(clientSocket, buffer, sizeof(buffer), 0);
    printf("%s",buffer);
}

/**
 * 功能:收藏记录
*/
void collect_word(void)
{
    char buffer[4096];
    memset(buffer,0,sizeof(buffer));
    recv(clientSocket, buffer, sizeof(buffer), 0);
    printf("%s",buffer);
}


int dict_sekect_menu(void)
{
    char falg[5];
    while(1)
    {
        menu2();
        printf("请输入您要执行的操作:");
        scanf("%s",falg);
        
        switch(atoi(falg))
        {
            case 2:
            send(clientSocket, falg, strlen(falg), 0);
            select_word();
            break;
            
            case 3:
            send(clientSocket, falg, strlen(falg), 0);
            collect_word();
            break;
            case 4:
            send(clientSocket, falg, strlen(falg), 0);
            select_reword();
            break;
            case 5:
            break;
            default:
            printf("输入有误,请选择合法输入\n");
        }
        if(atoi(falg) == 5)
        {
            return 0;
        }
    }
}


int main(int argc,char** argv) {
    
    int exit1;
    char cfalg[5];
    // 创建客户端套接字
    clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (clientSocket < 0) {
        perror("套接字创建失败");
        exit(1);
    }
    printf("客户端套接字创建成功\n");

    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(12345);
    serverAddr.sin_addr.s_addr = inet_addr("192.168.124.138");

    // 连接到服务器
    if (connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
        perror("连接失败");
        exit(1);
    }
    printf("连接成功\n");

    while (1) {
            memset(cfalg,0,sizeof(cfalg));
            //登录与注册界面
            menu();
            printf("请输入您要执行的操作:");
            scanf("%s",cfalg);
            
            
            //登录和注册
            switch(atoi(cfalg))
            {
                
                //注册
                case 0:
                send(clientSocket, cfalg, strlen(cfalg), 0);
                user_register();
                break;
                //登录账号
                case 1:
                send(clientSocket, cfalg, strlen(cfalg), 0);
                int ret = user_log();
                if(ret == 1)
                {
                     exit1 = dict_sekect_menu();
                }
                break;
                case 5:
                break;
                default:
                printf("输入错误,请输入合法选项\n");
            }
            if(exit1 == 0)
            {
                send(clientSocket, "5", strlen("5"), 0);
                printf("退出成功!\n");
                break;
            }
        }
        
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

语文同步练习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值