嗨聊
功能的描述:
- 客户端启动,提示你输入昵称(等其他信息);
- 按下回车之后,就连接到服务器上;
- 每个客户端能够看到当前聊天室的成员;
- 通过客户端发送一条消息,聊天室中所有的成员都能看到。
- 聊天室中任何成员发送的消息,你也能看到。
项目实现
- 用UDP协议实现数据的传输;
- 用jsoncpp实现数据的序列化和反序列化;
- 使用unordered_map来维护在线好友列表;
- 使用生产者/消费者模型传输数据,同时也可以广播数据给所有在线用户;
- 使用ncurses来绘制用户界面。
服务器模块
接受客户端的消息,并且广播给所有在线用户。
服务器需要能够:
- 能够存储在线好友列表(包含好友的昵称信息,IP地址)
- 能够感知到某个成员的上线和下线(使用哈希表的形式来存储好友列表)
- 接收消息(生产者线程,接收消息,把消息写入到一个队列中)
- 广播消息(消费者线程,从队列中读取消息,遍历好友列表,分别给每个好友发送消息)
详细过程介绍:
1. 从 socket 中读取数据
2. 把数据转发给所有的在线成员
3. 维护在线成员列表(unordered_map)
4. 基于生产者消费者模型完成数据的转发
5. 生产者线程负责从 socket 中读取数据
6. 消费者线程把数据转发给在线成员实现细节:
1. 在线成员列表构成:a) key 用户的身份标识 ip + name (近似标识用户的身份) b) value 每个成员对应的 ip:port
2. 服务器收到消息需要能够维护在线好友列表的状态:
a) 如果是新用户,就添加到好友列表中 b) 如果用户发送了下线命令,将其从好友中删除。
客户端模块
客户端需要能够:
- 显示在线好友列表
- 显示任意一个在线成员发送的消息
- 允许用户输入一条消息,并且将消息发送出去
注意:每个功能都要单独创建一个线程用于处理对应的情况
定制一个应用层协议
即客户端和服务器之间按照什么样的格式来传输数据。
struct{
name; // 发送该条消息的成员昵称
school; //发送该条消息的成员的学校
msg; //发送的消息
command; //对客户端的在线状态进行控制
};
使用jsoncpp实现数据的序列化和反序列化
json简介:
- json格式:每一个对象用大括号括住,信息在括号里面是以键值对的形式存储的,键值对与键值对之间是以”,”分割的,键和值之间是以”:“分割的。
举例:
[
{
name:"曹操",
skill1:"三段跳",
skill2:"剑气"
}
{
name:"大乔",
skill1:"沉默",
skill2:"传送"
}
]
- json优点:
扩展性好 、可读性好 (方便了程序的调试) - json缺点:空间占用太大