网盘——添加好友

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

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.rhkb.cn/news/312134.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Adobe AE(After Effects)2021下载地址及安装教程

Adobe After Effects是一款专业级别的视觉效果和动态图形处理软件&#xff0c;由Adobe Systems开发。它被广泛用于电影、电视节目、广告和其他多媒体项目的制作。 After Effects提供了强大的合成和特效功能&#xff0c;可以让用户创建出令人惊艳的动态图形和视觉效果。用户可以…

定制k8s域名解析------CoreDns配置实验

定制k8s域名解析------CoreDns配置实验 1. 需求 k8s集群内通过CoreDns互相解析service名. 同时pana.cn域为外部dns解析,需要通过指定dns服务器进行解析 再有3个服务器,需要使用A记录进行解析 2. K8s外DNS服务器 查看解析文件 tail -3 /var/named/pana.cn.zone 解析内容 ww…

第11章 数据仓库和数据智能知识点梳理

第11章 数据仓库和数据智能知识点梳理&#xff08;附带页码&#xff09; ◼ 数据仓库&#xff08;Data Warehouse&#xff0c;DW&#xff09;&#xff1a;始于 20 世纪 80 年代&#xff0c;发展于 20 世纪 90 年代&#xff0c;后与商务智能&#xff08;Business Inteligence,BI…

Servlet-Filter实现反爬虫

以前用DotNetCore实现过反爬虫功能。在tomcat里面可以利用Servlet的Filter类实现请求的控制来达到反爬虫功能&#xff0c;进而增强JRT的web安全。 实现黑名单过滤器&#xff0c;对在黑名单列表的IP的所有请求都跳转到警告页面&#xff0c;业务各种请求自行定义加入黑名单 /* …

OpenHarmony实战开发-如何使用ArkUIstack 组件实现多层级轮播图。

介绍 本示例介绍使用ArkUIstack 组件实现多层级轮播图。该场景多用于购物、资讯类应用。 效果图预览 使用说明 1.加载完成后显示轮播图可以左右滑动。 实现思路 1.通过stack和offsetx实现多层级堆叠。 Stack() {LazyForEach(this.swiperDataSource, (item: SwiperData, i…

彩虹聚合登录系统源码开心版 一站式社会化账号登录系统

本文来自&#xff1a;彩虹聚合登录系统源码开心版 一站式社会化账号登录系统 - 源码1688 应用介绍 简介&#xff1a; 彩虹聚合登录系统源码开心版 一站式社会化账号登录系统 彩虹聚合登录是彩虹旗下的社交账号聚合登录系统&#xff0c;为网站提供一站式社交账号登录选项&…

【Redis 神秘大陆】006 灾备方案

六、Redis 灾备方案 6.1 存储方案 6.1.1 基础对比 RDB持久化AOF持久化原理周期性fork子进程生成持久化文件每次写入记录命令日志文件类型二进制dump快照文件文本appendonly日志文件触发条件默认超过300s间隔且有1s内超过1kb数据变更永久性每秒fsync一次文件位置配置文件中指…

强强联手|AI赋能智能工业化,探索AI在工业领域的应用

随着人工智能&#xff08;AI&#xff09;技术的不断发展和应用&#xff0c;AI在各个领域展现出了巨大的潜力和价值。在工业领域&#xff0c;AI的应用也越来越受到关注。AI具备了丰富的功能和强大的性能&#xff0c;为工业领域的发展带来了巨大的机遇和挑战。 YesPMP是专业的互联…

【Java NIO】那NIO为什么速度快?

Java IO在工作中其实不常用到&#xff0c;更别提NIO了。但NIO却是高效操作I/O流的必备技能&#xff0c;如顶级开源项目Kafka、Netty、RocketMQ等都采用了NIO技术&#xff0c;NIO也是大多数面试官必考的体系知识。虽然骨头有点难啃&#xff0c;但还是要慢慢消耗知识、学以致用哈…

PDF.js介绍以及使用

这里写目录标题 下载放入项目内加载pdf文件其他问题加载远程文件跨域中文语言 下载 官网地址 下载最新版浏览器版本。 放入项目内 我这是uniapp项目 放入了 static vue 项目可以放入public内 build 是源码库 web 内是写好的一个类似pdf编辑器的完整项目 加载pdf文件 // 组件…

ArcGIS三维景观分层显示

今天将向大家介绍的事在ArcGIS中如何创建多层三维显示。 地表为影像的 地表为地形晕渲的 在土壤分层、油气分层等都有着十分重要的应用。下面我们具体来看看实现过程 一、 准备数据及提取栅格范围 我们这次准备的数据是之前GIS100例-30讲的案例数据。《ArcGIS三维影像图剖面图…

LeetCode 每日一题 Day 123-136

1379. 找出克隆二叉树中的相同节点 给你两棵二叉树&#xff0c;原始树 original 和克隆树 cloned&#xff0c;以及一个位于原始树 original 中的目标节点 target。 其中&#xff0c;克隆树 cloned 是原始树 original 的一个 副本 。 请找出在树 cloned 中&#xff0c;与 tar…

【静态分析】软件分析课程实验-前置准备

课程&#xff1a;南京大学的《软件分析》课程 平台&#xff1a;Tai-e&#xff08;太阿&#xff09;实验作业平台 1. 实验概述 Tai-e 是一个分析 Java 程序的静态程序分析框架&#xff0c;相比于已有的知名静态程序分析框架&#xff08;如 Soot、Wala 等&#xff09;&#xf…

女上司问我:误删除PG百万条数据,可以闪回吗?

作者&#xff1a;IT邦德 中国DBA联盟(ACDU)成员&#xff0c;10余年DBA工作经验 擅长主流数据Oracle、MySQL、PG、openGauss运维 备份恢复&#xff0c;安装迁移&#xff0c;性能优化、故障应急处理等可提供技术业务&#xff1a; 1.DB故障处理/疑难杂症远程支援 2.Mysql/PG/Oracl…

字体反爬积累知识

目录 一、什么是字体反扒 二、Unicode编码 三、利用font包获取映射关系 一、什么是字体反扒 字体反爬是一种常见的反爬虫技术&#xff0c;它通过将网页中的文本内容转换为特殊的字体格式来防止爬虫程序直接获取和解析文本信息。字体反爬的原理是将常规的字符映射到特殊的字…

服务器数据恢复—xfs文件系统节点、目录项丢失的数据恢复案例

服务器数据恢复环境&#xff1a; EMC某型号存储&#xff0c;该存储内有一组由12块磁盘组建的raid5阵列&#xff0c;划分了两个lun。 服务器故障&#xff1a; 管理员为服务器重装操作系统后&#xff0c;发现服务器的磁盘分区发生改变&#xff0c;原来的sdc3分区丢失。由于该分区…

C++ | Leetcode C++题解之第31题下一个排列

题目&#xff1a; 题解&#xff1a; class Solution { public:void nextPermutation(vector<int>& nums) {int i nums.size() - 2;while (i > 0 && nums[i] > nums[i 1]) {i--;}if (i > 0) {int j nums.size() - 1;while (j > 0 && …

Keepalived+LVS+nginx搭建nginx高可用集群

一、简介 nginx是一款非常优秀的反向代理工具&#xff0c;支持请求分发&#xff0c;负载均衡&#xff0c;以及缓存等等非常实用的功能。在请求处理上&#xff0c;nginx采用的是epoll模型&#xff0c;这是一种基于事件监听的模型&#xff0c;因而其具备非常高效的请求处理效率…

笔试题1 -- 吃掉字符串中相邻的相同字符(点击消除_牛客网)

吃掉字符串中相邻的相同字符 文章目录 吃掉字符串中相邻的相同字符题目重现解法一&#xff1a;(基于 erase() 函数实现)解法二&#xff1a;&#xff08;利用 栈 辅助实现&#xff09;总结 题目链接&#xff1a; 点击消除_牛客网 题目重现 牛牛拿到了一个字符串。 他每次“点击…

msyql中SQL 错误 [1118] [42000]: Row size too large (> 8126)

场景&#xff1a; CREATE TABLE test-qd.eqtree (INSERT INTO test.eqtree (idocid VARCHAR(50) NULL,sfcode VARCHAR(50) NULL,sfname VARCHAR(50) NULL,sfengname VARCHAR(50) NULL,…… ) ENGINEInnoDB DEFAULT CHARSETutf8 COLLATEutf8_general_ci;或 alter table eqtre…