服务器代码
头文件
#ifndef __FUNCTION_H__
#define __FUNCTION_H__
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/wait.h>
#include <sqlite3.h>
#include <time.h>
//宏定义IP和端口号
#define IP "192.168.8.120"
#define PORT 4444
#define N 200
//宏函数包装一个带行号的错误提示
#define ERR_MSG(msg) do{
\
fprintf(stderr,"__%d__", __LINE__);\
perror(msg);\
}while(0)
//传递信息给线程
struct msg
{
int fd;
struct sockaddr_in cin;
};
//和客户端交互的结构体
struct message
{
char flag;
char name[20];
char info[128];
};
//初始化数据库
int database_init(sqlite3* db);
//将文件中的单词插入到表中
int do_insert(sqlite3* db);
//初始化套接字
int socket_init();
//处理客户端请求
int deal_cli(int sfd);
//处理交互信息的线程
void* deal_cli_msg(void* arg);
//处理注册请求
int register_m(int newfd, struct message buf, sqlite3* db);
//处理登录请求
int login(int newfd, struct message buf, sqlite3* db);
//处理查询单词请求
int query(int newfd, struct message buf, sqlite3* db, char* name);
//查询历史信息
int history(int newfd, struct message buf, sqlite3* db);
//退出登录
int login_out(sqlite3* db, char* name);
//发送错误标志
int err(int newfd);
#endif
main函数
#include "function.h"
int main(int argc, const char *argv[])
{
//数据库初始化
sqlite3* db = NULL;
if(database_init(db) < 0 )
return -1;
//网络初始化
int sfd = socket_init();
if(sfd < 0)
return -1;
//处理客户端请求
if(deal_cli(sfd) < 0)
return -1;
//关闭数据库
if(sqlite3_close(db) != SQLITE_OK)
{
fprintf(stderr, "line:%d sqlite3_close:%s\n", __LINE__, sqlite3_errmsg(db));
return -1;
}
printf("数据库成功关闭\n");
return 0;
}
//初始化套接字
int socket_init()
{
//创建流式套接字
int sfd = socket(AF_INET, SOCK_STREAM, 0);
if(sfd < 0)
{
ERR_MSG("socket");
return -1;
}
printf("socket create success\n");
//设置端口快速重用
int reuse = 1;
if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
{
ERR_MSG("setsockopt");
return -1;
}
//填充服务器的IP地址以及端口号
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
//绑定服务器的地址信息结构体
if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0 )
{
ERR_MSG("bind");
return -1;
}
printf("bind success\n");
//将套接字设置为被动监听状态,让内核去监听是否有客户端连接
if(listen(sfd, 10) < 0)
{
ERR_MSG("listen");
return -1;
}
printf("listen success\n");
return sfd;
}
功能函数
数据库初始化
#include "function.h"
//初始化数据库
int database_init(sqlite3* db)
{
//用于判断是否导入单词文件到数据库
int flag = 0;
//创建数据库
if(sqlite3_open("dict.db", &db) != SQLITE_OK)
{
fprintf(stderr, "line:%d sqlite3_open:%s\n", __LINE__, sqlite3_errmsg(db));
return -1;
}
printf("数据库创建成功\n");
//创建单词表
char sql[128] = "create table dictionary (_word char, means char);";
char* errmsg = NULL;
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) !=SQLITE_OK)
{
//如果错误是已经存在该单词表就置flag为1,后面就不再导入单词文件
if(1 == sqlite3_errcode(db))
{
flag = 1;
}
else
{
fprintf(stderr, "line:%d sqlite3_exec:%s errcode = %d\n", __LINE__, errmsg, sqlite3_errcode(db));
return -1;
}
}
//将所给的单词文件录入到数据库中
if(flag == 0)
{
if(do_insert(db)< 0)
{
fprintf(stderr, "line:%d sqlite3_exec:%s\n", __LINE__, errmsg);
return -1;
}
}
//创建用户表
bzero(sql, sizeof(sql));
strcpy(sql,"create table if not exists usr (name char primary key, password char, stat char)");
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) !=SQLITE_OK)
{
fprintf(stderr, "line:%d sqlite3_exec:%s\n", __LINE__, errmsg);
return -1;
}
//创建用户信息表
bzero(sql, sizeof(sql));
strcpy(sql,"create table if not exists usr_info (name char, _word char, means char, time char)");
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) !=SQLITE_OK)
{
fprintf(stderr, "line:%d sqlite3_exec:%s\n", __LINE__, errmsg);
return -1;
}
//将用户的登录状态全部重置为N(N为未登录,Y为已登录)
bzero(sql, sizeof(sql));
sprintf(sql, "update usr set stat='N'");
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) !=SQLITE_OK)
{
fprintf(stderr, "line:%d sqlite3_exec:%s\n", __LINE__, errmsg);
return -1;
}
printf("数据库初始化成功\n");
//关闭数据库
if(sqlite3_close(db) != SQLITE_OK)
{
fprintf(stderr, "line:%d sqlite3_close:%s\n", __LINE__, sqlite3_errmsg(db));
return -1;
}
printf("database close success\n");
return 0;
}
//将文件中的单词插入到表中
int do_insert(sqlite3* db)
{
char sql[128] = "";
int id = 0;
char _word[20] = "", filename[50] ="/mnt/hgfs/share/dict.txt";
char means[128] = "";
char temp[10] = "";
float score = 0;
char *errmsg =NULL;
int count = 0;
//以只读方式打开单词文件(单词文件中的格式为:单词" "[单词]" "意思)
FILE *fd = fopen(filename,"r");
if(NULL == fd)
{
perror("fopen");
return -1;
}
//循环读取单词
while(