聊天室项目演示

聊天室 专栏收录该内容
2 篇文章 0 订阅

整体思路与框架

1.由于经历了一次重构,让我重新认识到服务器整体框架搭建的困难,在一番折腾过后了解到epoll的一个常规模型

    epfd = epoll_create(MAXEVENTS);                         //生成epoll文件描述符
    ev.data.fd = sockfd;
    ev.events = EPOLLIN  | EPOLLET | EPOLLRDHUP | EPOLLERR; //设置事件属性

    epoll_ctl(epfd,EPOLL_CTL_ADD,sockfd,&ev); //因为开始create也需要一个sockfd存到红黑树中
    connects++;

for(;;){
        npfd = epoll_wait(epfd,events,MAXEVENTS,-1);  //等待响应
        for(int i = 0;i < npfd;i++){
        connects++;
        if(events[i].data.fd == sockfd){
        if(connects > MAXEVENTS){
        my_err("达到最大连接数...",__LINE__);
        continue;
        }
        connfd = accept(events[i].data.fd,(struct sockaddr*)&cliaddr,&clen);
        printf("客户端[IP:%s],[port: %d]已链接...\n",
        inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr,ip,sizeof(ip)),
        ntohs(cliaddr.sin_port));

        if(connfd <= 0){
        my_err("accpet",__LINE__);
        continue;
        }
        ev.data.fd = connfd;
        ev.events = EPOLLIN  | EPOLLET | EPOLLRDHUP | EPOLLERR;
        epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev); //新增套接字
        }
        /* 用户非正常挂断或程序出错 */
        else if((events[i].events & EPOLLIN) && (events[i].events & EPOLLRDHUP) || (events[i].events & EPOLLIN) && (events[i].events & EPOLLERR)){
        epoll_ctl(epfd,EPOLL_CTL_DEL,events[i].data.fd,0); //删去套接字
        close(events[i].data.fd);
        connects--;
        }
        /* 用户正常发来消息请求 */
        else if(events[i].events & EPOLLIN){
        //...工作
        }
 }

2.对于客户端我开两个独立的线程来分别执行发数据和接收数据,这样一般不会阻塞,也对线程的知识进行了复习

int main(){
    int connfd;
    pthread_t tid1, tid2;
    struct sockaddr_in servaddr;
    if((connfd = socket(AF_INET, SOCK_STREAM,0))<0){  //初始化socket套接字
        my_err("socket",__LINE__);
    }
    bzero(&servaddr,sizeof(struct sockaddr_in));
    servaddr.sin_family = AF_INET;      //ipv4协议
    servaddr.sin_port = htons(PORT);    //填入端口号
    inet_pton(AF_INET,"127.0.0.1",(void*)&servaddr.sin_addr.s_addr);  //转为网络地址格式
    printf("正在与服务器建立连接...\n");
    if((connect(connfd,(struct sockaddr*)&servaddr,sizeof(servaddr))) < 0){ //与服务器链接
        my_err("connect",__LINE__);
    }else
    printf("与服务器链接成功!!!\n");
    pthread_create(&ptd1,NULL,send_mission,(void*)&connfd);           //发送消息的线程
    pthread_create(&ptd2,NULL,recv_mission,(void*)&connfd);           //接收消息的线程
    return 0;

数据库的准备

1.个人信息表:
个人信息表

id:帐号; name:昵称; passwd:密码; state:在线状态 fd:对方的文件描述符

2.好友信息表:
好友

your_id:你的帐号; friend_id: 好友的帐号; relation: 好友关系;

3.好友聊天记录表:
好友间的聊天记录

your_id:你的id; recv_id: 收消息的人的id; massages: 发的消息; y_look: 自己是否可见; recv_look: 对方是否可见

4.群信息表:

group_id:群id; group_name:群名; group_mem_id:群成员id; group_mem_nikename:群成员昵称; group_state: 群成员的阶级

演示功能

  • 加好友:
    当输入对方的id后就可以发送好友请求了
    在这里插入图片描述
    对面就会收到
    在这里插入图片描述
  • 查看好友请求:

会有提示是谁发的好友请求
在这里插入图片描述

  • 私聊:

客户端选择私聊后输入对方的id就可以私聊了
在这里插入图片描述
在这里插入图片描述
如果非法输入或者帐号不存在则会有如下提示:
在这里插入图片描述

  • 查看消息记录:

在这里插入图片描述

  • 群聊:

当其他人没打开群聊框时,会提示受到消息
在这里插入图片描述

当打开群聊框就能看到他们发的消息在这里插入图片描述
当查看消息时

在这里插入图片描述

  • 发文件:

在这里插入图片描述

对方接收文件

在这里插入图片描述

  • 退出:

客户端退出 :在这里插入图片描述

服务器显示如下:
在这里插入图片描述

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:深蓝海洋 设计师:CSDN官方博客 返回首页

打赏作者

Xavier丶

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值