嗨聊

嗨聊

功能的描述

  • 客户端启动,提示你输入昵称(等其他信息);
  • 按下回车之后,就连接到服务器上;
  • 每个客户端能够看到当前聊天室的成员;
  • 通过客户端发送一条消息,聊天室中所有的成员都能看到。
  • 聊天室中任何成员发送的消息,你也能看到。

项目实现

  1. 用UDP协议实现数据的传输;
  2. 用jsoncpp实现数据的序列化和反序列化;
  3. 使用unordered_map来维护在线好友列表;
  4. 使用生产者/消费者模型传输数据,同时也可以广播数据给所有在线用户;
  5. 使用ncurses来绘制用户界面。

服务器模块

接受客户端的消息,并且广播给所有在线用户。

服务器需要能够:

  1. 能够存储在线好友列表(包含好友的昵称信息,IP地址)
  2. 能够感知到某个成员的上线和下线(使用哈希表的形式来存储好友列表)
  3. 接收消息(生产者线程,接收消息,把消息写入到一个队列中)
  4. 广播消息(消费者线程,从队列中读取消息,遍历好友列表,分别给每个好友发送消息)

详细过程介绍
1. 从 socket 中读取数据
2. 把数据转发给所有的在线成员
3. 维护在线成员列表(unordered_map)
4. 基于生产者消费者模型完成数据的转发
5. 生产者线程负责从 socket 中读取数据
6. 消费者线程把数据转发给在线成员

实现细节:
1. 在线成员列表构成:

   a) key  用户的身份标识  ip + name (近似标识用户的身份)
   b) value  每个成员对应的 ip:port

2. 服务器收到消息需要能够维护在线好友列表的状态:

   a)  如果是新用户,就添加到好友列表中
   b)  如果用户发送了下线命令,将其从好友中删除。

客户端模块

客户端需要能够

  1. 显示在线好友列表
  2. 显示任意一个在线成员发送的消息
  3. 允许用户输入一条消息,并且将消息发送出去

注意:每个功能都要单独创建一个线程用于处理对应的情况

定制一个应用层协议

即客户端和服务器之间按照什么样的格式来传输数据。

struct{
    name;    // 发送该条消息的成员昵称
    school;  //发送该条消息的成员的学校
    msg;     //发送的消息
    command; //对客户端的在线状态进行控制
};

使用jsoncpp实现数据的序列化和反序列化

json简介:

  • json格式:每一个对象用大括号括住,信息在括号里面是以键值对的形式存储的,键值对与键值对之间是以”,”分割的,键和值之间是以”:“分割的。
举例:
[
    {
        name:"曹操",
        skill1:"三段跳",
        skill2:"剑气"
    }
    {
        name:"大乔",
        skill1:"沉默",
        skill2:"传送"
    }
]
  • json优点:
    扩展性好 、可读性好 (方便了程序的调试)
  • json缺点:空间占用太大

代码实现

chat_system

你可能感兴趣的:(Linux)