当前位置: 首页 > article >正文

使用epoll与sqlite3进行注册登录

将 epoll 服务器 客户端拿来用

客户端:写一个界面,里面有注册登录

服务器:处理注册和登录逻辑,注册的话将注册的账号密码写入数据库,登录的话查询数据库中是否存在账号,并验证密码是否正确

额外功能:客户端登录的时候,服务器向客户端发送一个验证码,只有验证码也正确的时候,才能登录成功·

server.c

#include <stdio.h>
#include <string.h>
#include <unistd.h> 
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/un.h>
#include <sys/epoll.h>
#include <sqlite3.h>
#include <time.h>
typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;
typedef struct sockaddr_un addr_un_t;

int sqllen;

enum Type{
	TYPE_REGIST,
	TYPE_LOGIN
};

typedef struct pack{
	enum Type type;
	char name[20];
	char pwd[20];
	int auth;
}pack_t;

void read_data(int client);
int callback(void* arg,int argc,char** argv,char** col);


void* thread_main(void* arg)//验证码验证
{
	int client=*(int *)arg;
	pack_t pack={0};
	srand(time(0));
	pack.auth=rand()%10000+1;
	int test=pack.auth;
	write(client,&pack,sizeof(pack));

	read(client,&pack,sizeof(pack));						
	if(test==pack.auth)
	{					
		printf("登录成功");
	}else
	{
		printf("验证码错误\n");
	}

}

int main(int argc, const char *argv[])
{
	if(argc!=2)
	{
		printf("请输入端口号\n");
		return 0;
	}
	int port=atoi(argv[1]);
	//为服务器准备套接字
	int server=socket(AF_INET,SOCK_STREAM,0);

	//准备网络地址结构体
	addr_in_t addr={0};
	addr.sin_family=AF_INET;
	addr.sin_port=htons(port);
	addr.sin_addr.s_addr=inet_addr("0.0.0.0");

	//为套接字绑定ip和port
	if(bind(server,(addr_t*)&addr,sizeof(addr))==-1)
	{
		perror("bind");
		return 1;
	}
	//监听
	listen(server,10);
	//动态监视列表
	int epfd=epoll_create1(EPOLL_CLOEXEC);
	//设定需要监视描述符,及激活形式
	struct epoll_event event_server={.events=EPOLLIN, .data.fd=server};
	struct epoll_event event_stdin={.events=EPOLLIN, .data.fd=0};
	//添加到监视列表
	epoll_ctl(epfd,EPOLL_CTL_ADD,server,&event_server);
	epoll_ctl(epfd,EPOLL_CTL_ADD,0,&event_stdin);
	//准备数组,存放激活的描述符
	struct epoll_event arr[50]={0};
	while(1)
	{
		int len=epoll_wait(epfd,arr,50,-1);
		for(int i=0;i<len;i++)
		{
			int fd=arr[i].data.fd;//取出激活的描述符
			if(fd==server)
			{
				printf("有新的客户端链接\n");
				int client=accept(server,0,0);
				struct epoll_event epoll_client={
						.events=EPOLLIN,
						.data.fd=client
				};
				epoll_ctl(epfd,EPOLL_CTL_ADD,client,&epoll_client);
			}
			else if(fd==0)
			{
				char buf[64]="";
				scanf("%63s",buf);
				while(getchar()!=10);
				printf("键盘输入值为:%s\n",buf);
			}
			else
			{
				read_data(fd);
			}
		}
	}
	return 0;
}

void read_data(int client)
{
	pack_t pack={0};
	int res=read(client,&pack,sizeof(pack));
	if(res==0)
	{
		printf("断开连接\n");
	}
	sqlite3* db=NULL;
	if(sqlite3_open("./login.db",&db)!=SQLITE_OK)
		{
			printf("数据库打开失败\n");
			return ;
		}
	switch(pack.type)
	{
		case TYPE_REGIST:
			{
			    char sql[128]="";
				char* errmsg=NULL;
				sprintf(sql,"insert into login(name,pwd) values('%s','%s')",pack.name,pack.pwd);
				if(sqlite3_exec(db,sql,0,0,&errmsg)!=SQLITE_OK)
				{
					fprintf(stderr,"errmsg=%s\n",errmsg);
				}
				printf("注册成功\n");
				break;
			}
		case TYPE_LOGIN:
			{
				int flag=0;
				pack_t arr[20]={0};
				char* sql="select*from login;";
				char* errmsg=NULL;
				if(sqlite3_exec(db,sql,callback,arr,&errmsg)!=SQLITE_OK)
				{
					fprintf(stderr,"errmsg=%s\n",errmsg);
				}

				for(int i=0;i<sqllen;i++)
				{
					if(strcmp(arr[i].name,pack.name)==0 && strcmp(arr[i].pwd,pack.pwd)==0)//判断登录
					{
											
						pthread_t id;
						pthread_create(&id,0,thread_main,&client);//线程判断验证码
						pthread_detach(id);

						flag=1;
					}
				}
				if(flag==0)
				{
					printf("登录失败\n");
				}

				
			}
	}
	return ;
}

int callback(void* arg,int argc,char** argv,char** col)
{
	pack_t* arr=(pack_t*)arg;
	strcpy(arr[sqllen].name,argv[0]);
	strcpy(arr[sqllen].pwd,argv[1]);
	sqllen++;
	printf("一共%d个数据\n",sqllen);
	return 0;	
}

client.c

#include <stdio.h>
#include <string.h>
#include <unistd.h> 
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/un.h>

typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;
typedef struct sockaddr_un addr_un_t;

enum Type{
	TYPE_REGIST,
	TYPE_LOGIN
};

typedef struct pack{
	enum Type type;
	char name[20];
	char pwd[20];
	int auth;
}pack_t;

void* thread_main(void* arg)
{
		int client=*(int *)arg;
		pack_t pack;
		read(client,&pack,sizeof(pack));
		printf("验证码为:%d\n",pack.auth);
		printf("请输入验证码\n");
		scanf("%d",&pack.auth);
		while(getchar()!=10);
		write(client,&pack,sizeof(pack));

}


int main(int argc, const char *argv[])
{
	if(argc!=2)
	{
		printf("请输入端口号\n");
		return 0;
	}
	int port=atoi(argv[1]);

	int client=socket(AF_INET,SOCK_STREAM,0);

	addr_in_t addr={0};
	addr.sin_family=AF_INET;
	addr.sin_port=htons(port);
	addr.sin_addr.s_addr=inet_addr("192.168.126.86");
	
	if(connect(client,(addr_t*)&addr,sizeof(addr))==-1)
	{
		perror("connect");
		return 1;
	}
	 
	while(1)
	{
		int ch=-1;
		printf("请选择\n");
		printf("1:注册\n");
		printf("2:登录\n");
		printf("0:退出\n");
		scanf("%d",&ch);
		while(getchar()!=10);
		switch(ch)
		{
			case 1:{
				pack_t pack = {0};
				printf("请输入账号:");
				scanf("%s",pack.name);
				while(getchar()!=10);
				printf("请输入密码:");
				scanf("%s",pack.pwd);
				while(getchar()!=10);
				pack.type = TYPE_REGIST;
				write(client,&pack,sizeof(pack));
				break;
			}
			case 2:{
				pack_t pack = {0};
				printf("请输入账号:");
				scanf("%s",pack.name);
				while(getchar()!=10);
				printf("请输入密码:");
				scanf("%s",pack.pwd);
				while(getchar()!=10);
				pack.type = TYPE_LOGIN;
				write(client,&pack,sizeof(pack));
				
				pthread_t id;
				pthread_create(&id,0,thread_main,&client);
				pthread_detach(id);
				break;
			}
			case 0:
				{
					exit(0);	
			    }
		}
	}
	return 0;
}

 


http://www.kler.cn/a/542378.html

相关文章:

  • 可编程网卡芯片在京东云网络的应用实践【BGW边界网关篇】
  • 单片机之基本元器件的工作原理
  • LINUX——内核
  • 【AI时代】以聊天框的模式与本地部署DeepSeek交互 (Docker方式-Open WebUI)
  • Node.js怎么调用到打包的python文件呢
  • 深度学习-交易预测
  • 基于ESP32的远程开关灯控制(ESP32+舵机+Android+物联网云平台)——下
  • linux部署nacos集群
  • 【Elasticsearch】derivative聚合
  • CSS 属性选择器详解与实战示例
  • 认识Electron 开启新的探索世界一
  • 香港服务器远程超出最大连接数的解决方案是什么?
  • android 指定跳转页面返回触发
  • 数据分析:蛋白质组的GO term的富集分析详解
  • MySQL 使用create table as 与like 复制表
  • redis底层数据结构——整数集合
  • ubuntu20.04+ROS+Gazebo+px4+QGC+MAVROS
  • MacOS 15 无法打开Docker问题(Malware Blocked)解决
  • 【分布式理论9】分布式协同:分布式系统进程互斥与互斥算法
  • 【前端】几种常见的跨域解决方案代理的概念
  • 前端如何判断浏览器 AdBlock/AdBlock Plus(最新版)广告屏蔽插件已开启拦截
  • [操作系统] 进程等待
  • PHP设备巡检系统小程序
  • 掌握 PHP 单例模式:构建更高效的应用
  • C# Thread与Task的区别
  • 哪吒闹海!SCI算法+分解组合+四模型原创对比首发!SGMD-FATA-Transformer-LSTM多变量时序预测