网盘——添加好友

news2025/3/16 13:45:56

关于添加好友,过程如下:

A、首先客户端A发送加好友的请求,发送的信息包括双方的用户名

B、当服务器收到请求之后,服务器将数据库中在线用户查找出来,如果客户端B已经是你的好友了,服务器告诉客户端A他已经是你的好友了。如果不是好友且客户端B在线则转发好友请求,不在线直接回复加好友失败。

C、客户端B接受请求信息并回复答复信息给服务器

D、如果同意被添加好友,则在数据库中添加好友信息。发送同意或者拒绝信息发送给客户端A。

QT代码实现

1、首先右击加好友按钮,并且转到槽clicked

2、在客户端还有服务器这里添加协议,保持客户端服务器协议一致

   ENUM_MSG_TYPE_ADD_FRIEND_REQUEST,  //添加好友请求
    ENUM_MSG_TYPE_ADD_FRIEND_RESPOND,  //添加好友回复

3、获得左边的用户名

4、测试一下

void Online::on_addFriendpb_clicked()
{
    //发送当前点击的行,通过currentItem获得当前的文字信息
    QListWidgetItem *pItem = ui->online_lw->currentItem();
    qDebug()<< pItem->text();
}

可以看到,当我们添加22222和jack的时候,会打印出来这两个名字 

5、获取pItem的用户名以及本机的用户名

A、要加的好友的用户名

  QString strPerUsrName = pItem->text();

B、自己的用户名

在这里,直接在tcpclient里面定义一个,添加好友时候,自己的用户名

    QString m_strLoginName;

使得再登录的时候,直接将登录的用户名传给他

m_strLoginName = strName;

C、定义一个共有的接口去获得他

 QString loginName();
QString TcpClient::loginName()
{
    return  m_strLoginName;
}

D、在tcpclient里面获得本机用户名

 QString strLoginName = TcpClient::getinstance().loginName();

6、最后写你要添加谁,你是谁

void Online::on_addFriendpb_clicked()
{
    //发送当前点击的行,通过currentItem获得当前的文字信息
    QListWidgetItem *pItem = ui->online_lw->currentItem();
    //要加的好友的用户名
    QString strPerUsrName = pItem->text();
    //获得自己的名字
    QString strLoginName = TcpClient::getinstance().loginName();

    PDU *pdu = mkPDU(0);
    pdu->uiMsgType = ENUM_MSG_TYPE_ADD_FRIEND_REQUEST;
    //你要添加谁?你是谁
    //获得数据的地址-要加的好友的用户名
    memcpy(pdu->caData, strPerUsrName.toStdString().c_str(), strPerUsrName.size());
    //登录的名字,往后放32个字节——自己的用户名
    memcpy(pdu->caData+32, strLoginName.toStdString().c_str(),strLoginName.size());   
}

7、将信息发送出去

void Online::on_addFriendpb_clicked()
{
    //发送当前点击的行,通过currentItem获得当前的文字信息
    QListWidgetItem *pItem = ui->online_lw->currentItem();
    //要加的好友的用户名
    QString strPerUsrName = pItem->text();
    //获得自己的名字
    QString strLoginName = TcpClient::getinstance().loginName();

    PDU *pdu = mkPDU(0);
    pdu->uiMsgType = ENUM_MSG_TYPE_ADD_FRIEND_REQUEST;
    //你要添加谁?你是谁
    //获得数据的地址-要加的好友的用户名
    memcpy(pdu->caData, strPerUsrName.toStdString().c_str(), strPerUsrName.size());
    //登录的名字,往后放32个字节——自己的用户名
    memcpy(pdu->caData+32, strLoginName.toStdString().c_str(),strLoginName.size());
    //将信息发送出去
    TcpClient::getinstance().getTcpSocket().write((char*)pdu,pdu->uiPDULen);
    free(pdu);
    pdu=NULL;
}

8、操作服务器

8.1、定义加好友的函数

    //------------------------加好友--------------------------
    int handleAddFriend(const char *pername, const char *name);

8.2、在friend表里面添加数据

8.4、在服务器添加加好友的case

case ENUM_MSG_TYPE_ADD_FRIEND_REQUEST:
    {
        char caPerName[32] = {'\0'};
        char caName[32] ={'\0'};
        strncpy(caPerName, pdu->caData, 32);
        strncpy(caName, pdu->caData+32, 32);
        int ret = OperateDB::getInstance().handleAddFriend(caPerName,caName);
        PDU *respdu = NULL;
        if(-1==ret){
            respdu=mkPDU(0);
            respdu->uiMsgType=ENUM_MSG_TYPE_ADD_FRIEND_RESPOND;
            strcpy(respdu->caData, UNKNOW_ERROR);
            //发送
            write((char*)respdu, respdu->uiPDULen);
            //释放空间
            free (respdu);
            respdu =NULL;
        }
        else if(0==ret){
            respdu=mkPDU(0);
            respdu->uiMsgType=ENUM_MSG_TYPE_ADD_FRIEND_RESPOND;
            strcpy(respdu->caData, EXISTED_FRIEND);
            //发送
            write((char*)respdu, respdu->uiPDULen);
            //释放空间
            free (respdu);
            respdu =NULL;
        }
        else if(1==ret){
            //在线
            MyTcpServer::getInstance().reSend(caPerName,pdu);
        }
        else if(2==ret){
            respdu=mkPDU(0);
            respdu->uiMsgType=ENUM_MSG_TYPE_ADD_FRIEND_RESPOND;
            strcpy(respdu->caData, ADD_FRIEND_OFFLINE);
            //发送
            write((char*)respdu, respdu->uiPDULen);
            //释放空间
            free (respdu);
            respdu =NULL;
        }
        else if(3==ret){
            respdu=mkPDU(0);
            respdu->uiMsgType=ENUM_MSG_TYPE_ADD_FRIEND_RESPOND;
            strcpy(respdu->caData, ADD_FRIEND_NO_EXISTED);
            //发送
            write((char*)respdu, respdu->uiPDULen);
            //释放空间
            free (respdu);
            respdu =NULL;
        }
        break;
    }
int OperateDB::handleAddFriend(const char *pername, const char *name)
{
    //首先对形参的有效性做出判断
    if(NULL==pername||NULL==name)
    {
        return -1;
    }
    //查看是否已经是自己的好友
    //我作为id,我的friendid里面有没有这个名字
    QString data = QString("select * from friend where (id=(select id from usrInfo where name = '\%1\') and friendId= (select id from usrInfo where name = '\%2\'))"
                           "or(id=(select id from usrInfo where name = '\%3\') and friendId=(select id from usrInfo where name = '\%4\'))").arg(pername).arg(name).arg(name).arg(pername);
    qDebug()<<data;
    QSqlQuery query;
    query.exec(data);
    if(query.next()){

        return 0;//双方已经是好友
    }
    else
    {
        data = QString("select online from usrInfo where name = \'%1\'").arg(pername);
        QSqlQuery query;
        query.exec(data);
        if(query.next()){
            //查看是否在线
            int ret = query.value(0).toUInt();
            if(1==ret){
                return 1;//不是好友 在线
            }
            else if(0==ret) {
                return 2;
            }
        }
        else {
            return  3;//对方不存在
        }
    }
}

void OperateDB::handleAgreeAddfriend(const char *pername, const char *name)
{
    //首先对形参的有效性做出判断
    if(NULL==pername||NULL==name)
    {
        return;
    }
    QString data = QString("insert into friend(id,friendId) values((select id from usrInfo where name=\'%1\'),(select id from usrInfo where name=\'%2\'))").arg(pername).arg(name);
    qDebug()<<data;
    QSqlQuery query;
    query.exec(data);
}

其中reSend的函数定义如下,这个是一个转发的函数,也就是将对方的名字传过来pername,pdu进行转发

void MyTcpServer::reSend(const char *pername, PDU *pdu)
{
    if(NULL==pername||NULL==pdu){
        return;
    }
    QString strName = pername;
    //遍历链表
    for(int i=0; i<m_tcpSocketList.size();i++)
    {
        qDebug()<<m_tcpSocketList.at(i)->getName();
        if(strName==m_tcpSocketList.at(i)->getName())
        {
            m_tcpSocketList.at(i)->write((char*)pdu,pdu->uiPDULen);
            break;
        }
    }
}

8.5、添加好友的拒绝case

case  ENUM_MSG_TYPE_ADD_FRIEND_REFUSE:
    {
        char caName[32] ={'\0'};
        strncpy(caName, pdu->caData+32, 32);
        MyTcpServer::getInstance().reSend(caName,pdu);
        break;
    }

8.6、对消息类型进行判断

在resend里面,使用的是原来的pdu,但是原来的pdu消息类型还是friend request,所以说接收方那边需要对这两种消息类型进行判断

A、添加好友回复

case ENUM_MSG_TYPE_ADD_FRIEND_RESPOND:
    {
        QMessageBox::information(this,"添加好友",pdu->caData);
        break;
    }

B、添加好友同意或者拒绝代码

 case  ENUM_MSG_TYPE_ADD_FRIEND_AGGREE:
    {
        char caPerName[32] = {'\0'};
        strncpy(caPerName, pdu->caData, 32);
        QMessageBox::information(this,"添加好友",QString("添加%1好友成功").arg(caPerName));
        break;
    }

    case  ENUM_MSG_TYPE_ADD_FRIEND_REFUSE:
    {
        char caPerName[32] = {'\0'};
        strncpy(caPerName, pdu->caData, 32);
        QMessageBox::information(this,"添加好友",QString("添加%1好友失败").arg(caPerName));
        break;
    }

C、添加好友总的case

除了YES之外,其他的情况都属于是不同意

 case ENUM_MSG_TYPE_ADD_FRIEND_REQUEST:
    {
        //同意添加好友还是不同意添加好友
        char caName[32]={'\0'};
        strncpy(caName,pdu->caData+32,32);
        int ret = QMessageBox::information(this,"添加好友",QString("%1 what to add you as friend?").arg(caName),
                                           QMessageBox::Yes,QMessageBox::No);

        PDU *respdu =mkPDU(0);

        //将对方的名字添加进来
        memcpy(respdu->caData,pdu->caData,64);
        
        if(QMessageBox::Yes==ret){
            //同意添加这个好友
            respdu->uiMsgType=ENUM_MSG_TYPE_ADD_FRIEND_AGGREE;
        }
        else{
            //不同意添加这个好友
            respdu->uiMsgType=ENUM_MSG_TYPE_ADD_FRIEND_REFUSE;
        }
        m_tcpSocket.write((char*)respdu,respdu->uiPDULen);
        free(respdu);
        respdu=NULL;
        break;
    }

在这里只是将自己名字发送过去了,对方的名字也是需要发送过去的,服务器收到pdu的时候是要转发给对方的。如果这里没有对方的名字,就不知道怎么转发,不知道转发给谁,所以对方的名字也要写进去

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1598278.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【深度学习】深度学习md笔记总结第5篇:神经网络与tf.keras,学习目标【附代码文档】

深度学习笔记完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;深度学习课程&#xff0c;深度学习介绍要求,目标,学习目标,1.1.1 区别,学习目标,学习目标。TensorFlow介绍&#xff0c;2.4 张量学习目标,2.4.1 张量(Tensor),2.4.2 创建张量的指令,2.4.3 张量…

Sublime Text下载,安装,安装插件管理器,下载汉化插件

SublimeTest官网 © Sublime Text中文网 下载安装 一路点击安装即可 安装插件管理器 管理器官网安装 - 包控制 (packagecontrol.io) 手动安装将3 位置点击网址下载 再打开SublimeTest 点击 选择第一个Browse Packages..... 将会跳转到文件夹中 进入上一个文件夹 在进入…

【模拟】Leetcode 提莫攻击

题目讲解 495. 提莫攻击 算法讲解 前后的两个数字之间的关系要么是相减之差 > 中毒时间 &#xff0c;要么反之 那即可通过示例&#xff0c;进行算法的模拟&#xff0c;得出上图的计算公式 class Solution { public:int findPoisonedDuration(vector<int>& time…

MySql 安装,小白也可以学会成功安装的保姆级教程

MySql 安装 文章目录 MySql 安装1.Mysql下载1.1 访问下载链接1.2 选择合适版本1.3 下载安装包 2.MySql安装3.安装成功检测验证3.1 mysql自带控制台验证3.2 win系统控制台进入验证 4. mysql 配置path5. navicat 连接 mysql 1.Mysql下载 1.1 访问下载链接 MySQL Downloads 这里…

定时器、PWM定时器、UART串口通信

我要成为嵌入式高手之4月15日ARM第八天&#xff01;&#xff01; ———————————————————————————— 定时器 S3C2440A 有 5 个 16 位定时器。其中定时器 0、1、2 和 3 具有脉宽调制&#xff08;PWM&#xff09;功能。定时器 4 是一个无 输出引脚的内部…

电商技术揭秘二十五:电商平台的智能库存管理与优化

相关系列文章 电商技术揭秘一&#xff1a;电商架构设计与核心技术 电商技术揭秘二&#xff1a;电商平台推荐系统的实现与优化 电商技术揭秘三&#xff1a;电商平台的支付与结算系统 电商技术揭秘四&#xff1a;电商平台的物流管理系统 电商技术揭秘五&#xff1a;电商平台…

【DM8】ET SQL性能分析工具

通过统计SQL每个操作符的时间花费&#xff0c;从而定位到有性能问题的操作&#xff0c;指导用户去优化。 开启ET工具 INI参数&#xff1a; ENABLE_MONITOR1 MONITOR_SQL_EXEC1 查看参数 select * FROM v$dm_ini WHERE PARA_NAMEMONITOR_SQL_EXEC;SELECT * FROM v$dm_ini WH…

Fiddler工具的操作和功能时-----定位到步骤图(助力抓包)

前言&#xff1a; 继续上一篇&#xff0c;已经对fiddler的安装、配置和代理的问题进行了讲解&#xff1a; Fiddle配置代理&#xff0c;保手机模拟器访问外部网络-CSDN博客 本章&#xff0c;讲对一些fiddler的操作进行一系列讲解&#xff01;Fiddler作为一款网络调试工具&…

小型时间继电器ST3PA-C DC24V 带插座PF085A 导轨安装 JOSEF约瑟

ST3P系列时间继电器 系列型号 ST3PF-2Z(JSZ3F-2Z) 5s AC110V ST3PF(JSZ3F) 10s AC48V ST3PC-1(AH3-3) 5s DC24V ST3PC-1(AH3-3) 2h AC220V ST3PC-F(JSZ3C-F) AC380V ST3PA-E(JSZ3A-E) DC24V ST3PA-F(JSZ3A-F) DC24V ST3PF(JSZ3F) 10s AC36V ST3PC-1(AH3-3) 10s AC24V ST3PC-1…

基于SSM+Jsp+Mysql的贝儿米幼儿教育管理系统

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…

【包邮送书】MicroPython项目开发实战

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和技术。关…

读天才与算法:人脑与AI的数学思维笔记01_洛夫莱斯测试

1. 创造力 1.1. 创造力是一种原动力&#xff0c;它驱使人们产生新的、令人惊讶的、有价值的想法&#xff0c;并积极地将这些想法付诸实践 1.2. 创造出在表面上看似新的东西相对容易 1.3. 在遇到偶然间的创造性行为时&#xff0c;都会表现得异…

建立时间/保持时间为负是什么情况

目录 建立时间为负保持时间为负参考 在说明建立时间和保持时间为何为负的情况下&#xff0c;首先可以看看建立时间Tsu和保持时间Th的由来&#xff0c;可参考如下两篇文章&#xff1a; 建立时间和保持时间理解_为什么要满足建立时间和保持时间-CSDN博客 ic基础|时序篇&#xff…

分布式文件系统HDFS-1

文章目录 主要内容一.分布式文件系统HDFS1.定义2.优缺点3.原理4.设计思想及原则5.框架结构 6.HDFS的主要组件包括7.块、名称节点和数据节点8.HDFS冗余数据保存9.数据存取策略 总结 主要内容 HDFS 一.分布式文件系统HDFS 1.定义 HDFS&#xff08;Hadoop Distributed File Syst…

使用python在本地指定的目录临时模拟服务器(3),2024年最新网易 面经

先自我介绍一下&#xff0c;小编浙江大学毕业&#xff0c;去过华为、字节跳动等大厂&#xff0c;目前阿里P7 深知大多数程序员&#xff0c;想要提升技能&#xff0c;往往是自己摸索成长&#xff0c;但自己不成体系的自学效果低效又漫长&#xff0c;而且极易碰到天花板技术停滞…

二叉树的前、中、后序遍历【c++】

前序遍历&#xff1a;根左右 中序遍历&#xff1a;左根右 后序遍历&#xff1a;左右根 #include <iostream> #include <vector> using namespace std;//双链表节点结构 typedef struct treeNode {int value;struct treeNode* left;struct treeNode* right;treeNod…

Vue3(四):Pinia

一、Pinia介绍 Pinia是一个专门为Vue.js设计的状态管理库&#xff0c;它提供了一种简单和直观的方式来管理应用程序的状态。在使用Pinia时&#xff0c;可以轻松地创建定义状态的存储&#xff0c;然后将其与Vue组件绑定&#xff0c;使它们能够使用该状态。和上一个博客提到的Vu…

bestvike --bvframe学习

ref title fetch后台api 分页属性&#xff0c;pagination 要差几条&#xff1f;pagelimit 在api中写一个饭方法&#xff0c;vue中用用他 vue.cinfig.js中配置别名 nacos微服务 实体类要继承basedata&#xff08;封装了公共数据&#xff09; 控制器autowired&#xff0c;getm…

哈希函数的简单介绍

哈希函数&#xff1a; hash: 把....弄糟(乱) 又称为散列函数&#xff0c;杂凑函数 什么是哈希表&#xff1f; 哈希表简单来说可以看作是是对数组的升级&#xff0c;&#xff08;也有不少人认为哈希表的本质就是数组&#xff09;&#xff0c;那么哈希表和数组的具体联系和区…

每日OJ题_BFS解决最短路③_力扣127. 单词接龙

目录 ③力扣127. 单词接龙 解析代码 ③力扣127. 单词接龙 127. 单词接龙 难度 困难 字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列 beginWord -> s1 -> s2 -> ... -> sk&#xff1a; 每一对相邻的单词只差一个字母。…