聊一聊系统 (Linux下实现群聊系统)

1.原理


聊一聊系统 (Linux下实现群聊系统)_第1张图片

 

  • 客户端从标准输入读取数据,将数据序列化后发送至网络;

  • 服务器端使用多线程+生产者消费者模型

    • 生产者从网络中读取数据,并将读取到的用户信息添加至用户列表中,将数据放至数据池中;

    • 消费者从数据池读取数据,并广播给所有在用户列表中的用户;

  • 数据经过网络以后,反序列化再次发给客户端,实现群聊功能;

 

2.所用技术


    平台: CentOS 7, 64位操作系统

    语言: C/C++

    编译工具: g++

    序列化反序列化工具:  jsoncpp

    窗口设计框架:  nucrse/ncurses

    其他: 生产者消费者模型、信号量互斥机制、多线程编程、socket套接字编程

 

3.系统框架


server模块: 收到用户发送的字符串以后, 将用户信息存储到在线用户表中,将数据存储到数据池中, 再将数据广播给所有在线用户;

client模块: 从标准输入读取用户数据,并且将字符串序列化,发送给服务器; 接收到服务器的数据以后,反序列化,输出到output框;

data_pool模块: 数据池,存放用户发过来的诗句,是一个环形队列描述的;

window模块: 显示用户界面,使用ncurses库实现;

 

4.具体模块


server:

聊一聊系统 (Linux下实现群聊系统)_第2张图片

部分成员函数:

addrUser: 将用户添加至online中

delUser: 将用户online中删除

RecvDate: 接收客户端发送到网络中的数据,并且判断用户的cmd状态是不是"QUIT",就调用del从online中删除,如果用户状态不为"QUIT",就将用户数据存放到数据池

SendData: 将数据发给所有才online列表中的用户

部分成员变量:

std::map online: 是一个在线用户表,使用的是STL中的map结构,以ip为键,sockaddr_in结构体为值,可通过ip地址查找到对应用户。

data_pool pool: 后面讲解;

 

clinet:

聊一聊系统 (Linux下实现群聊系统)_第3张图片

client这里的定义比较简单,进行数据的收发,但是主逻辑部分实现逻辑就比较复杂了

首先,我们使用多线程,为了使用户端聊天室的每一个部分都独立(主要分为欢迎头部,输出框,和输入框)

聊一聊系统 (Linux下实现群聊系统)_第4张图片

  • 欢迎头部的功能就是滚动的播放welcome

  • 输出框又分为了输出用户信息和在线成员,并且实现框满清屏的效果

  • 输入框使用户用来输入消息,按回车键就发送出去

data_pool:

聊一聊系统 (Linux下实现群聊系统)_第5张图片

data_pool是实现一个数据池,讲用户发来的数据都存储在数据池中,服务器要广播数据的时候,也会从数据池中拿数据。

这里使用生产者消费者模型,完成资源的同步与互斥,使用vector维护一个环形队列,生产者只在意当前环形队列的空白个数,消费者只在意当前的数据个数。

 

window:

聊一聊系统 (Linux下实现群聊系统)_第6张图片

因为在客户端是多线程并发执行数据,我们这里使用互斥锁来保证线程安全。

window模块主要是实现客户端界面,设计效果如下

聊一聊系统 (Linux下实现群聊系统)_第7张图片

comm:

这一部分主要实数据的序列化和反序列化,使用 jsoncpp

聊一聊系统 (Linux下实现群聊系统)_第8张图片

并且将序列化和反序列化进行简单的封装

聊一聊系统 (Linux下实现群聊系统)_第9张图片

发送的数据会有 昵称、学校、消息内容、状态信息,客户端将这些信息发送出去以后,在网络中会序列化为一个字符串,服务器接收到数据以后,再将字符串反序列化为用户信息,进行存储和处理。

5.效果演示


聊一聊系统 (Linux下实现群聊系统)_第10张图片

 

6.代码链接


聊一聊系统

 

你可能感兴趣的:(jsoncpp,ncurses,多线程,生产者消费者模型,http,udp)