利用多线程实现服务器与客户端的连接

实现用户修改密码的服务器代码

#include "../../include/db.h"
#include "../../include/server.h"

#define N 30

User user = {0};


int server()
{
	//监听套接字文件描述符
	int listenFd = -1;
	//连接套接字的文件描述符
	int connFd = -1;
	//服务器的地址结构
	struct sockaddr_in servAddr = {0};
	//客户端的地址解构
	struct sockaddr_in cliAddr = {0};
	socklen_t len = sizeof(cliAddr);
	int ret;
	char buf[512] = {0};
	int address = 1;
	//pthread_t tid = -1;
	char *argv[N] = {0};

	//创建套接字
	listenFd = socket(PF_INET, SOCK_STREAM, 0);
	if (listenFd < 0)
	{
		perror("socket error!");
		return -1;
	}
	printf("socket ok!\n");
	
	//地址复用
	setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR, &address, sizeof(address));
	//绑定ip和端口号
	servAddr.sin_family = PF_INET;
	servAddr.sin_port = htons(9999);
	servAddr.sin_addr.s_addr = inet_addr("0.0.0.0");
	ret = bind(listenFd, (struct sockaddr *)&servAddr, sizeof(servAddr));
	if (ret < 0)
	{
		perror("bind error!");
		close(listenFd);
		return -1;
	}
	printf("bind ok!");
	
	//创建监听队列
	ret = listen(listenFd, 1);
	if (ret < 0)
	{
		perror("listen error!");
		close(listenFd);
		return -1;
	}
	printf("等待连接......\n");
	
	//将listenFd加入集合
	//listenFd  监听套接字   有客户端connect就准备就绪
	//创建文件描述符的表
	fd_set rfds;
	//清空表
	FD_ZERO(&rfds);
	//将listenFd加入表
	FD_SET(listenFd, &rfds);
	int maxFd = listenFd;
	
	while (1)
	{
		printf("before select...\n");
		//判断有无文件描述符准备就绪
		fd_set tmp = rfds;
		ret = select(maxFd + 1, &tmp, NULL, NULL, NULL);
		if (ret < 0)
		{
			perror("select error!\n");
			continue;
		}
		int i;
		for (i = 0; i < maxFd + 1; i++)
		{
			//对标志位置为1的文件描述符处理,用tmp,不会改变rfds的值
			if (FD_ISSET(i, &tmp))
			{
				//i位置的文件描述符为1,则有请求
				//判断套接字文件描述符是否为1,==1则有连接请求
				if (listenFd == i)
				{
					//等待并建立连接
					connFd = accept(listenFd, (struct sockaddr *)&cliAddr, &len);
					if (connFd < 0)
					{
						perror("accept error!");
						close(listenFd);
						return -1;
					}
					printf("客户端%s连接成功 , 端口号为:%d\n", inet_ntoa(cliAddr.sin_addr), ntohs(cliAddr.sin_port));
					//将新产生的connFd加入文件描述符的表
					FD_SET(connFd, &rfds);
					if (connFd > maxFd)
					{
						maxFd = connFd;
					}
				}
				else
				{
					memset(buf, 0, sizeof(buf));
					//接收消息并打印
					ret = recv(i, buf, sizeof(buf), 0);
					if (ret < 0)
					{
						perror("recv error!");
						close(i);
						return -1;
					}
					else if (0 == ret)
					{
						printf("clent quit!\n");
						//将对应的文件描述符从表中移出
						FD_CLR(i, &rfds);
					}
					printf("recv:%s\n", buf);
					ret = get_file_head(buf, argv);
					memset(buf, 0, sizeof(buf));
					if (ret == SEV_LOG)
					{
						sprintf(buf, "%s", "登陆成功");
					}
					else if ( ret == SEV_REG )
					{
						sprintf(buf, "%s", "注册成功");
					}
					else if ( ret == SEV_CAG )
					{
						sprintf(buf, "%s", "修改密码成功");
					}
					else if (ret == SEV_DEL)
					{
						sprintf(buf, "%s", "删除成功");
					}
					send(i, buf, sizeof(buf), 0);
				}
			}
	
		}
	}
	
	/*//创建子线程
	//参数1:指向线程id的指针
	//参数2:线程属性,一般为NULL
	//参数3:传给线程执行函数的函数指针
	//参数4:传给线程执行函数的入参
	while(0 != pthread_create(&tid,NULL,thread_exe,&connFd));
	//将子线程设置为分离态,子线程终止时会被系统自动回收
	pthread_detach(&tid);*/


	//关闭套接字
	close(listenFd);
	close(connFd);
}

//解析文件头
int get_file_head(char *buf, char *argv[])
{
	int ret;
	int i = 0, j = 0;
	argv[0] = buf;
	char cmd[N] = {0};
	while (buf[i] != '\0')
	{
		if (buf[i] == '#')
		{
			buf[i] = '\0';
			j++;
			argv[j] = &buf[i + 1];
		}
		i++;
	}

	// 打印解析信息
	for (int i = 0; i < 10; i++)
	{
		if (argv[i] != NULL)
		{
			printf("%s	", argv[i]);
		}
	}
	printf("\n");


	strcpy(cmd, argv[0]);
	strcpy(user.user_id, argv[1]);
	strcpy(user.password, argv[2]);
	printf("\n");
	printf("cmd:%s  user_id:%s  password:%s\n", cmd, user.user_id, user.password);
	if (strcmp(cmd, "login") == 0)
	{
		ret = user_login(user.user_id, user.password);
		if (ret == 0)
		{
			printf("登陆成功\n");
			return SEV_LOG;
		}
		else if (ret < 0)
		{
			printf("密码错误\n");
		}
	}
	else if (strcmp(cmd, "register") == 0)
	{
		ret = user_register(user.user_id, user.password);
		if (ret < 0)
		{
			printf("注册失败,请重试\n");
			//printf("注册成功\n");
		}
		else
		{
			printf("注册成功\n");
			//printf("注册失败,请重试\n");
			return SEV_REG;
		}
	
	}
	else if (strcmp(cmd, "user_change_password") == 0)
	{
		ret = user_change_password(user.user_id, user.password);
		if (ret < 0)
		{
			printf("修改失败");
			return SEV_ERROR;
		}
		else if (ret == 0)
		{
			printf("修改成功");
			return SEV_CAG;
		}
	}
	else if (strcmp(cmd, "user_delete") == 0)
	{
		ret = user_delete(user.user_id);
		if (ret < 0)
		{
			printf("删除失败,用户不存在");
			return SEV_ERROR;
		}
		else if (ret == 0)
		{
			printf("删除用户信息成功");
			return SEV_DEL;
		}
	}
}

//用户登陆
int user_login(char *user_id, char *password)
{
	printf("user_id:%s  password:%s\n", user_id, password);

	int ret, i, j;
	char db_Upassword[N] = {0};//数据库中保存的用户密码
	ret = select_user_id(user_id);//查找用户id是否和数据库中相匹配
	if (ret != DB_OK)
	{
		printf("输入错误\n");
		return -1;
	}
	if (0 == row)
	{
		printf("用户不存在\n");
		return -1;
	}
	//打印查找结果
	/*for (i = 0; i < row + 1; i++)
	{
		for (j = 0; j < column; j++)
		{
			sprintf(db_Upassword, "%s  ", ppTable[column * i + j]);
		}
		printf("\n");
	}*/
	printf("%s ", ppTable[column * 1 + 1]);
	sprintf(db_Upassword, "%s", ppTable[column * 1 + 1]);
	//释放ppTable
	sqlite3_free_table(ppTable);
	if (strcmp(password, db_Upassword) != 0)
	{
		printf("密码错误\n");
		return -1;
	}
	printf("密码输入正确\n");
	return 0;
}

//用户注册
int user_register(char *user_id, char *password)
{
	int ret;
	ret = db_insert(user_id, password); //插入用户信息->用户名+密码
	if (ret != DB_OK)
	{
		return -1;
	}
	/*ret = select_user_id(user_id);//查找用户id是否和数据库中相匹配
	if (ret != DB_OK)
	{
		printf("输入错误\n");
		return -1;
	}
	if (0 == row)
	{
		printf("用户不存在,可以注册\n");
		printf("ret = :%d",ret);
		// ret = db_insert(user_id, password); //插入用户信息->用户名+密码
		// if (ret != DB_OK)
		// {
		// 	return -1;
		// }
	}*/
	return 0;
}


int user_change_password(char *user_id, char *password) //用户修改密码
{
	int ret;
	// strcpy(user.user_id,user_id);
	// strcpy(user.password,password);
	//Sqlite>update stu set name=’wangwu’ where id=1001;
	ret = db_change_password(user_id, password);
	if (ret != DB_OK)
	{
		return -1;
	}
	return 0;
}

//用户注销账号
int user_delete(char *user_id)
{
	int ret;
	ret = db_user_delete(user_id);
	if (ret != DB_OK)
	{
		return -1;
	}
	return 0;
}

实现修改用户密码的客户端代码:

#include "../../include/client.h"

//创建套接字
int sockFd = -1;
char user_id[30] = {0};
int client()
{

	//服务器的地址结构
	struct sockaddr_in servAddr = {0};
	int ret;
	char buf[512] = {0};

	//创建套接字
	sockFd = socket(PF_INET, SOCK_STREAM, 0);
	if (sockFd < 0)
	{
		perror("socket error!");
		return -1;
	}
	printf("socket ok!\n");
	//按照服务器的ip地址和端口号连接服务器
	servAddr.sin_family = PF_INET;
	servAddr.sin_port = htons(9999);
	servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
	ret = connect(sockFd, (struct sockaddr *)&servAddr, sizeof(servAddr));
	if (ret < 0)
	{
		perror("connect error!");
		close(sockFd);
		return -1;
	}
	printf("connect ok!\n");


	char password[30] = {0};
	char buf_login[100] = {0};
	char buf_register[100] = {0};

	while (1)
	{
		memset(buf, 0, sizeof(buf));
		strcpy(buf_login, login_page());
		if (buf_login == NULL)
		{
			return -1;
		}
		printf("请输入用户名:");
		scanf("%s", user_id);
		printf("请输入密码:");
		scanf("%s", password);

		sprintf(buf, "%s#%s#%s", buf_login, user_id, password);
		printf("%s\n", buf);

		ret = send(sockFd, buf, sizeof(buf), 0);
		if (ret < 0)
		{
			perror("send error!");
			close(sockFd);
			return -1;
		}
		printf("send ok!\n");
		memset(buf, 0, sizeof(buf));

		//接收
		recv(sockFd, buf, sizeof(buf), 0);
		printf("recv:%s\n", buf);
		if (strcmp(buf, "登陆成功") == 0)
		{
			user_operations();
		}
	}
	//关闭套接字
	close(sockFd);
	return 0;
}

char *login_page()//登陆界面
{
	menu_interface();
	int input;
	scanf("%d", &input);
	if (input == 1)
	{
		return "login";
	}
	else if (2 == input)
	{
		return "register";
	}
	else if (input == -1)
	{
		exit(0);
	}
	else
	{
		return NULL;
	}
}

int user_operations()//用户操作界面->店铺管理,修改密码
{

	int input;
	int ret;
	char app[30] = {0};
	char ap[30] = {0};
	// char user_id[30] = {0};
	char buf[512] = {0};
	while (1)
	{
		user_menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1://店铺管理
			management();
			break;
		case 2://修改密码
			printf("请输入要更改的密码:");
			scanf("%s", app);
			printf("请再次确认要进行更改的密码:");
			scanf("%s", ap);
			if (strcmp(app,ap) == 0)
			{
				sprintf(buf, "user_change_password#%s#%s", user_id, ap);
				ret = send(sockFd, buf, sizeof(buf), 0);
				if (ret < 0)
				{
					printf("%d", ret);
					perror("send error!");
					break;
				}
				memset(buf, 0, sizeof(buf));
				ret = recv(sockFd, buf, sizeof(buf), 0);
				if (ret < 0)
				{
					perror("recv error!");
					break;
				}
				printf("recv:%s\n", buf);
				if (strcmp(buf, "密码修改成功!") == 0)
				{
					return 0;
				}
			}
			else
			{
				printf("两次输入的密码不一致,请重试\n");
				continue;
			}

			break;
		case 3://注销用户
			printf("请输入要注销的用户名:");
			scanf("%s", app);
			sprintf(buf, "user_delete#%s", user_id);
			ret = send(sockFd, buf, sizeof(buf), 0);
			if (ret < 0)
			{
				perror("send error!");
				break;
			}
			memset(buf, 0, sizeof(buf));
			ret = recv(sockFd, buf, sizeof(buf), 0);
			if (ret < 0)
			{
				perror("recv error!\n");
				break;
			}
			printf("recv:%s\n", buf);
			if (strcmp(buf, "注销成功") == 0)
			{
				printf("请按-1退出");
				break;
			}

			break;
		case -1:
			printf("退出成功\n");
			return -1;
		}

	}
}

void menu_interface()
{
	printf("[=========================================]\n");
	printf("[[---------------------------------------]]\n");
	printf("[[     |    【店铺管理系统】  	   |     ]]\n");
	printf("[[     | 【请输入要进行的操作】	   |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[     |  1.登陆                   |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[     |  2.注册                   |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[     |  -1.退出                  |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[---------------------------------------]]\n");
	printf("[=========================================]\n");
	printf("please input:");
}

void user_menu()//用户菜单
{
	printf("[=========================================]\n");
	printf("[[---------------------------------------]]\n");
	printf("[[     |    【店铺管理系统】  	   |     ]]\n");
	printf("[[     | 【请输入要进行的操作】	   |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[     |  1.店铺管理               |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[     |  2.修改密码               |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[     |  3.注销账号               |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[     |  -1.退出操作              |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[---------------------------------------]]\n");
	printf("[=========================================]\n");
}

void menu()
{
	printf("[=========================================]\n");
	printf("[[---------------------------------------]]\n");
	printf("[[     |    【店铺管理系统】  	   |     ]]\n");
	printf("[[     | 【请输入要进行的操作】	   |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[     |  1.显示所有库存           |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[     |  2.增加商品库存           |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[     |  3.删除商品库存           |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[     |  4.修改商品库存           |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[     |  5.查询商品库存           |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[     |  -1.退出操作              |     ]]\n");
	printf("[[     |  --------------------     |     ]]\n");
	printf("[[---------------------------------------]]\n");
	printf("[=========================================]\n");
}

int management()//用户操作商品管理界面
{
	int ret, input;
	char buf[512] = {0};
	char reply[521] = {0};
	char user_id[30] = {0};
	while (1)
	{
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			sprintf(buf, "management#db_select_all#%s", user_id);
			ret = send(sockFd, buf, sizeof(buf), 0);
			if (ret < 0)
			{
				perror("send error!");
				close(sockFd);
				break;
			}
			printf("send ok!\n");
			recv(sockFd, reply, sizeof(reply), 0);
			if (strcmp(reply, "end") == 0)
			{
				break;
			}
			printf("%s", reply);
			memset(reply, 0, sizeof(reply));
			break;
		//	case 2:
		//		break;
		/*		case 3:
					break;
				case 4:
					break;
				case 5:
					break;*/
		case -1:
			printf("退出成功\n");
			//exit(0);
			//break;
			return 0;
		default:
			break;

		}

	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值