第零步: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