protobuf 通信 实现登录注册功能 连mysql

第零步:protobuf实现通信 linux 实现 protobuf 通信_Adolphrocs的博客-CSDN博客

第一步:安装mysql

第二步:创建一个database 叫 Net, 新建一个表LoginInfo (mysql教程: MySQL 教程 | 菜鸟教程)

第三步:

server.cpp

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <bits/stdc++.h>
#include "test.pb.h"
#include "mysql.h"

using namespace std;
using namespace Test::protobuf;

class CMysqlInterface
{
public:
	CMysqlInterface();
	~CMysqlInterface();

	void mysqlLibInit();
	void mysqlLibDestroy();
	string QueryDatabase(const string& UserName, const string& UserPwd);
	string InsertData(const string& UserName, const string& UserPwd);
	bool ModifyData();
	bool DeleteData();
	int Connect();
	int Close();

private:
	MYSQL* m_mysqlPtr;
	MYSQL_FIELD* fd;    //字段列数组
	char field[32][32]; //存字段名二维数组
	MYSQL_RES* res;     //行的一个查询结果集
	MYSQL_ROW column;   //数据行的列
	char query[150];    //查询语句
};

const int MAXSIZE = 4096;
void output(HeartInfo ServerHI);
int main(){
    //创建套接字
    int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (serv_sock <= 0)
	{
		cout << "Server create socket failed = " << errno << endl;
	}
	else
	{
		cout << "Server create socket success ..." << endl;
	}
    //将套接字和IP、端口绑定
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));  //每个字节都用0填充
    serv_addr.sin_family = AF_INET;  //使用IPv4地址
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具体的IP地址
    serv_addr.sin_port = htons(8888);  //端口
    int BindResult = bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
    if (BindResult < 0) 
	{
        cout << "Server bind failed ..." << endl;
        return -1;
    }
    else 
	{
        cout << "Server bind success ..." << endl;
    }

	//连接Mysql 数据库
	int iRet = -1;
	CMysqlInterface MysqlObj;
	iRet = MysqlObj.Connect();
	
	//进入监听状态,等待用户发起请求
	listen(serv_sock, 20);
	//接收客户端请求
	struct sockaddr_in clnt_addr;
	socklen_t clnt_addr_size = sizeof(clnt_addr);
	int clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);


    char buffer[MAXSIZE];
    HeartInfo serverHI;
    read(clnt_sock, buffer, sizeof(buffer));
    if (strlen(buffer) != 0) 
	{
        //printf("Message form client: %s\n", buffer);
        serverHI.ParseFromArray(buffer, sizeof(buffer));
		output(serverHI);

		//写入数据库
		if (serverHI.loginorregister() == "Login") //登录
		{
			string Loginresult = MysqlObj.QueryDatabase(serverHI.uname(), serverHI.upwd());
			const char* Loginresult_c = Loginresult.c_str();
			write(clnt_sock, Loginresult_c, MAXSIZE);
		}
		else //注册
		{
			string Loginresult = MysqlObj.QueryDatabase(serverHI.uname(), serverHI.upwd());
			if (Loginresult == "Please Register First ...")
			{
				string RegisterResult = MysqlObj.InsertData(serverHI.uname(), serverHI.upwd());
				const char* RegisterResult_c = RegisterResult.c_str();
				write(clnt_sock, RegisterResult_c, MAXSIZE);
			}
			else
			{
				const char* Loginresult_c = "Your Have Registered ...";
				write(clnt_sock, Loginresult_c, MAXSIZE);
			}
		}
    }
    //关闭套接字
    close(clnt_sock);
    close(serv_sock);
    return 0;
}

void output(HeartInfo serverHI) 
{
	cout << "HostIp Is ..." << serverHI.hostip() << endl;
	cout << "curtime Is ..." << serverHI.curtime() << endl;
	cout << serverHI.loginorregister() << endl;
	cout << "UserName Is ..." << serverHI.uname() << endl;
	cout << "Password Is ..." << serverHI.upwd() << endl;
}
CMysqlInterface::CMysqlInterface()
{
	printf("CMysqlInterface ...\n");
	m_mysqlPtr = NULL;
	m_mysqlPtr = mysql_init(NULL);
}

CMysqlInterface::~CMysqlInterface()
{
	Close();
}

int CMysqlInterface::Close()
{
	int iRet = 0;

	if (NULL != m_mysqlPtr)
	{
		mysql_close(m_mysqlPtr);
		m_mysqlPtr = NULL;
	}
	return iRet;
}

void CMysqlInterface::mysqlLibDestroy()
{
	mysql_library_end();
}

int CMysqlInterface::Connect()
{
	printf("Connect ...\n");
	int iRet = -1;
	m_mysqlPtr = mysql_real_connect(m_mysqlPtr, "localhost", "root", NULL, "Net", 0, NULL, 0);
	if (m_mysqlPtr)
	{
		iRet = 0;
	}
	if (0 == iRet)
	{
		printf("mysql_real_connect success\n");
	}
	else
	{
		printf("mysql_real_connect failed\n");
	}
	return iRet;
}

string CMysqlInterface::QueryDatabase(const string& UserName, const string& UserPwd) 
{
	//将数据格式化输出到字符串
	sprintf(query, "select * from LoginInfo");
	//设置编码格式
	mysql_query(m_mysqlPtr, "set names gbk");

	if (mysql_query(m_mysqlPtr, query))
	{
		printf("Query failed (%s)\n", mysql_error(m_mysqlPtr));
		return "Query failed";
	}
	else 
	{
		printf("query success\n");
	}

	res = mysql_store_result(m_mysqlPtr);
	if (!res) {
		printf("Couldn't get result from %s\n", mysql_error(m_mysqlPtr));
		return "Couldn't get result";
	}
	//查询的数据行数
	printf("number of dataline returned: %d\n", (int)mysql_affected_rows(m_mysqlPtr));
	// 获取列数
	int j = mysql_num_fields(res);
	//存储字段信息
	char* str_field[32];
	//获取字段名
	for (int i = 0; i < j; i++) {
		str_field[i] = mysql_fetch_field(res)->name;
	}
	//打印字段
	for (int i = 0; i < j; i++)
		printf("%10s\t", str_field[i]);
	printf("\n");
	//打印查询结果
	//MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)
	//Fetches the next row from the result set
	bool IsRegistered = false, IsPassWordRight = false;
	while (column = mysql_fetch_row(res)) {
		printf("%10s\t%10s\n", column[0], column[1]);
		const char* UserName_c = UserName.c_str();
		if (strcmp(column[0], UserName_c) == 0) {
			IsRegistered = true;
			const char* Userpwd_c = UserPwd.c_str();
			if (strcmp(column[1], Userpwd_c) == 0) {
				IsPassWordRight = true;
			}
			else IsPassWordRight = false;
		}
	}
	string LastResult;
	if (IsRegistered) {
		if (IsPassWordRight) LastResult = "Login Success...";
		else LastResult = "Password WRONG!!!";
	}
	else {
		LastResult = "Please Register First ...";
	}
	//cout << UserName << " : " << LastResult << endl;

	return LastResult;
}

//插入数据
string CMysqlInterface::InsertData(const string& UserName, const string& UserPwd) {
	char* UserName_c = (char*)UserName.c_str();
	char* UserPwd_c = (char*)UserPwd.c_str();
	sprintf(query, "insert into LoginInfo values ('%s', '%s');", UserName_c, UserPwd_c);
	if (mysql_query(m_mysqlPtr, query)) {
		//printf("Query failed (%s)\n", mysql_error(m_mysqlPtr));
		return "Insert failed ...";
	}
	else {
		//printf("Insert success ...\n");
		return "Insert success ...";
	}
}

client.cpp

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <bits/stdc++.h>
#include "test.pb.h"

using namespace std;
using namespace Test::protobuf;

const int MAXSIZE = 4096;
int CreateSocket()
{
	int sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock <= 0)
	{
        cout << "Client create socket failed = " << errno << endl;
	}
	else
	{
		cout << "Client create socket success ..." << endl;
	}
    return sock;
}

int ConnectServer(int sock, sockaddr_in &serv_addr)
{
	int ConnectResult = connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
	if (ConnectResult < 0)
	{
		cout << "Client connect server failed ..." << endl;
		close(sock);
		return ConnectResult;
	}
	else
	{
		cout << "Client connect server success ..." << endl;
        return ConnectResult;
	}
}

int main() {
    //创建套接字
    int sock = CreateSocket();

    //向服务器(特定的IP和端口)发起请求
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));  //每个字节都用0填充
    serv_addr.sin_family = AF_INET;  //使用IPv4地址
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具体的IP地址
    serv_addr.sin_port = htons(8888);  //端口
    
    int ConnectResult = ConnectServer(sock, serv_addr);
    if (ConnectResult < 0) return -1;
   
    //读取服务器传回的数据

    char buffer[40];
// 	read(sock, buffer, sizeof(buffer) - 1);
// 
// 	printf("Message form server: %s\n", buffer);
// 
//     cin >> buffer;
//     write(sock, buffer, sizeof(buffer));

    cout << "Please Input Your Next Operation ... Login(L) or Register(R)" << endl;
    string operation;
    cin >> operation;
	cout << "Please Input Your UserName and Password ..." << endl;
	string uname, upwd;
	cin >> uname >> upwd;
	HeartInfo newHI;
	int curtime = time(NULL);
	newHI.set_curtime(curtime);
	newHI.set_hostip("127.0.0.1");
	newHI.set_uname(uname);
	newHI.set_upwd(upwd);
	char buff[MAXSIZE];
    if (operation == "Login" || operation == "L")
	{
		newHI.set_loginorregister("Login");
    }
	else
	{
		newHI.set_loginorregister("Register");
	}
	newHI.SerializeToArray(buff, 100);
	write(sock, buff, sizeof(buff));
	//进入监听状态,等待服务器回应
	//listen(sock, 20);

	memset(buffer, 0, sizeof(buffer));
	read(sock, buffer, sizeof(buffer));
	cout << buffer << endl;
    //关闭套接字
    close(sock);
    return 0;
}

第四步:编译

g++ -o server server.cpp test.pb.cc -lprotobuf -lpthread -lmysqlclient -I/usr/include/mysql -L/usr/lib/mysql
g++ -o client client.cpp test.pb.cc -lprotobuf -lpthread

参考:C/C++连接MySQL数据库执行查询 - wangzhch - 博客园

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值