电子辞典基于TCP多线程并发实现

服务器代码

头文件

#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(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值