libevent+QT即时通信项目——服务器链表设计(上)

通信

4.服务器链表设计

在这里插入图片描述

2个链表

MySQL

安装
sudo apt-get update
sudo apt-get install mysql-server mysql-client libmysqlclient-dev

查看版本 mysql -V 或者进入mysql select version();

设置密码

  1. 首先,登录到 MySQL 服务器:

    sudo mysql
    
  2. 在进入 MySQL 提示符后,将以下命令替换为你希望设置的密码,并执行该命令:

    ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password';
    

    'your_password' 替换为你想要设置的实际密码。

  3. 如果 MySQL 服务器上有其他用户,你可能还需要更新其他用户的密码。执行以下命令来查看当前存在的用户:

    SELECT user FROM mysql.user;
    

    然后对于每个用户,使用以下命令设置密码(将 useryour_password 替换为实际值):

    ALTER USER 'user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password';
    
  4. 最后,刷新权限以使更改生效:

    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 的作用就是创建类型的别名,从而简化代码并提高代码的可读性。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值