MFC网络通信传输结构体(服务器获取MYSQL数据库数据传给客户端)

5 篇文章 0 订阅

连接数据库:

        MYSQL m_sqlCon;
	mysql_init(&m_sqlCon);//初始化数据库对象
	if (!mysql_real_connect(&m_sqlCon, "localhost", "root", "123456", "student", 3306, NULL, 0))
		//localhost:服务器地址,可以直接填入IP;root:账号;123:密码;test:数据库名;3306:网络端口  
	{
		AfxMessageBox(_T("数据库连接失败!"));
		return FALSE;
	}
	else//连接成功则继续访问数据库,之后的相关操作代码基本是放在这里面的
	{
		AfxMessageBox(_T("数据库连接成功!"));
	}

传输的结构体定义netStruch:

#define LOGIN_MSGID			10003//登录
#define LOGIN_RESULT_MSGID		10008

#define REGISTER_MSGID		10007
#define REGISTER_RESULT_MSGID		10009//注册

#define ALLCOURSE_MSGID		10010		//查询全部课程
#define ALLCOURSE_RESULT_MSGID		10011

#define STUDENT_COURSE_MSGID		10012		//查询全部课程
#define STUDENT_COURSE_RESULT_MSGID		10013

#define STUDENT_ADD_COURSE_MSGID		10014
#define STUDENT_ADD_COURSE_RESULT_MSGID		10015

#define STUDENT_DELETE_COURSE_MSGID		10016
#define STUDENT_DELETE_COURSE_RESULT_MSGID		10017

struct LOGIN{//客户端发送给服务器
	short msgID;
	char userId[32];
	char userPassword[32];
};

struct LOGIN_RESULT {//服务器返回结果给客户端
	short msgID;
	char result[32];
};

struct REGISTER
{
	short msgID;
	char userId[32];
	char userName[32];
	char userPassword[32];
};

struct REGISTER_RESULT {
	short msgID;
	char result[32];
};

struct ALLCOURSE {
	short msgID;
};

struct ALLCOURSE_RESULT {
	short msgID;
	short row;//显示在第几行
	char courseId[32];
	char courseName[32];
	char courseScore[32];
	char courseTime[32];
	char coursePeople[32];
	char teacherId[32];
};

struct STUDENT_COURSE {
	short msgID;
	char userId[32];
};

struct STUDENT_ADD_COURSE {
	short msgID;
	char userId[32];
	char courseId[32];
};

struct STUDENT_ADD_COURSE_RESULT {//服务器返回结果给客户端
	short msgID;
	char result[32];
};

struct STUDENT_DELETE_COURSE {
	short msgID;
	char userId[32];
	char courseId[32];
};

struct STUDENT_DELETE_COURSE_RESULT {//服务器返回结果给客户端
	short msgID;
	char result[32];
};

服务器中写SOCKET:

                SOCKET s[5];
		int j = 0;

		//剩下的都是有事件发生的套接字
		for (int i = 0; i < tmSet.fd_count; i++)
		{
			if (tmSet.fd_array[i] == lisSock) //如果是监听监听套接字
			{
				SOCKET cliSock = accept(lisSock, 0, 0);
				printf("新连接.\n");
				FD_SET(cliSock, &fds);  //将已连接的套接字加入数组中
			}
			else
			{
				char recvBuf[1024] = { 0 };
				int recvLen = recv(tmSet.fd_array[i], recvBuf, 1024, 0);
				
				if (recvLen > 0)
				{
					//接收到客户端的数据后进行处理
					HandleData(recvBuf,recvLen,m_sqlCon, tmSet.fd_array[i]);
				}
				else  //错误发生,或者客户端断开连接 
				{
					printf("客户已断开\n");
					FD_CLR(tmSet.fd_array[i], &fds);  //从数组中移除已端口的客户端
				}
			}
		}
	

服务器处理接收到的数据dataHandle.cpp:

//处理收到的数据
bool HandleData(const char* recvData,int len, MYSQL &sqlCon, SOCKET lisSock)
{
	short msgID = *(short*)recvData;

	switch (msgID)
	{
	case LOGIN_MSGID://登录消息
	{
		DB_Login(recvData, len, sqlCon, lisSock);
	}
	break;

	case REGISTER_MSGID://注册消息
	{
		DB_Register(recvData, len, sqlCon, lisSock);
	}
	break;

	case ALLCOURSE_MSGID://查询全部课程消息
	{
		DB_AllCourse(recvData, len, sqlCon, lisSock);
	}
	break;

	case STUDENT_COURSE_MSGID://查询全部课程消息
	{
		DB_Student_Course(recvData, len, sqlCon, lisSock);
	}
	break;

	case STUDENT_ADD_COURSE_MSGID://学生添加课程消息
	{
		DB_Student_AddCourse(recvData, len, sqlCon, lisSock);
	}
	break;

	case STUDENT_DELETE_COURSE_MSGID://学生删除课程消息
	{
		DB_Student_DeleteCourse(recvData, len, sqlCon, lisSock);
	}
	break;

	case TALKALL_MSGID:
	{
		//...给所有人的消息
		const MSG_TALKALL* takAll = (MSG_TALKALL*)recvData;
		printf("群聊消息: %s\n", takAll->Content);
	}
	break;
	case TALKONE_MSGID:
	{
		//给某个人的消息
		const MSG_TALKONE* takOne = (MSG_TALKONE*)recvData;
		printf("私聊消息: %s : %s\n", takOne->userName, takOne->Content);
		//takOne.useName
	}
	break;
	case FILEINFO_MSGID:
	{
		const MSG_SENDFILEINFO *fileInfo = (MSG_SENDFILEINFO*)recvData;
		printf("文件路径:%s ,文件大小:%d\n", fileInfo->fileName, fileInfo->fileSize);
	}
	break;
	case FILE_MSGID:
	{
		const MSG_SENDFILE *file = (MSG_SENDFILE*)recvData;
		printf("文件内容:%s\n", file->fileBuf);
	}
	break;
	default:
		break;
	}

	return true;
}

数据库操作dbOperation.cpp,将对数据库得到的数据传给客户端

void DB_Login(const char* recvData, int len, MYSQL &sqlCon, SOCKET lisSock) {
	const LOGIN* loginMsg = (LOGIN*)recvData;
	printf("登录消息:%s\t%s\n", loginMsg->userId, loginMsg->userPassword);

	CString query;
	query.Format(_T("select * from student_info where studentId like '%s' and studentPassword like '%s';"), loginMsg->userId, loginMsg->userPassword);
	const char *str = (char*)query.GetBuffer(0);//要将属性中字符类型改为多字节

	int ress = mysql_real_query(&sqlCon, str, strlen(str));
	MYSQL_RES *res;
	MYSQL_ROW row;
	if (ress == 0)//检测查询成功
	{
		res = mysql_store_result(&sqlCon);//得到存储结果集  
		if (mysql_num_rows(res) == 0) {

			LOGIN_RESULT loginResult;
			memset(&loginResult, 0, sizeof(LOGIN_RESULT));
			loginResult.msgID = LOGIN_RESULT_MSGID;
			strcpy_s(loginResult.result, "loginFalse");

			char buff[1024] = { 0 };
			memset(buff, 0, sizeof(buff));
			memcpy(buff, &loginResult, sizeof(loginResult));
			send(lisSock, buff, sizeof(buff), 0);

		}
		else
		{
			LOGIN_RESULT loginResult;
			memset(&loginResult, 0, sizeof(LOGIN_RESULT));
			loginResult.msgID = LOGIN_RESULT_MSGID;
			strcpy_s(loginResult.result, "loginTrue");

			char buff[1024] = { 0 };
			memset(buff, 0, sizeof(buff));
			memcpy(buff, &loginResult, sizeof(loginResult));
			send(lisSock, buff, sizeof(buff), 0);

		}
	}
}

void DB_Register(const char* recvData, int len, MYSQL &sqlCon, SOCKET lisSock) {
	const REGISTER* registerMsg = (REGISTER*)recvData;
	printf("注册消息:%s\t%s\t%s\n", registerMsg->userId, registerMsg->userName, registerMsg->userPassword);

	CString query;
	query.Format(_T("insert into student_info values('%s','%s','%s');"), registerMsg->userId, registerMsg->userName, registerMsg->userPassword);
	//AfxMessageBox(query.GetBuffer(0));
	const char *str = (char*)query.GetBuffer(0);//要将属性中字符类型改为多字节

	if (mysql_real_query(&sqlCon, str, strlen(str)))
	{
		REGISTER_RESULT registerResult;
		memset(&registerResult, 0, sizeof(REGISTER_RESULT));
		registerResult.msgID = REGISTER_RESULT_MSGID;
		strcpy_s(registerResult.result, "registerFalse");

		char buff[1024] = { 0 };
		memset(buff, 0, sizeof(buff));
		memcpy(buff, &registerResult, sizeof(registerResult));
		send(lisSock, buff, sizeof(buff), 0);
	}
	else
	{
		REGISTER_RESULT registerResult;
		memset(&registerResult, 0, sizeof(REGISTER_RESULT));
		registerResult.msgID = REGISTER_RESULT_MSGID;
		strcpy_s(registerResult.result, "registerTrue");

		char buff[1024] = { 0 };
		memset(buff, 0, sizeof(buff));
		memcpy(buff, &registerResult, sizeof(registerResult));
		send(lisSock, buff, sizeof(buff), 0);

	}
}

void DB_AllCourse(const char* recvData, int len, MYSQL &sqlCon, SOCKET lisSock)//查看所有课程
{

	CString query;
	query.Format(_T("select * from course;"));
	AfxMessageBox(query.GetBuffer(0));
	const char *str = (char*)query.GetBuffer(0);//要将属性中字符类型改为多字节

	int ress = mysql_real_query(&sqlCon, str, strlen(str));
	MYSQL_RES *result;

	if (ress == 0)//检测查询成功
	{
		result = mysql_store_result(&sqlCon);//得到存储结果集  
		int rowCount = mysql_num_rows(result);//行数									  
		unsigned int fieldCount = mysql_num_fields(result);//列数

		//逐行发送
		MYSQL_ROW row = NULL;
		row = mysql_fetch_row(result);
		printf("全部课程:\n");

		char buff[1024] = { 0 };
		int line = 0;
		while (NULL != row) {
			printf("%d\t%s\t%s\t%s\t%s\t%s\t%s\n",line,row[0], row[1], row[2], row[3], row[4], row[5]);
			ALLCOURSE_RESULT course;
			course.msgID = ALLCOURSE_RESULT_MSGID;
			course.row = line;
			line++;
			strcpy_s(course.courseId, row[0]);
			strcpy_s(course.courseName, row[1]);
			strcpy_s(course.courseScore, row[2]);
			strcpy_s(course.courseTime, row[3]);
			strcpy_s(course.coursePeople, row[4]);
			strcpy_s(course.teacherId, row[5]);


			memset(buff, 0, sizeof(buff));
			memcpy(buff, &course, sizeof(course));
			send(lisSock, buff, sizeof(buff), 0);

			row = mysql_fetch_row(result);
		}
	}
}

void DB_Student_Course(const char* recvData, int len, MYSQL &sqlCon, SOCKET lisSock) {//查看学生所选课程
	const STUDENT_COURSE* studentMsg = (STUDENT_COURSE*)recvData;
	printf("查询%s学生课程:\n",studentMsg->userId);

	CString query;
	query.Format(_T("select *from course WHERE courseId in ( select courseId from selectcourse where studentId = '%s');"),studentMsg->userId);
	//AfxMessageBox(query.GetBuffer(0));
	const char *str = (char*)query.GetBuffer(0);//要将属性中字符类型改为多字节

	int ress = mysql_real_query(&sqlCon, str, strlen(str));
	MYSQL_RES *result;


	if (ress == 0)//检测查询成功
	{
		result = mysql_store_result(&sqlCon);//得到存储结果集  
		int rowCount = mysql_num_rows(result);//行数		
		unsigned int fieldCount = mysql_num_fields(result);
														   
		MYSQL_ROW row = NULL;
		row = mysql_fetch_row(result);

		char buff[1024] = { 0 };
		int line = 0;
		while (NULL != row) {
			printf("%d\t%s\t%s\t%s\t%s\t%s\t%s\n", line, row[0], row[1], row[2], row[3], row[4], row[5]);
			ALLCOURSE_RESULT course;
			course.msgID = STUDENT_COURSE_RESULT_MSGID;
			course.row = line;
			line++;
			strcpy_s(course.courseId, row[0]);
			strcpy_s(course.courseName, row[1]);
			strcpy_s(course.courseScore, row[2]);
			strcpy_s(course.courseTime, row[3]);
			strcpy_s(course.coursePeople, row[4]);
			strcpy_s(course.teacherId, row[5]);


			memset(buff, 0, sizeof(buff));
			memcpy(buff, &course, sizeof(course));
			send(lisSock, buff, sizeof(buff), 0);

			row = mysql_fetch_row(result);
		}
	}
}

void DB_Student_AddCourse(const char* recvData, int len, MYSQL &sqlCon, SOCKET lisSock)//学生添加课程
{
	const STUDENT_ADD_COURSE* msg = (STUDENT_ADD_COURSE*)recvData;
	printf("%s学生添加%s课程\n", msg->userId, msg->courseId);

	CString query;
	query.Format(_T("insert into selectcourse values('%s','%s');"), msg->userId,msg->courseId);
	const char *str = (char*)query.GetBuffer(0);//要将属性中字符类型改为多字节
												
	int res = mysql_real_query(&sqlCon, str, strlen(str));
	if (res == 0)
	{
		STUDENT_ADD_COURSE_RESULT addCourseResult;
		memset(&addCourseResult, 0, sizeof(STUDENT_ADD_COURSE_RESULT));
		addCourseResult.msgID = STUDENT_ADD_COURSE_RESULT_MSGID;
		strcpy_s(addCourseResult.result, "addCourseTrue");

		char buff[1024] = { 0 };
		memset(buff, 0, sizeof(buff));
		memcpy(buff, &addCourseResult, sizeof(addCourseResult));
		send(lisSock, buff, sizeof(buff), 0);
	}
	else
	{
		STUDENT_ADD_COURSE_RESULT addCourseResult;
		memset(&addCourseResult, 0, sizeof(STUDENT_ADD_COURSE_RESULT));
		addCourseResult.msgID = STUDENT_ADD_COURSE_RESULT_MSGID;
		strcpy_s(addCourseResult.result, "addCourseFalse");

		char buff[1024] = { 0 };
		memset(buff, 0, sizeof(buff));
		memcpy(buff, &addCourseResult, sizeof(addCourseResult));
		send(lisSock, buff, sizeof(buff), 0);
	}

}

void DB_Student_DeleteCourse(const char* recvData, int len, MYSQL &sqlCon, SOCKET lisSock) {
	const STUDENT_DELETE_COURSE* msg = (STUDENT_DELETE_COURSE*)recvData;
	printf("%s学生删除%s课程\n", msg->userId, msg->courseId);

	CString query;
	query.Format(_T("delete from selectcourse where studentId = '%s' and courseId = '%s';"), msg->userId, msg->courseId);
	const char *str = (char*)query.GetBuffer(0);//要将属性中字符类型改为多字节

	int res = mysql_real_query(&sqlCon, str, strlen(str));
	if (res == 0)
	{
		STUDENT_DELETE_COURSE_RESULT deleteCourseResult;
		memset(&deleteCourseResult, 0, sizeof(STUDENT_DELETE_COURSE_RESULT));
		deleteCourseResult.msgID = STUDENT_DELETE_COURSE_RESULT_MSGID;
		strcpy_s(deleteCourseResult.result, "deleteCourseTrue");

		char buff[1024] = { 0 };
		memset(buff, 0, sizeof(buff));
		memcpy(buff, &deleteCourseResult, sizeof(deleteCourseResult));
		send(lisSock, buff, sizeof(buff), 0);
	}
	else
	{
		STUDENT_DELETE_COURSE_RESULT deleteCourseResult;
		memset(&deleteCourseResult, 0, sizeof(STUDENT_DELETE_COURSE_RESULT));
		deleteCourseResult.msgID = STUDENT_DELETE_COURSE_RESULT_MSGID;
		strcpy_s(deleteCourseResult.result, "deleteCourseFalse");

		char buff[1024] = { 0 };
		memset(buff, 0, sizeof(buff));
		memcpy(buff, &deleteCourseResult, sizeof(deleteCourseResult));
		send(lisSock, buff, sizeof(buff), 0);
	}
}

在客户端中,写一个继承自CSOCKET的类,并实现其OnRecevie方法:

#include "../select/netStruct.h"


extern HWND login_hwnd;
extern HWND student_hwnd;

// clientSock

clientSock::clientSock()
{
}

clientSock::~clientSock()
{
}


// clientSock 成员函数


void clientSock::OnReceive(int nErrorCode)
{
	// TODO: 在此添加专用代码和/或调用基类
	
	char recvData[1024] = {0};
	memset(recvData, 0, sizeof(recvData));
	int nLen = Receive(recvData, sizeof(recvData));

	short msgID = *(short*)recvData;
	switch (msgID)
	{

		case LOGIN_RESULT_MSGID:
		{
			LOGIN_RESULT loginMsg;
			memset(&loginMsg, 0, sizeof(LOGIN_RESULT));
			memcpy(&loginMsg,recvData, sizeof(loginMsg));//注意sizeof中要是转换的结构体大小
			if (strcmp(loginMsg.result, "loginTrue") == 0) {
				AfxMessageBox("登录成功!");
				::PostMessage(login_hwnd, LOGINMSG, 0, (LPARAM)recvData);//自定义消息,用于将内容传到对话框
			}
			else
			{
				AfxMessageBox("登录失败!");
			}

		}
		break;

		case REGISTER_RESULT_MSGID:
		{
			REGISTER_RESULT registerMsg;
			memset(&registerMsg, 0, sizeof(LOGIN_RESULT));
			memcpy(&registerMsg, recvData, sizeof(registerMsg));//注意sizeof中要是转换的结构体大小
			if (strcmp(registerMsg.result, "registerTrue") == 0) {
				AfxMessageBox("注册成功!");
			}
			else
			{
				AfxMessageBox("注册失败!");
			}

		}
		break;

		case ALLCOURSE_RESULT_MSGID://显示所有课程
		{
			::PostMessage(student_hwnd, SHOW_COURSE_MSG, 0, (LPARAM)recvData);//自定义消息
		}
		break;

		case STUDENT_COURSE_RESULT_MSGID://显示学生已选课程
		{
			::PostMessage(student_hwnd, SHOW_MYCOURSE_MSG, 0, (LPARAM)recvData);//自定义消息
		}
		break;

		case STUDENT_ADD_COURSE_RESULT_MSGID://学生添加课程结果
		{
			STUDENT_ADD_COURSE_RESULT addMsg;
			memset(&addMsg, 0, sizeof(STUDENT_ADD_COURSE_RESULT));
			memcpy(&addMsg, recvData, sizeof(addMsg));//注意sizeof中要是转换的结构体大小
			if (strcmp(addMsg.result, "addCourseTrue") == 0) {
				::PostMessage(student_hwnd, UPDATE_DATA_MSG, 0, 0);//自定义消息
				AfxMessageBox("选课成功!");
			}
			else
			{
				AfxMessageBox("选课失败!");
			}
		}
		break;

		case STUDENT_DELETE_COURSE_RESULT_MSGID://学生添加课程结果
		{
			STUDENT_DELETE_COURSE_RESULT deleteMsg;
			memset(&deleteMsg, 0, sizeof(STUDENT_DELETE_COURSE_RESULT));
			memcpy(&deleteMsg, recvData, sizeof(deleteMsg));//注意sizeof中要是转换的结构体大小
			if (strcmp(deleteMsg.result, "deleteCourseTrue") == 0) {
				::PostMessage(student_hwnd, UPDATE_DATA_MSG, 0, 0);//自定义消息
				AfxMessageBox("删除课程成功!");
			}
			else
			{
				AfxMessageBox("删除课程失败!");
			}
		}
		break;
	}

	CSocket::OnReceive(nErrorCode);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值