网络编程项目

流程图

 

1.注册

2.登录

3.查询单词

 

4.查询历史记录

 

 5.退出登录

服务器代码

main.c

#include "ser.h"
struct sockaddr_in clis[1024];//存放地址信息
sqlite3 *db;
int main(int argc,const char *argv[])
{
	//创建数据库,导入辞典
	//sqlite3 *db;
	if(sqlite3_open("dict.db",&db) != SQLITE_OK)
	{
		fprintf(stderr,"sqlopen:%s line:%d",sqlite3_errmsg(db),__LINE__);
		return -1;
	}

	//创建辞典表,用户表,历史记录表
	char *errmsg;
	if(sqlite3_exec(db,"create table if not exists dict(word char parmary key,mean char);"
					"create table if not exists users(user char parmary key,pwd char);"
					"create table if not exists history(user char,word char,time char);"
					,NULL,NULL,&errmsg) != SQLITE_OK)
	{
		fprintf(stderr,"sqlcreate:%s line:%d",errmsg,__LINE__);
		return -1;
	}
	
	//判断辞典是否有值
	int row = 0,col = 0;
	char **result = NULL;
	if(sqlite3_get_table(db,"select * from dict",&result,&row,&col,&errmsg) != SQLITE_OK)
	{
		fprintf(stderr,"sqlgettable:%s line:%d",errmsg,__LINE__);
		return -1;
	}
	//printf("%d %d %s\n",row,col,result[0]);
	sqlite3_free_table(result);
	
	//导入辞典
	if(row == 0) if(importDict(db)) return -1;
	puts("辞典导入完成");

	//创建tcp服务器
	int sfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sfd < 0)
	{
		ERR_MSG("socket");
		return -1;
	}

	//允许端口快速被重用
	int reuse = 1;
	if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
	{
		ERR_MSG("setsockopt");
		return -1;
	}

	struct sockaddr_in addr={AF_INET,htons(PORT),inet_addr(IP)};
	if(bind(sfd,(struct sockaddr*)&addr,sizeof(addr)) < 0)
	{
		ERR_MSG("bind");
		return -1;
	}

	if(listen(sfd, 128) < 0)
    {
        ERR_MSG("listen");
        return -1;
    }
    printf("服务器启动成功\n");
	
	socklen_t cinlen = sizeof(struct sockaddr_in);
	while(1)
	{
		struct sockaddr_in clitemp;
		int fd = accept(sfd,(struct sockaddr*)&clitemp,&cinlen);
		if(fd < 0)
		{
			ERR_MSG("socket");
			return -1;
		}
		printf("[%s:%d] %d 客户端已连接\n",inet_ntoa(clitemp.sin_addr),ntohs(clitemp.sin_port),fd);

		clis[fd] = clitemp;
		pthread_t tid;
		if(pthread_create(&tid,NULL,dictSystem,&fd) < 0)
		{
			ERR_MSG("pthread_create");
			return -1;
		}
		pthread_detach(tid);
	}

	sqlite3_close(db);
	close(sfd);
	return 0;
}

 ser.h

#ifndef __SER_H__
#define __SER_H__
#include <myhead.h>
#define IP "192.168.125.106"
#define PORT 8888
#define REGISTER 1
#define LOGON 2
#define WORDQUERY 3
#define HISTORY 4
#define QUIT 5

int importDict();//导入辞典
void *dictSystem(void *arg);//线程体
int dictRegister(int fd,char *nandp);//注册
int logon(int fd,char *nandp,char **username);//登陆
int quit(char **username);//退出
int wordQuery(int fd,char *word,char *username);//查询单词
int history(int fd,char *username);//查询历史记录
char *format(char *buf,char *data,int size);//中英混杂格式对齐
#endif

ser.c

#include "ser.h"
extern struct sockaddr_in clis[1024];//存放地址信息
extern sqlite3 *db;
char *usersname[128] = {NULL};//存放已经登录的用户名

int importDict()
{
	FILE *fdict = fopen("./dict.txt","r");
	if(fdict == NULL)
	{
		ERR_MSG("fopen");
		return -1;
	}
	
	char word[128] = "";
	char *mean = word;
	char *errmsg = NULL;
	while(fgets(word,sizeof(word),fdict))
	{
		while(1) 
		{
			if(*mean == ' '&&*(mean+1) == ' ') break;
			mean++;
		}
		*mean++ = '\0';
		while(*mean == ' ') mean++;
		mean[strlen(mean)-1] = '\0';
		char dict[192] = "";
		snprintf(dict,sizeof(dict),"insert into dict values(\"%s\",\"%s\")",word,mean);
		//printf("%s\n",dict);
		
		if(sqlite3_exec(db,dict,NULL,NULL,&errmsg) != SQLITE_OK)
		{
			fprintf(stderr,"sqlinsertdict:%s line:%d",errmsg,__LINE__);
			return -1;
		} 
		bzero(word,sizeof(word));
		mean = word;
	}
	fclose(fdict);
	return 0;
}

void *dictSystem(void *arg)//线程体
{
	int fd = *(int *)arg;
	char * username = NULL;
	while(1)
	{
		char buf[129] = "";
		ssize_t res = recv(fd,buf,sizeof(buf),0);
		if(res == 0)
		{
			printf("[%s:%d] %d 客户端已下线\n",inet_ntoa(clis[fd].sin_addr),
					ntohs(clis[fd].sin_port),fd);
			break;
		}
		else if(res < 0)
		{
			ERR_MSG("recv");
			break;
		}
		
		switch(buf[0])
		{
		case REGISTER:
			dictRegister(fd,&buf[1]);
			break;
		case LOGON:
			logon(fd,&buf[1],&username);
			break;
		case WORDQUERY:
			wordQuery(fd,&buf[1],username);
			break;
		case HISTORY:
			history(fd,username);
			break;
		case QUIT:
			quit(&username);
			break;
		}
	}
	if(username != NULL) quit(&username);
	close(fd);
	return NULL;
}

int history(int fd,char *username)
{
	int row=0,col=0;
	char **result = NULL;
	char *errmsg = NULL;
	char buf[192] = "";
	snprintf(buf,sizeof(buf),"select h.user,h.word,d.mean,h.time "
			"from dict as d,history as h where h.user = '%s' and "
			"d.word = h.word",username);
	sqlite3_get_table(db,buf,&result,&row,&col,&errmsg);
	bzero(buf,sizeof(buf));
	buf[0] = 1;
	if(row == 0)
	{
		strcpy(buf+1,"没有历史记录");
		//printf("%s\n",buf+1);
		send(fd,buf,sizeof(buf),0);
	}
	else
	{
		for(int i=0;i<=row;i++)
		{
			/*
			snprintf(buf+1,sizeof(buf)-1,"%-16s%-16s%-32s%-s",result[col*i],
					result[col*i+1],result[col*i+2],result[col*i+3]);
					*/
			char *p = buf+1;
			
			p = format(p,result[col*i],16);
			p = format(p,result[col*i+1],16);
			p = format(p,result[col*i+2],32);
			p = format(p,result[col*i+3],0);

			send(fd,buf,sizeof(buf),0);
			bzero(buf+1,sizeof(buf)-1);
		}
	}
	sqlite3_free_table(result);
	buf[0]=0;
	send(fd,buf,1,0);
	return 0;
}

char *format(char *buf,char *data,int size)
{
	ssize_t len = strlen(data);
	char *p = buf;
	int count = 0;
	for(int i=0;data[i]!=0;i++,p++)
	{
		if((*p = data[i]) < 0) count++;
	}
	count /= 3;
	for(int i=0;i<size-len+count;i++,p++)
	{
		*p = ' ';
	}
	*p = 0;
	return p;
}

int wordQuery(int fd,char *word,char *username)
{
	char sql[128] = "";
	snprintf(sql,sizeof(sql),"select * from dict where word = '%s'",word);
	int row = 0,col = 0;
	char **result = NULL;
	char *errmsg = NULL;
	if(sqlite3_get_table(db,sql,&result,&row,&col,&errmsg) != SQLITE_OK)
	{
		fprintf(stderr,"sqlselectdict:%s line:%d",errmsg,__LINE__);
		return -1;
	}
	char msg[129] = "";
	if(row == 0) strcpy(msg,"没有查询到数据");
	else
	{
		snprintf(msg,sizeof(msg),"%s\t%s",result[2],result[3]);
		//记录历史记录
		time_t sys_time;
		time(&sys_time);
		struct tm *t = localtime(&sys_time);
		char time[64]="";
		snprintf(time,sizeof(time),"%4d-%02d-%02d %02d:%02d:%02d",
				t->tm_year+1900,t->tm_mon+1,t->tm_mday,
				t->tm_hour,t->tm_min,t->tm_sec);
		snprintf(sql,sizeof(sql),"insert into history values('%s','%s','%s')",
				username,word,time);
		printf("%s\n",sql);
		if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
		{
			fprintf(stderr,"sqlinserthistory:%s line:%d",errmsg,__LINE__);
			return -1;
		}
	}

	sqlite3_free_table(result);
	if(send(fd,msg,strlen(msg),0) < 0)
	{
		ERR_MSG("send");
		return -1;
	}

	return 0;
}

int quit(char **username)
{
	int i = 0;
	while(usersname[i] == *username) i++;//删除保存的登录的用户
	while(usersname[i] != NULL) usersname[i] = usersname[++i];
	free(*username);
	*username = NULL;
	return 0;
}

int logon(int fd,char *nandp,char **username)
{

	char name[64] = "";
	strcpy(name,nandp);
	
	char sql[192] = "";
	snprintf(sql,sizeof(sql),"select *from users where user = \"%s\"",name);
	
	int row = 0,col = 0;
	char **result = NULL;
	char *errmsg = NULL;
	if(sqlite3_get_table(db,sql,&result,&row,&col,&errmsg) != SQLITE_OK)
	{
		fprintf(stderr,"sqlselectusers:%s line:%d",errmsg,__LINE__);
		return -1;
	}
	//printf("%d %d %s\n",row,col,result[0]);
	if(row == 0)//判断用户名是否存在
	{
		sqlite3_free_table(result);
		char mes = -1;
		send(fd,&mes,sizeof(mes),0);
		return 0;
	}	
	char pwd[64] = "";
	strcpy(pwd,nandp+strlen(nandp)+1);
	if(strcmp(pwd,result[3]))
	{
		sqlite3_free_table(result);
		char mes = -1;
		send(fd,&mes,sizeof(mes),0);
		return 0;
	}
	sqlite3_free_table(result);

	int i = 0;
	char mes = 0;
	while(usersname[i]!=NULL)//判断用户是否已经登陆
	{
		if(strcmp(usersname[i],name) == 0)
		{
			mes = -2;
			send(fd,&mes,sizeof(mes),0);
			return 0;
		}
		i++;
	}
	
	*username = malloc(strlen(name)+1);//保存用户
	strcpy(*username,name);
	usersname[i] = *username;
	if(send(fd,&mes,sizeof(mes),0) < 0)
	{
		ERR_MSG("send");
		return -1;
	}
	return 0;
}

int dictRegister(int fd,char *nandp)
{	
	char name[64] = "";
	strcpy(name,nandp);
	
	char sql[192] = "";
	snprintf(sql,sizeof(sql),"select *from users where user = \"%s\"",name);
	
	int row = 0,col = 0;
	char **result = NULL;
	char *errmsg = NULL;
	if(sqlite3_get_table(db,sql,&result,&row,&col,&errmsg) != SQLITE_OK)
	{
		fprintf(stderr,"sqlselectusers:%s line:%d",errmsg,__LINE__);
		return -1;
	}
	//printf("%d %d %s\n",row,col,result[0]);
	sqlite3_free_table(result);
	if(row != 0)//判断用户名是否存在
	{
		char *mes = "用户名已存在";
		send(fd,mes,strlen(mes)+1,0);
		return 0;
	}	
	char pwd[64] = "";
	strcpy(pwd,nandp+strlen(nandp)+1);
	bzero(sql,sizeof(sql));
	snprintf(sql,sizeof(sql),"insert into users values(\"%s\",\"%s\")",name,pwd);
	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
	{
		fprintf(stderr,"sqlinsertusers:%s line:%d",errmsg,__LINE__);
		return -1;
	}
	char *mes = "注册成功";
	if(send(fd,mes,strlen(mes)+1,0) < 0)
	{
		ERR_MSG("send");
		return -1;
	}
	return 0;
}

客户端

main.c

#include "cli.h"
int main(int argc,const char *argv[])
{
	int cfd = socket(AF_INET, SOCK_STREAM, 0);
    if(cfd < 0)
    {
        ERR_MSG("socket");
        return -1;
    }

	struct sockaddr_in sin = {AF_INET,htons(PORT),inet_addr(IP)};
	
	if(connect(cfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
    {
        ERR_MSG("connect");
        return -1;
    }
    printf("连接客户端成功\n");

	while(1)
	{
		puts("1.注册\n2.登陆\n3.退出\n");
		printf("输入:");
		char flag;
		scanf("%hhd",&flag);
		if(flag == 3) break;
		switch(flag)
		{
		case 1:
			dictRegister(cfd);
			break;
		case 2:
			logon(cfd);
			break;
		}
	}

	close(cfd);
	return 0;
}

cli.h

#ifndef __CLI_H__
#define __CLI_H__
#include <myhead.h>

#define IP "192.168.125.106"
#define PORT 8888
#define REGISTER 1
#define LOGON 2
#define WORDQUERY 3
#define HISTORY 4
#define QUIT 5

int dictRegister(int cfd);//注册
int logon(int cfd);//登录
int dictsystem(int cfd);//系统界面
int wordQuery(int cfd);//查询单词
int quit(int cfd);//退出登录
int history(int cfd);//查询历史记录
#endif

cli.c

#include "cli.h"

int dictRegister(int cfd)
{
	char buf[129] = "";
	buf[0] = REGISTER;
	printf("\n注册\n输入用户名:");
	while(getchar()!='\n');
	fgets(buf+1,sizeof(buf)-1,stdin);
	buf[strlen(buf)-1] = '\0';
	char *pwd = buf+strlen(buf)+1;
	printf("输入密码:");
	fgets(pwd,sizeof(buf)-strlen(buf)-1,stdin);
	pwd[strlen(pwd)-1] = '\0';
	if(send(cfd,buf,sizeof(buf),0) < 0)
	{
		ERR_MSG("send");
		return -1;
	}

	bzero(buf,sizeof(buf));
	ssize_t res = recv(cfd,buf,sizeof(buf),0);
	if(res < 0)
	{
		ERR_MSG("res");
		return -1;
	}
	else if(res == 0)
	{
		printf("客户端下线\n");
		return -1;
	}
	printf("\n%s\n\n",buf);
	return 0;
}

int logon(int cfd)
{
	char buf[129] = "";
	buf[0] = LOGON;
	printf("\n登陆\n输入用户名:");
	while(getchar()!='\n');
	fgets(buf+1,sizeof(buf)-1,stdin);
	buf[strlen(buf)-1] = '\0';
	char *pwd = buf+strlen(buf)+1;
	printf("输入密码:");
	fgets(pwd,sizeof(buf)-strlen(buf)-1,stdin);
	pwd[strlen(pwd)-1] = '\0';
	if(send(cfd,buf,sizeof(buf),0) < 0)
	{
		ERR_MSG("send");
		return -1;
	}

	bzero(buf,sizeof(buf));
	ssize_t res = recv(cfd,buf,sizeof(buf),0);
	if(res < 0)
	{
		ERR_MSG("res");
		return -1;
	}
	else if(res == 0)
	{
		printf("客户端下线\n");
		return -1;
	}

	if(buf[0] == -1)
	{
		printf("\n登陆失败,用户名或密码错误\n\n");
		return 0;
	}
	else if(buf[0] == 0)
	{
		
		printf("\n登陆成功\n\n");
		dictsystem(cfd);
		return 0;
	}
	else if(buf[0] == -2)
	{
		
		printf("\n用户已登录,不能重复登录\n\n");
		return 0;
	}
	return 0;
}

int dictsystem(int cfd)
{
	while(1)
	{
		puts("1.查询单词\n2.查询历史记录\n3.退出登录\n");
		printf("输入:");
		char flag;
		scanf("%hhd",&flag);
		if(flag == 3)
		{
			quit(cfd);
			break;
		}
		switch(flag)
		{
		case 1:
			wordQuery(cfd);
			break;
		case 2:
			history(cfd);
			break;	
		}
	}
	puts("");
}

int history(int cfd)
{
	puts("");
	char buf[192]="";
	buf[0] = HISTORY;
	if(send(cfd,buf,1,0) < 0)
	{
		ERR_MSG("send");
		return -1;
	}
	
	while(1)
	{
		bzero(buf,sizeof(buf));
		ssize_t res = recv(cfd,buf,sizeof(buf),0);	
		if(res < 0)
		{
			ERR_MSG("res");
			return -1;
		}
		else if(res == 0)
		{
			printf("客户端下线\n");
			return -1;
		}
		if(buf[0]==1) printf("%s\n",buf+1);
		else if(buf[0]==0) break;
	}
	puts("");
	return 0;
}

int quit(int cfd)
{
	char msg = QUIT;
	if(send(cfd,&msg,sizeof(msg),0) < 0)
	{
		ERR_MSG("send");
		return -1;
	}
	return 0;
}

int wordQuery(int cfd)
{
	puts("");
	char buf[129] = "";
	buf[0] = WORDQUERY;
	printf("输入要查询的单词:");
	while(getchar()!='\n');
	char *word = buf + 1;
	fgets(word,sizeof(buf)-1,stdin);
	int i = 0;
	word[strlen(word)-1] = '\0';
	while(word[i]!='\0')
	{
		if(word[i]=='\'')
		{
			for(int j = strlen(word);i!=j;j--)	
				word[j] = word[j-1];
			i++;
		}
		i++;
	}
	if(send(cfd,buf,sizeof(buf),0) < 0)
	{
		ERR_MSG("send");
		return -1;
	}
	bzero(buf,sizeof(buf));
	ssize_t res = recv(cfd,buf,sizeof(buf),0);
	if(res < 0)
	{
		ERR_MSG("res");
		return -1;
	}
	else if(res == 0)
	{
		printf("客户端下线\n");
		return -1;
	}
	printf("%s\n\n",buf);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值