基于linux环境tcp网络编程(在线英英词典)文档【3】

C语言在线词典项目—Linux C语言-在线词典项目 功能:基于网络编程和数据库实现在线词典功能,客户端可以注册,登入,查询历史信息等操作,服务器基于多进程实现多客户端的并发访问,并使用sqlite数据库实现对用户信息的管理。 客户端 #include<stdio.h> #include<string.h> #include<unistd.h> #include<strings.h> #include<stdlib.h> #include<sys/types.h> 阅读详情

完整代码如下:

有真心想学习的,需要库的朋友,底下留言哦!

server.c:


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

#define N 64
#define M 512		
typedef struct		//消息结构体 
{
	int type;
	char name[N];
	char data[M];
}MSG;

int client(int connfd,sqlite3 *db);			//客户端命令选择函数
int login(int connfd, MSG *msg,sqlite3 *db);		//登录函数
int register_z(int connfd, MSG *msg,sqlite3 *db);	//注册函数
int search_word(int connfd, MSG *msg,sqlite3*db);	//查询单词函数
int history(int connfd, MSG *msg,sqlite3*db);		//查询历史记录函数
int history_date(char *date);

void handler(int signo)		//对僵尸进程收尸
{
	while(waitpid(-1,NULL,WNOHANG) > 0);
}

int main()
{
	int n;//
	sqlite3 *db;
	int connfd;//定义通信套接字
	signal(SIGCHLD, handler);
	/*1.创建套接字*/
	int sockfd;
	if((sockfd=socket(PF_INET, SOCK_STREAM, 0)) < 0)
	{
		perror("socket");
		return -1;
	}
	printf("socket success!\n");
	
	int on=1;
	if(0 > setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)))//设置重复端口号使用
	{
		perror("setsockopt");
		return -1;
	}

	if(0 != sqlite3_open("my.db",&db))//打开当前目录下的数据库
	{
		fprintf(stderr,"sqlite3_open:%s\n",sqlite3_errmsg(db));
		return -1;
	}

	/*2.绑定本机地址和端口*/
	struct sockaddr_in myaddr;
	memset(&myaddr, 0, sizeof(myaddr));
	myaddr.sin_family     =AF_INET;
	myaddr.sin_port	      =htons(8888);
	myaddr.sin_addr.s_addr=inet_addr("127.0.0.1");//采用本机静态IP地址
	if(bind(sockfd, (struct sockaddr *)&myaddr,sizeof(myaddr))<0)
	{
		perror("bind");
		return -1;
	}
	printf("bind success!\n");

	/*3.监听套接字*/
	if(listen(sockfd, 8)<0)
	{
		perror("listen");
		return -1;
	}
	printf("listen success!\n");

	while(1)
	{

		/*4.接受tcp连接*/
		connfd=accept(sockfd, NULL, NULL);
		if(connfd < 0)
		{
			perror("accept");
			return -1;
		}
		printf("accept success!\n");

		pid_t pid=fork();	   //采用并发服务器,利用产生子进程进行通信
		if(pid < 0)
		{
			perror("fork");
			exit(EXIT_FAILURE);
		}
		else if(pid == 0)	  //子进程进行通信
		{
			close(sockfd);	  //关闭监听套接字
			client(connfd,db);//选择页面
		}
		close(connfd);
	}
	if(0 != sqlite3_close(db))	  //关闭数据库
	{
		fprintf(stderr,"sqlite3_close:%s\n",sqlite3_errmsg(db));
		return -1;
	}

	/*6.关闭套接字*/
	close(sockfd);
	return 0;
}

int client(int connfd,sqlite3 *db)			 //页面选择函数
{
	
	MSG msg;    //定义一个新的消息结构体用来接受客户端发给服务器的所有消息
loop1:	while(0 < recv(connfd, &msg, sizeof(MSG),0))	//接受到客户端发的消息
	{
		//printf("msg->name:%s\n",msg.name);
		switch(msg.type)
		{
			case 1:
				if(1 == login(connfd,&msg,db))	//调用登录函数
				{
					client(connfd,db);	//如返回值为1,又返回到选择函数
				}
				break;
			case 2:
				register_z(connfd,&msg,db);	//注册用户函数
				break;
			case 3:
				search_word(connfd,&msg,db);	//查询单词函数
				break;
			case 4:
				history(connfd,&msg,db);	//查询历史记录函数
				break;
			case 5:
				goto loop1;//当客户端返回上一级时服务器也需要返回上一级
			default:
				printf("input error!\n");
		}
	}
	close(connfd);		//关闭通信套接字
	exit(EXIT_FAILURE);	//关闭子进程
	return 0;
}

int login(int connfd,MSG *msg,sqlite3 *db)//登录函数
{
	char buff[M];		//定义查询用户名及密码的缓存空间
	char **resultp;		//定义函数之行后返回的结果空间
	char *errmsg=NULL;	//定义函数执行后返回的错误信息
	int nrow,ncolumn;	//定义数据库中的表的行数及列数
	int ret;
	memset(buff,0,sizeof(buff));
	sprintf(buff,"select * from user where username = '%s' and password = '%s'",msg->name,msg->data);//将从客户端接受到的用户名及密码放入缓存中

	if(0 != sqlite3_get_table(db,buff,&resultp,&nrow,&ncolumn,&errmsg))//执行SQL指令
	{
		printf("%s\n",errmsg);
		return -1;
	}	
	else
	{
		printf("client login success!\n");
	}
	if(1 == nrow)		//根据指定的条件查找完成后成功找到数据,返回有>0的行数
	{
		strcpy(msg->name,"OK");
		if (0 > (ret = send(connfd,msg,sizeof(MSG),0)))		//将成功的数据发送给客户端
		{
			perror("send1");
		}
		return 1;
	}
	if(0 == nrow )		//查询没有结果
	{
		strcpy(msg->data,"    登录失败\n密码或者用户名错误!\n");
		if (0 > (ret = send(connfd,msg,sizeof(MSG),0)))		//将查询结果失败的数据返回给客户端
		{
			perror("send1");
			return -1;
		}
		printf("login fail!\n");
	}
	else
		printf("login success!\n");
	return 0;
}

int register_z(int connfd,MSG *msg,sqlite3 *db)//注册函数
{
	char *errmsg=NULL;
	char buff[M];
	char **resultp;
	int nrow,ncolumn;

	memset(buff,0,sizeof(buff));
	sprintf(buff,"select * from user where username='%s'",msg->name);	//将按照查找指定的用户名SQL命令缓存到buff中
	if(0 != sqlite3_get_table(db,buff,&resultp,&nrow,&ncolumn,&errmsg))	//将buff中的命令执行
	{
		printf("%s\n",errmsg);
		return -1;
	}

	if(nrow >= 1)		//查询的行数返回值>=1
	{
		strcpy(msg->data,"用户已存在!\n");
	}
	else			//没有相同用户名情况下再去注册新的用户
	{
		memset(buff,0,sizeof(buff));
		sprintf(buff,"insert into user values('%s','%s')",msg->name,msg->data);	//将要添加新的用户名和密码缓存在buff中
		if(0 != sqlite3_exec(db,buff,NULL,NULL,&errmsg))			//使用函数执行SQL命令
		{
			printf("%s\n",errmsg);
			return -1;
		}
		else
		{
			printf("client register success!\n");
			strcpy(msg->data,"注册成功!\n");
		}
	}


	if(0 > send(connfd,msg,sizeof(MSG),0))	//发送查询成功与否的数据
	{
		perror("send");
		return -1;
	}
	
	printf("register success!\n");
	return 0;
}

int search_word(int connfd, MSG *msg, sqlite3 *db)//查询单词函数
{
	int i,j;
	char *errmsg=NULL;
	char buff[M];	//定义查找的单词和解释缓存区
	char order[M];	//定义装入历史记录的缓存区
	char date[M];
	char **resultp;
	int nrow,ncolumn;
	memset(buff,0,sizeof(buff));	//对缓存区清空
	memset(date,0,sizeof(date));	//对时间缓冲区清空
	sprintf(buff,"select * from word where word='%s'",msg->name);		//将要查询的单词名字SQL命令放入缓存中
	if(0 != sqlite3_get_table(db,buff,&resultp,&nrow,&ncolumn,&errmsg))	//执行SQL命令
	{
		printf("error: %s\n",errmsg);
		return -1;
	}
	int count=2;
	for(i=0; i < nrow; i++)			//行
	{
		for(j=1; j < ncolumn; j++)	//列
		{
			history_date(date);
			strcpy(msg->name,resultp[count]);	//单词
			strcpy(msg->data,resultp[count+1]);	//单词解释
			count +=2;				//只有两列,每次的单词解释都需要跳过单词名那一列
			sprintf(order,"insert into history values('%s','%s')",date,msg->name);	//将单词名和解释放入历史记录的缓存中
			if(0 != sqlite3_exec(db,order,NULL,NULL,&errmsg))			//执行SQL命令
			{
				printf("error: %s\n",errmsg);
				return -1;
			}
			printf("%s  %s\n",date,msg->name);

		}
	}
	if(0 == nrow)
	{
		printf("没有这个单词!\n");
		strcpy(msg->data,"NO");		//给客户端发一个没有找到单词的信号
		if(0 > send(connfd,msg,sizeof(MSG),0))
		{
			perror("send");
			return -1;
		}
	}
	else
	{
		printf("word search success!\n");
		if(0 > send(connfd, msg, sizeof(MSG), 0))	//给客户端发送查询到的解释
		{
			perror("send");
			return -1;
		}
	}

	return 0;
}

 

网络编程实战之在线电子词典 1.头文件 #include <stdio.h> #include <stdlib.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h... 阅读详情

相关推荐

linux网络编程在线词典

服务器代码和客户端代码均完整,可直接上机测试

在线词典网络编程

网络编程,实现在线词典,客户端和服务器之间的交互。用户在客户端进行登陆,成功后可进行查找单词,输入要查的单词即可查到他的解释,同时还有历史储存功能,客户自己什么时候查的什么单词都有记录。

linux c在线词典tcp

c语言实现的在线词典功能, 全部代码以及运行程序和使用说明。本程序使用tcp完成, 采用多进程,已经sqlite3 数据库,运行完美,可供课设作为参考代码

基于linux环境tcp网络编程在线英英词典文档 [1]

在线英英词典说明文档 用户登录(登录失败可重复登录); 用户注册(已有用户不能注册,需要输入两次密码); 单词查询(根据客户端输入的单词,服务器可以根据数据库查找反馈查询的单词和解释); 历史记录查询(查询单词时服务器会将历史记录存在数据库中,客户端查询时刻查询历史记录的时间和具体单词); 进入每一级后可以返回上一级继续执行上一级的操作,有清屏功能;  可同时登录多个用户(多个用户可反...

echo 2537

基于linux环境tcp网络编程在线英英词典文档【2】

真心想学习的伙伴,需要库的朋友们请留言! 完整代码如下: client.c /************************************************************************* File Name: client.c Author: Young motto: Continuous efforts will l...

echo 1850

Linux网络编程之六 --在线英英字典的实现

综合项目:在线英英字典   服务器端 head.h:   server.c   do_client.c   Makefile       客户端 head.h

drinkingcode 4688

基于Linux操作系统的在线英英词典C语言代码

功能描述:1、可进行用户注册、登录2、可对用户查找的单词进行存储,放入SQLite数据库中,对历史记录进行查询,查询方式有用户名和单词两种方式3、可进行查看和修改用户信息,包括用户名,密码,电话,地址等4、分为客户端和服务器端,客户端进行用户的注册登录和查找单词等操作,服务器端进行操作数据库,进行存储和查找5、可进行多个客户端登录6、服务器端有管理员模式,在管理员模式下,不影响客户端的发送和接...

半路码农的博客 3895

在线词典项目

当前流行的在线词典项目,C语言编写,Linux环境实现。拿来练练手是个不错的选择。 设计知识:Linux C语言、TCP编程、多进程编程、sqlite3数据库接口调用、文件读写、Makefile编写等等。

C/S模型的英英词典

网络编程实现C/S模型的基本英英词典

在线英英词典

网络在线英英词典,实现全词汇查询,基于C平台的所有软件即可运行,代码简单易懂。采用TCP协议,多路复用epoll机制,条例清晰明了。

网络编程之电子词典(完全版)

TCP协议完成电子词典的开发。。。。。。。。。。。。。。

在线词典项目源码

在线词典项目源码在线词典项目源码在线词典项目源码在线词典项目源码

在线英英词典服务器代码(Linux平台)

该代码是在Linux下编写的在线英英词典服务器端。采用TCP/IP协议,结合了sqlite3编写词典数据库。代码非常简单,易于初学者练习Linux网络编程

基于TCP在线词典

此程序主要是利用tcp传输和sqlite3进行操作的。 程序执行过程部分截图 #在终端输入sqlite3,查看是否安装sqlite3,没有的话先安装sqlite3 sudo apt-get install sqlite3 sudo apt-get install libsqlite3-dev 打开数据库 sqlite3 my.db 然后在里面创建数据库 create table &lt;ta...

weixin_41868476的博客 1357

基于Linux系统开发在线词典

Linux开发词典 做了一个小级别的实验项目,对之前所学过的知识有个综合性的总结。在线词典实验涉及有,Linux C语言的开发、网络套接字编程、多进程开发、sqlite3数据库接口调用、文件读写等操作,make编译及Makefile文件的编写。。 项目介绍 项目总体划分为客户端、和服务端两个部分。客户端(也是APP)一方面为使用的用户提供简单的注册、登录、查询等操作,另一方面负责与服务端进行TCP通信,向服务器发送请求。而真正提供服务的是服务端进程,它不仅能和数据库进行交互,而且要接收用户的请求,把服务提供

chenmi123321的博客 1385

Linux在线词典小项目

利用c语言,Linux网络编程,SQLite3数据库操作,文件操作

基于TCP在线词典客户端与服务器端

用QT编写的tcp通信的在线词典,客户端有注册登录模块,查找模块,历史记录模块;服务器端有注册登录(基于数据库查询和插入)模块,单词库搜索模块,还做了应对多用户同时访问的并发处理框架

上一篇: 基于linux环境tcp网络编程(在线英英词典)文档【2】
下一篇: C语言--指针详解1
JIANXIN.Y
博客等级 码龄9年 270粉丝 42原创
评论 18
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值