P2P聊天室的实现
总体设计
数据结构
- 用户
- 报文定义
1 |
|
架构说明
server和client在同一个程序中- 程序跑起来之后,没有明确的客户和服务端区别
用户存储
- 选用合适的数据结构来存储用户信息
- 可链表,可数组,也可以是其他的复杂结构
1 | //此结构不参与任何节点之间的数据交互,可自行维护 |
心跳线程
- 该线程用来遍历每一个用户,对其发送心跳包
- 并判断是否需要将用户移出
接收线程
- 循环接受用户信息,将用户的请求压到任务队列中
发送线程
读取标准输入,并将数据发送给工作线程,负责将数据转发出去
第一阶段
节点发现
每个节点启动后,建立好主反应堆后,启动一个新的线程,给所有iplist中的所有
ip发送SYN报文注意,在这里先把自己的ip加到iplist文件中,换一个端口,开一个相应的进程测试
发送完SYN报文后,将该节点信息添加到用户存储结构中
等待对方的
SYNACK报文,如果收到SYNACK报文,则认为节点在线「实际是在主反应堆中做」使用UDP的
connect与对方建立一条确定的伪连接并标记为在线
节点被发现
- 在主反应堆中,处于监听状态的套接字,收到数据连接之后,收到包,需要判断是否是合法的包
- 如果合法,并且该包是一个
SYN包,则给对方发送一个SYNACK报文 - 通过
connect连接到对方,建立一条确认的伪连接 - 并标记为对方在线
- 如果收到的是
SYNACK,处理如上节节点发现
循环打印发现的结点
- 设置一个专门的线程,或者可以直接使用上面节点发现里第1条所使用的线程来接续完成下面的工作
- 循环打印自己发现的结点
第二阶段
心跳的发送
心跳的目的是用来判断对端是否在线,也就是帮助你确定,好友列表里的这些个人,是否真的在线。
- 启动一个单独的线程
heart_beat - 这个线程,每隔一段时间给自己的所有好友发一个心跳报文
CHAT_HEART - 当心跳线程发现某个好友,已经发了10个心跳包了,但是一直没有任何数据响应,那么任务他失联了,标记为下线
心跳的确认
在这里,需要明确一点,对心跳的ACK算是对心跳的确认,但,同时,给对方的任何数据,其实都是在告知对方:“我还活着”。
- 如果收到一个心跳包,那么给对方回一个心跳确认包
CHAT_ACK
