3-IM聊天系统-Mediator

3-IM聊天系统-Mediator

准备工作

创建筛选器

梳理:

  1. 父类
    • 网络类
    • 实现功能
      1. 打开网络-初始化网络(initNet)
      2. 关闭网络-关闭(close)

INetMediator.h

#pragma once
 class INetMediator {
 public:
     INetMediator(){}
     virtual ~INetMediator(){}
 
     //打开网络
     //和初始化一样,是调用initNet函数
     virtual bool openNet() = 0;
 
     //关闭网络
     //调用unInitNet函数
     virtual void closeNet() = 0;
 
     //发送数据
     //data:发送数据的内容,len:发送的数据长度,to:发送的地址,发给谁,UDP是ip,TCP是socket
     virtual bool sendData(char* data, int len, unsigned long to) = 0;
 
     //转发数据(把Net层接收到的数据传给核心处理类)
     //1.什么数据
     //2.数据从哪儿来 UDP-ip TCP-socket
     virtual void transmitData(char* data, int len, unsigned long from) = 0;
 
 };

框架实现类似INet类。测试代码详见3-01笔记。

实现

主函数

通过中介者初始化网络。

UdpMediator

  1. openNet()函数:

通过对象调用Udp中initNet函数。

  • 创建Udp对象-在INetMediator.h头文件中添加父类指针成员

(在Tcp中也需要使用该对象)

加入头文件

使用相对路径-"./"返回上一级寻找。(默认从当前文件夹开始寻找)

指针初始化

  • 子类的构造函数中创建对象
//打开网络
 bool UdpMediator::openNet() {
     //构造函数创建对象,实现调用
     m_pNet = new Udp(this);
     return true;
 }

创建Udp的对象,调用Udp的函数。

添加Udp的文件

  • 通过指针调用函数
//关闭网络
 void UdpMediator::closeNet() {
     //回收资源
     m_pNet->unInitNet();
 }

相比原本直接调用,使用中介者类,多一层调用更安全。

  • 析构函数回收指针
//关闭网络
 void UdpMediator::closeNet() {
     //回收资源
     if (m_pNet) {
         m_pNet->unInitNet();
         delete m_pNet;
         m_pNet = nullptr;
     }
 }
  • 传输数据

//转发数据(把net层的数据传给核心处理类)//net层的数据由Udp使用transmit函数传给Mediator

- <font style="color:black;">Udp 使用指针调用Mediator的transmit函数把接收的的数据传给Mediator。</font>
- <font style="color:black;">同理,不止UDP,Tcp也需要使用父类指针创建对象</font>

在INet类中添加指针

加入头文件

创建指针

初始化

- <font style="color:black;"> INet() :m_isRunning(true) , m_pMediator(nullptr) {}</font>
  • 问题:

INetMediator.h包含INet.h文件

INet.h文件包含INetMediator.h文件

头文件相互包含。编译在预处理的阶段会导致重复拷贝。

解决:

申明先有INet类,可以直接使用,先不编译INet类。

但是INet类需要在整个编译过程中被使用。

  • 问题:
  • 栈溢出

Udp::Udp(INetMediator* p) :m_sock(INVALID_SOCKET),m_handle(nullptr),m_isRunning(true) {
     m_pMediator = p;
 }
bool UdpMediator::openNet() {
     //构造函数创建对象,实现调用
     m_pNet = new Udp(this);
     return m_pNet->initNet();
 }

原因:

主函数中创建了udpMediator对象,udpMediator对象走析构函数到udpMediator,创建udp对象。udp走析构函数,创建udpMediator对象。走udpMediator析构函数创建udp对象。相互调用死循环,stack溢出。

解决:

将主函数创建的对象传入udpMediator构造中创建的udp对象。

加入有参构造。把对象传入。

在udpMediator析构,创建Udp对象的时候传入参数(this-当前的udpMediater)。

代码

主函数测试

#include<Windows.h>
 #include<iostream>
 #include"Mediator/TcpClientMediator.h"
 #include"Mediator/TcpServerMediator.h"
 #include"Mediator/UdpMediator.h"
 
 using namespace std;
 
 int main() {
     INetMediator* p1 = new UdpMediator;
     //初始化UDP网络
     if (!p1->openNet()) {
         cout << "打开UDP网络失败" << endl;
         delete p1;
         return 1;
     }
     //使用直接广播发送测试消息
     char s[] = "this is a test";
     //p1->sendData(s, sizeof(s), inet_addr("192.168.134.1"));
 
     //打开服务端网络
     INetMediator* p3 = new TcpServerMediator;
     if (!p3->openNet()) {
         cout << "打开tcp服务端网络失败" << endl;
         delete p3;
         return 1;
     }
     //打开客户端网络
     INetMediator* p2 = new TcpClientMediator;
     if (!p2->openNet()) {
         cout << "打开tcp网络失败" << endl;
         delete p2;
         return 1;
     }
     //客户端给服务端发一个消息
     
 
     for (int i = 0; i < 20; i++) {
         p2->sendData(s, sizeof(s), 0);
     }
     while (true) {
         Sleep(50000);
         cout << "imserver is running" << endl;
     }
 
     delete p1;
     delete p2;
     delete p3;
     
     //INetMediator* p11 = new TcpClientMediator;
     //INetMediator* p12 = new TcpServerMediator;
     //INetMediator* p13 = new UdpMediator;
     //delete p11;
     //delete p12;
     //delete p13;
     
     
     return 0;
 }
 
 
 //IM--聊天系统
 //功能
 /*1.注册
 * 2.登陆账号
 * 3.添加好友
 * 4.聊天窗口界面
 * 5.主界面
 * 6.下线 -由服务端维护socket通信状态
 * 7.上线
 */
 
 /*面向对象编程,分析系统框架
 * 
 * 客户端QT
 * 核心处理类(处理收到的数据,组织要发送的数据)-注册信息,聊天信息,在线状态
 * UI界面
 * 网络类(收发数据,初始化网络,关闭网络)
 
 
 *服务端
 * 数据库(好友关系,账号数据,信息) 
 * 核心处理类(处理收到的数据,组织要发送的数据)
 * 中介者类
 //不做数据处理,只做转发
 //代码量不大的时候不使用中介者类也可以,添加是为了方便以后的功能扩展
 * 网络类(收发数据,初始化网络,关闭网络) UDP-TCP协议
 */
 
 //网络类
 //封装继承多态
 //父类:定义接口--纯虚函数
 //子类:实现函数:UDP子类,TCPClient子类,TCPServer子类
 
 //中介者:架构和网络类一样
 //父类:
 //子类:
 
 
 //数据结构STL:
 //vector:数组,数据连续存储,知道下标查找快,不知道下标查找慢,下标是连续的。增加和删除数据不方便
 //一串连续的数字
 //list:数据不连续存储,查找效率低,插入删除方便,
 //经常插入删除
 
 //stack:数据先进后出
 //queue:数据先进先出
 //对数据顺序有要求
 
 //map:key-value,自动排序,查找快
 //一一对
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值