网盘——添加好友

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

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的时候是要转发给对方的。如果这里没有对方的名字,就不知道怎么转发,不知道转发给谁,所以对方的名字也要写进去

相关推荐
FreeBuf_9 小时前
SesameOp 恶意软件滥用 OpenAI Assistants API 实现与 C2 服务器的隐蔽通信
运维·服务器·网络
凤凰战士芭比Q9 小时前
部署我的世界-java版服务器-frp内网穿透
java·服务器
噜啦噜啦嘞好9 小时前
Linux进程信号
linux·运维·服务器
REDcker10 小时前
Linux 进程资源占用分析指南
linux·运维·chrome
samroom10 小时前
Linux系统管理与常用命令详解
linux·运维·服务器
PKNLP10 小时前
07.docker介绍与常用命令
运维·docker·容器
Mxsoft61910 小时前
电力系统AR远程运维与数字孪生交互技术
运维·ar
一叶之秋141211 小时前
Linux基本指令
linux·运维·服务器
亚林瓜子11 小时前
在amazon linux 2023上面源码手动安装tesseract5.5.1
linux·运维·服务器·ocr·aws·ec2
FreeBuf_11 小时前
研究人员披露 Windows SMB 服务器权限提升漏洞(CVE-2025-58726)
运维·服务器·windows