一.原理

mini聊天室(Linux下基于UDP实现的群聊系统)

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

(2)服务器端使用多线程+生产者消费者模型;

  • 生产者从网络中读取数据,并将读取到的用户信息添加至用户列表,将数据放至数据池中;
  • 消费者从数据池读取数据,并广播给所有在用户列表中的用户。

(3)数据经过网络以后,反序列化再次发送给客户端,实现群聊功能。

二.所用技术

平台:Centos7.0,64位操作系统

语言:C/C++

编译工具:g++

序列化和反序列化工具:jsoncpp

窗口设计框架:ncurse/ncurses

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

三.系统框架

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

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

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

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

四.具体模块

server:

mini聊天室(Linux下基于UDP实现的群聊系统)

部分成员函数介绍:

addrUser:将上线用户添加至online用户列表中; 

delUser:将下线用户从online用户列表中删除;

RecvData:接受客户端发送到网络中的数据,并且判断用户的cmd状态是否是“QUIT”,若是“QUIT”就调用del将该用户从online用户列表中删除,若不是“QUIT”就将该用户数据存放至数据池;

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

部分成员变量的介绍:

std::map<int,struct sockaddr_in> online:维护一个在线用户列表,使用的是STL中的map数据结构,以ip为key值,sockaddr_in结构体为value值,可以通过ip地址查找到对应的用户;

client:

mini聊天室(Linux下基于UDP实现的群聊系统)

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

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

mini聊天室(Linux下基于UDP实现的群聊系统)

(1)标题部分:实现左右滚动的播放标题头部信息;

(2)输出框:输出分为用户数据和在线成员列表,并且实现满屏就清屏的效果;

(3)输入框:用户输入要发送的消息,按回车键就发送出去。

data_pool:

mini聊天室(Linux下基于UDP实现的群聊系统)

data_pool是实现一个数据池,将用户发来的数据都存储在数据池中,服务器要广播数据的时候,就从数据池中拿取数据;

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

window:

mini聊天室(Linux下基于UDP实现的群聊系统)

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

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

mini聊天室(Linux下基于UDP实现的群聊系统)

comm:

这一部分主要实现数据的序列化和反序列化,使用C++第三方库jsoncpp来完成;

mini聊天室(Linux下基于UDP实现的群聊系统)

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

mini聊天室(Linux下基于UDP实现的群聊系统)

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

四.聊天效果图

mini聊天室(Linux下基于UDP实现的群聊系统)

项目源码:https://gitee.com/ypttest/chat_system

相关文章:

  • 2021-11-07
  • 2021-04-09
  • 2021-04-17
  • 2021-10-18
猜你喜欢
  • 2021-04-26
  • 2022-12-23
  • 2021-11-06
  • 2022-12-23
  • 2021-10-05
  • 2021-06-21
  • 2021-10-13
相关资源
相似解决方案