聊天室总结
刚开始知道要写这个项目的时候,一点思路都没有,之前从来就没有写过这一类的项目.学了 网络编程后 才开始有一点思路.
基本思路:
- 客户端 和 服务器 一共采用多个结构体 打包传输 ,每个结构体的 前 四个字节都是一个 flag. 服务器 和 客户端每次判断 buf 中的 前 四个字节去 执行相应的操作.
- 服务器 采用epoll 监控 对应的事件.
- 客户端 采用两个线程 一个线程负责处理 , 一个线程负责 接受数据.
- 服务器采用数据库对数据进行保存.
项目实现的需求:
基本要求:
1.帐号管理:
登录
注册(防止重复登录、防止重复注册、不显示密码内容)
密码加密
找回密码
好友管理:
添加好友(必须通过好友同意)
删除好友
查看好友列表(显示好友状态)
2. 聊天通信:
私聊(必须保证不在对方的黑名单里,实时显示)
群聊
查看聊天记录
离线消息
屏蔽某人消息
3.群管理:
创建群
加群
退群
查看已加群,查看群成员
解散群(群主才有的权限)
设置管理员
踢人(群主或管理员拥有的权限)
4.传送文件
发送文件和接受文件(考虑大文件,视频,图片,ppt,pdf)
5.离线传输
离线消息,上线即传送
6.有关客户端的要求:
容错处理:对于输入内容进行判断,防止用户不正规操作导致程序崩溃。
7.有关服务器的要求:
稳定性:这是服务器最基本的要求。
写项目时遇见的问题 :
1 . epoll监控事件: 每当一个客户端 异常退出时,epoll 就会接收到 一个 可读 事件类型,然后陷入死循环.
解决方法: 给epoll 注册 一个 EPOLLRDHUP 事件.当一个服务器 异常退出时,返回的是 一个 EPOLLRDHUP 事件,如果 监测到的 事件 为EPOLLRDHUP,则 删除 这个套接字.
2 . 因为客户端 有两个 线程,所以不可避免 的是 遇到同步处理,.
解决办法: 转化为异步处理,将负责收消息的 线程 需要进行的操作 保存下来,等待用户主动处理.
3 . 发包 和收包 问题.因为 tcp 是基于 流传输,所以会出现 收包 每次收的 大小不一样,导致数据混乱,但是 总数是不会少的.
在本机 很少出现这种情况,当两台电脑联机时,这种情况会很明显.
解决方法: 刚开始 我用 while 循环发送,如果没有发送 到一定的字节数,他就会 一直发送.刚开始 这样还没问题,联机 时也不会出现问题. 然而在 发送文件的时候出现 了问题.文件传输 一会 后就出现 段错误.
然后 在 recv(fd,buf,1024,MSG_WAITALL) 加上 MSG_WAITALL 参数 文件传输也没有问题
这个参数 是当recv 没有接受到 请求的字节数 recv 会阻塞.
4 . 数据库的使用
第一次使用数据库,出现了很多问题,数据库的建表,增,删,改,查,主键,外建的使用 ,虽然挺简单,但是问题 还是不断.
程序的好多bug 都是由于数据库的使用不当 造成的.
5 . 交互.
申请好友时,申请加群 时的交互比较麻烦.
申请好友时,要判断是否在线,不在线 保存到离线消息,上线在发送,对方同意或拒绝时,有个反馈,发送反馈时.要判断 对方是否在线,不在线保存到 离线消息.
申请加群时,要判断是否有群主或管理员 在线,不在线 保存到离线消息中,等其中一个人上线发送消息.同样有一个反馈,要判断是否在线,在线则直接发送,离线则 保存到离线消息中,待其上线发送.
6.离线消息
当给好友发消息时,对方不在线,保存到数据库,待其上线再发送,同理,群聊时,若有好友不在线,则将消息保存下来,待其上线,再发送.
和交互用的多
7.传输文件
传输文件 时,每次发送时,将read 的返回值作为 包中的一个数据,然后将包发送,解析时,每次先判断 这个值的大小,然后根据这个值读取多少个字节.