通信
4.服务器链表设计
2个链表
MySQL
安装
sudo apt-get update
sudo apt-get install mysql-server mysql-client libmysqlclient-dev
查看版本 mysql -V 或者进入mysql select version();
设置密码
-
首先,登录到 MySQL 服务器:
sudo mysql
-
在进入 MySQL 提示符后,将以下命令替换为你希望设置的密码,并执行该命令:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password';
将
'your_password'
替换为你想要设置的实际密码。 -
如果 MySQL 服务器上有其他用户,你可能还需要更新其他用户的密码。执行以下命令来查看当前存在的用户:
SELECT user FROM mysql.user;
然后对于每个用户,使用以下命令设置密码(将
user
和your_password
替换为实际值):ALTER USER 'user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password';
-
最后,刷新权限以使更改生效:
FLUSH PRIVILEGES;
添加测试数据
mysql -uroot -p
show database;
create database user;
create database chatgroup;
use chatgroup;
CREATE TABLE 学习交流群1 (owner VARCHAR(32),member VARCHAR(2048)) CHAR SET utf8;
CREATE TABLE 学习交流群2 (owner VARCHAR(32),member VARCHAR(2048)) CHAR SET utf8;
CREATE TABLE 学习交流群3 (owner VARCHAR(32),member VARCHAR(2048)) CHAR SET utf8;
insert into 学习交流群1(owner,member) values("小张","肥猪|狗杰|比凯|莎边");
insert into 学习交流群2(owner,member) values("小成","小哈|阿强|李四|王五");
insert into 学习交流群3(owner,member) values("小青","小枪|兄|雨燕|波大");
select *from 学习交流群1;
数据库操作文件
chat_databases.h
#ifndef CHAT_DATABASES_H
#define CHAT_DATABASES_H
#include <mysql/mysql.h>
#include <iostream>
#include <string>
class ChatDataBases
{
private:
MYSQL *mysql;
public:
ChatDataBases();
~ChatDataBases();
void my_database_connect(const char *name); //参数是你要链接的数据库名字
int my_database_get_group_name(std::string *); //获取群的数量和群名字.数量直接return就好;名字是string类型的,用一个string数组保存起来
};
#endif
chat_databases.cpp
#include "chat_databases.h"
ChatDataBases::ChatDataBases()
{
mysql = mysql_init(nullptr);
}
ChatDataBases::~ChatDataBases()
{
mysql_close(mysql);
}
void ChatDataBases::my_database_connect(const char*databaseName)
{
mysql = mysql_real_connect(mysql,"localhost","root","1227",databaseName, 0, NULL, 0);
if (!mysql)
{
std::cout << "database connect failure! " << std::endl;
}
}
int ChatDataBases::my_database_get_group_name(std::string *s)
{
//设置中文,不然读取出来的数据会是乱码
if (mysql_query(mysql,"set names utf8") != 0)
{
std::cout << "mysql_query error" << std::endl;
}
if (mysql_query(mysql,"show tables;") != 0)
{
std::cout << "mysql_query error" << std::endl;
}
//存储数据
MYSQL_RES *res = mysql_store_result(mysql);
if (!res)
{
std::cout << "mysql_store_result error" << std::endl;
}
/*res就是下面这个结果,然后对这个结果进行解析就好
mysql> show tables;
+---------------------+
| Tables_in_chatgroup |
+---------------------+
| 学习交流群1 |
| 学习交流群2 |
| 学习交流群3 |
+---------------------+
*/
//一行就是一个数据,直接按行读取
MYSQL_ROW row;
int count = 0;
while (row = mysql_fetch_row(res))
{
s[count] = row[0];
count++;
}
return count;
}
链表设计
chatinfo.h
#ifndef CHATINFO_H
#define CHARINFO_H
#include <iostream>
#include <string>
#include <list>
#include <event.h>
#include "chat_databases.h"
#define MAXGROUPNUM 1024 //查询的群最大数量
//在线用户,bev只有客户端上线了才会创建对象
struct User
{
std::string name;
struct bufferevent *bev;
};
typedef struct User User;
struct GroupUser
{
std::string name; //用户名
};
typedef struct GroupUser GroupUser;
//交流群信息,一开始就有
struct Group
{
std::string name; //群名
std::list<GroupUser> *l;
};
typedef struct Group Group;
class ChatInfo
{
private:
std::list<User> *onlineUser; //在线用户链表,有用户上线才有
std::list<Group> *group_info; //交流群链表 ,一开始就有
ChatDataBases *mydatabase; //数据库对象
public:
ChatInfo();
~ChatInfo();
};
#endif
chatinfo.cpp
#include "chatinfo.h"
ChatInfo::ChatInfo()
{
onlineUser = new std::list<User>; //空
group_info = new std::list<Group>; //群
//往group_info链表里添加群信息
//这里需要数据库的保存的群信息,所以要先创建好操作数据库的文件chat_databases
//操作数据库
mydatabase = new ChatDataBases();
mydatabase->my_database_connect("chatgroup"); //连接
std::string group_name[MAXGROUPNUM];
int groupNum = mydatabase->my_database_get_group_name(group_name);
std::cout << "群组数量为:" << groupNum << std::endl;
for (size_t i = 0; i < groupNum; ++i)
{
std::cout << "群名" << i<< ": " << group_name[i] << std::endl;
}
}
ChatInfo::~ChatInfo()
{
if (onlineUser)
{
delete onlineUser;
onlineUser = nullptr;
}
if (group_info)
{
delete group_info;
group_info = nullptr;
}
}
server.h .cpp 添加链表对象
class Server
{
private:
struct event_base *base; //事件集合,这个管理集合
struct evconnlistener *listener; //监听事件
ChatInfo *chatlist; //链表对象(里面有两个链表,分别保存在线用户信息和群信息)
}
Server::Server(const char *ip , int port)
{
chatlist = new ChatInfo();
}
编译执行:
g++ *.cpp -o main -levent -lpthread -lmysqlclient -std=c++11
知识点1 - - typedef
typedef
是C/C++中的关键字,用于==为数据类型取别名==。在给定的代码中,typedef
用于为 struct Group
定义了一个别名 Group
。
作为别名,可以通过使用 Group
来代替 struct Group
来声明变量、定义函数参数、返回类型等。这样做的好处是可以简化代码,使其更易读,同时也增加了代码的可维护性和可读性。
例如,在给定的代码中,通过使用 typedef struct Group Group;
可以将 struct Group
这个较长的类型名称简化为 Group
。这样在后续的代码中就可以直接使用 Group
来声明变量,而不需要写成 struct Group
。
示例用法:
cCopy CodeGroup myGroup; // 使用 typedef 后直接使用 Group 代替了 struct Group
// 函数参数和返回类型
void functionName(Group param);
Group functionName();
// 定义指针变量
Group* groupPtr;
总结来说,typedef
的作用就是创建类型的别名,从而简化代码并提高代码的可读性。