协议解析必用的责任链模式

简介: 协议解析必用的责任链模式

书籍

《设计模式-可复⽤⾯向对象软件的基础》

《重构与模式》

设计模式

设计模式是指在软件开发中,经过验证的,⽤于解决在特定环境下,重复出现的,特定问题的解决⽅案;

内存模型:

扩展:c语⾔当中的多态

       redis

       nginx

模式设计原则:

依赖倒置原则

⾼层模块不应该依赖低层模块,⼆者都应该依赖抽象

抽象不应该依赖具体实现,具体实现应该依赖于抽象;

⾃动驾驶系统公司是⾼层,汽⻋⽣产⼚商为低层,它们不应该互相依赖,⼀⽅变动另⼀⽅也会

跟着变动;⽽应该抽象⼀个⾃动驾驶⾏业标准,⾼层和低层都依赖它;这样以来就解耦了两⽅

的变动;⾃动驾驶系统、汽⻋⽣产⼚商都是具体实现,它们应该都依赖⾃动驾驶⾏业标准(抽

象);

开放封闭原则

⼀个类应该对扩展开放,对修改关闭;

⾯向接⼝编程

不将变量类型声明为某个特定的具体类,⽽是声明为某个接⼝。客户程序⽆需获知对象的具体类型,只需要知道对象所具有的接⼝。

减少系统中各部分的依赖关系,从⽽实现⾼内聚、松耦合的类型设计⽅案。

封装变化点

将稳定点和变化点分离,扩展修改变化点;让稳定点与变化点的实现层次分离

单⼀职责原则

⼀个类应该仅有⼀个引起它变化的原因;

⾥⽒替换原则

⼦类型必须能够替换掉它的⽗类型;主要出现在⼦类覆盖⽗类实现,原来使⽤⽗类型的程序可

能出现错误;覆盖了⽗类⽅法却没实现⽗类⽅法的职责

接⼝隔离原则

不应该强迫客户依赖于他们不⽤的⽅法;

⼀般⽤于处理⼀个类拥有⽐较多的接⼝,⽽这些接⼝涉及到很多职责;

对象组合优于类继承

继承耦合度⾼,组合耦合度低;

什么情况下使⽤设计模式?

系统的关键依赖点;

能明确找到变化点;

能明确找到复⽤⽅向;

对需求变化⽅向熟悉;

如何找到设计模式?

从重构中获得;

重构

静态转变为动态;

早绑定转变为晚绑定;

继承转变为组合;

编译时依赖转变为运⾏时依赖;

紧耦合转变为松耦合;

为什么要学习设计模式?

从已有的且证明有效的设计模式中获取灵感,少⾛弯路;

通⽤语⾔,知道在已有的设计模式扩展代码;

体会模式设计,设计⾃⼰的⾏之有效的设计模式;

学习设计模式的步骤

深刻体会上⾯的原则;

理解设计模式,能知道设计模式的变化点和稳定点

能在已使⽤的设计模式中,知道如何写扩展;

能在复杂需求中,抽象出已有设计模式;能在重构中,开发⾃⼰的设计模式;

能在重构中,开发⾃⼰的设计模式;

模板⽅法

定义

定义⼀个操作中的算法的⻣架 ,⽽将⼀些步骤延迟到⼦类中。Template Method使得⼦类可以不

改变⼀个算法的结构即可重定义该算法的某些特定步骤。——《 设计模式》GoF

背景

某个品牌动物园,有⼀套固定的表演流程,但是其中有若⼲个表演⼦流程受欢迎程度⽐较低,希望

将这⼏个表演流程创新,以尝试迭代更新表演流程;

代码

#include <iostream>
using namespace std;
class ZooShow {
public:
    // 固定流程封装到这里
    void Show() {
        Show0();
        Show1();
        Show2();
        Show3();
    }
protected:
    // 子流程 使用protected保护起来 不被客户调用 但允许子类扩展
    virtual void Show0(){
        cout << "show0" << endl;
    }
    virtual void Show2(){
        cout << "show2" << endl;
    }
    virtual void Show1() {
    }
    virtual void Show3() {
    }
};
class ZooShowEx : public ZooShow {
protected:
    virtual void Show1(){
        cout << "show1" << endl;
    }
    virtual void Show3(){
        cout << "show3" << endl;
    }
    virtual void Show4() {
        //
    }
};
class ZooShowEx1 : public ZooShow {
protected:
    virtual void Show0(){
        cout << "show1" << endl;
    }
    virtual void Show2(){
        cout << "show3" << endl;
    }
};
class ZooShowEx2 : public ZooShow {
protected:
    virtual void Show1(){
        cout << "show1" << endl;
    }
    virtual void Show2(){
        cout << "show3" << endl;
    }
};
/*
依赖倒置原则
单一职责原则
接口隔离原则
反向控制:应用程序 框架 应用程序(变化的)应该依赖框架(稳定的),应该是框架去调应用程序,而不是应用程序去调框架
*/
int main () {
    ZooShow *zs = new ZooShowEx;
    ZooShow *zs1 = new ZooShowEx1;
    ZooShow *zs2 = new ZooShowEx2;
    zs->Show();
    return 0;
}

要点

⾮常常⽤的设计模式,⼦类可以复写⽗类的⼦流程,使⽗类的⼤流程更丰富;

反向控制流程的典型应⽤;

⽗类protected 保护⼦类需要复写的⼦流程;这样⼦类的⼦流程只能⽗类来调⽤;

充分体现了依赖倒置原则;

本质

通过固定算法⻣架来约束⼦类的⾏为;

结构图

观察者模式

定义

定义对象间的⼀种⼀对多(变化)的依赖关系,以便当⼀个对象(Subject)的状态发⽣改变时,所有

依赖于它的对象都得到通知并⾃动更新。——《 设计模式》GoF

背景

⽓象站发布⽓象资料给数据中⼼,数据中⼼经过处理,将⽓象信息更新到两个不同的显示终端(A

B);

代码

#include <vector>
class IDisplay {
public:
    virtual void Show(float temperature) = 0;
    virtual ~IDisplay() {}
};
class DisplayA : public IDisplay {
public:
    virtual void Show(float temperature);
};
class DisplayB : public IDisplay{
public:
    virtual void Show(float temperature);
};
class WeatherData {
};
class DataCenter {
public:
    void Attach(IDisplay * ob);
    void Detach(IDisplay * ob);
    void Notify() {
        float temper = CalcTemperature();
        for (auto iter = obs.begin(); iter != obs.end(); iter++) {
            (*iter)->Show(temper);
        }
    }
private:
    virtual WeatherData * GetWeatherData();
    virtual float CalcTemperature() {
        WeatherData * data = GetWeatherData();
        // ...
        float temper/* = */;
        return temper;
    }
    std::vector<IDisplay*> obs;
};
int main() {
    DataCenter *center = new DataCenter;
    IDisplay *da = new DisplayA();
    IDisplay *db = new DisplayB();
    center->Attach(da);
    center->Attach(db);
    center->Notify();
    //-----
    center->Detach(db);
    center->Notify();
    return 0;
}

要点

观察者模式使得我们可以独⽴地改变⽬标与观察者,从⽽使⼆者之间的关系松耦合;

观察者⾃⼰决定是否订阅通知,⽬标对象并不关注谁订阅了;

观察者不要依赖通知顺序,⽬标对象也不知道通知顺序;

常使⽤在基于事件的ui框架中,也是MVC的组成部分;

常使⽤在分布式系统中,actor框架中;

本质

触发联动;

结构图

策略模式

定义

定义⼀系列算法,把它们⼀个个封装起来,并且使它们可互相替换。该模式使得算法可独⽴于使⽤

它的客户程序⽽变化。——《设计模式》GoF

背景

某商场节假⽇有固定促销活动,为了加⼤促销⼒度,现提升国庆节促销活动规格;

代码

要点

策略模式提供了⼀系列可重⽤的算法,从⽽可以使得类型在运⾏时⽅便地根据需要在各个算法

之间进⾏切换;

策略模式消除了条件判断语句;就是在解耦合;

充分体现了开闭原则;单⼀职责;

本质

分离算法,选择实现;

结构图

责任链模式

定义

使多个对象都有机会处理请求,从⽽避免请求的发送者和接收者之间的耦合关系。将这些对象连成

⼀条链,并沿着这条链传递请求,直到有⼀个对象处理它为⽌。——《设计模式》GoF

背景

请假流程,1天内需要主程序批准,3天内需要项⽬经理批准,3天以上需要⽼板批准;

代码

class Context {
public:
    std::string name;
    int day;
};
class IHandler {
public:
    virtual ~IHandler() {}
    void SetNextHandler(IHandler *next) {
        next = next;
    }
    bool Handle(ctx) {
        if (CanHandle(ctx)) {
            return HandleRequest();
        } else if (GetNextHandler()) {
            return GetNextHandler()->HandleRequest(ctx);
        } else {
            // err
        }
    }
protected:
    virtual bool HandleRequest(const Context &ctx) = 0;
    virtual bool CanHandle(const Context &ctx) =0;
    IHandler * GetNextHandler() {
        return next;
    }
private:
    IHandler *next;
};
class HandleByMainProgram : public IHandler {
protected:
    virtual bool HandleRequest(const Context &ctx){
        //
    }
    virtual bool CanHandle() {
        //
    }
};
class HandleByProjMgr : public IHandler {
protected:
    virtual bool HandleRequest(const Context &ctx){
        //
    }
    virtual bool CanHandle() {
        //
    }
};
class HandleByBoss : public IHandler {
public:
    virtual bool HandleRequest(const Context &ctx){
        //
    }
protected:
    virtual bool CanHandle() {
        //
    }
};
int main () {
    IHandler * h1 = new MainProgram();
    IHandler * h2 = new HandleByProjMgr();
    IHandler * h3 = new HandleByBoss();
    h1->SetNextHandler(h2);
    Context ctx;
    h1->handle(ctx);
    return 0;
}

nginx 阶段处理

// 严格意义说是功能链

// ngx_http_init_phase_handlers 初始化责任链cmcf->phase_engine.handlers

// ngx_http_core_run_phases 调⽤责任链

要点

解耦请求⽅和处理⽅,请求⽅不知道请求是如何被处理,处理⽅的组成是由相互独⽴的⼦处理

构成,⼦处理流程通过链表的⽅式连接,⼦处理请求可以按任意顺序组合;

责任链请求强调请求最终由⼀个⼦处理流程处理;通过了各个⼦处理条件判断;

责任链扩展就是功能链,功能链强调的是,⼀个请求依次经由功能链中的⼦处理流程处理;

充分体现了单⼀职责原则;将职责以及职责顺序运⾏进⾏抽象,那么职责变化可以任意扩展,

同时职责顺序也可以任意扩展;

本质

分离职责,动态组合;

结构图

装饰器模式

定义

动态地给⼀个对象增加⼀些额外的职责。就增加功能⽽⾔,装饰器模式⽐⽣成⼦类更为灵活。——

《设计模式》GoF

背景

普通员⼯有销售奖⾦,累计奖⾦,部⻔经理除此之外还有团队奖⾦;后⾯可能会添加环⽐增⻓奖

⾦,同时可能针对不同的职位产⽣不同的奖⾦组合;

代码

// 普通员工有销售奖金,累计奖金,部门经理除此之外还有团队奖金;后面可能会添加环比增长奖金,同时可能产生不同的奖金组合;
// 销售奖金 = 当月销售额 * 4%
// 累计奖金 = 总的回款额 * 0.2%
// 部门奖金 = 团队销售额 * 1%
// 环比奖金 = (当月销售额-上月销售额) * 1%
// 销售后面的参数可能会调整
class Context {
public:
    bool isMgr;
    // User user;
    // double groupsale;
};
// 试着从职责出发,将职责抽象出来
class CalcBonus {    
public:
    CalcBonus(CalcBonus * c = nullptr) {}
    virtual double Calc(Context &ctx) {
        return 0.0; // 基本工资
    }
    virtual ~CalcBonus() {}
protected:
    CalcBonus* cc;
};
class CalcMonthBonus : public CalcBonus {
public:
    CalcMonthBonus(CalcBonus * c) : cc(c) {}
    virtual double Calc(Context &ctx) {
        double mbonus /*= 计算流程忽略*/; 
        return mbonus + cc->Calc(ctx);
    }
};
class CalcSumBonus : public CalcBonus {
public:
    CalcSumBonus(CalcBonus * c) : cc(c) {}
    virtual double Calc(Context &ctx) {
        double sbonus /*= 计算流程忽略*/; 
        return sbonus + cc->Calc(ctx);
    }
};
class CalcGroupBonus : public CalcBonus {
public:
    CalcGroupBonus(CalcBonus * c) : cc(c) {}
    virtual double Calc(Context &ctx) {
        double gbnonus /*= 计算流程忽略*/; 
        return gbnonus + cc->Calc(ctx);
    }
};
class CalcCycleBonus : public CalcBonus {
public:
    CalcGroupBonus(CalcBonus * c) : cc(c) {}
    virtual double Calc(Context &ctx) {
        double gbnonus /*= 计算流程忽略*/; 
        return gbnonus + cc->Calc(ctx);
    }
};
int main() {
    // 1. 普通员工
    Context ctx1;
    CalcBonus *base = new CalcBonus();
    CalcBonus *cb1 = new CalcMonthBonus(base);
    CalcBonus *cb2 = new CalcSumBonus(cb1);
    cb2->Calc(ctx1);
    // 2. 部门经理
    Context ctx2;
    CalcBonus *cb3 = new CalcGroupBonus(cb2);
    cb3->Calc(ctx2);
}

要点

通过采⽤组合⽽⾮继承的⼿法, 装饰器模式实现了在运⾏时动态扩展对象功能的能⼒,⽽且

可以根据需要扩展多个功能。 避免了使⽤继承带来的灵活性差多⼦类衍⽣问题。不是解决“多⼦类衍⽣的多继承问题,⽽是解决⽗类在多个⽅向上的扩展功能问题;装饰器模式把⼀系列复杂的功能分散到每个装饰器当中,⼀般⼀个装饰器只实现⼀个功能,实现复⽤装饰器的功能;

本质

动态组合

结构图

单例模式

定义

保证⼀个类仅有⼀个实例,并提供⼀个该实例的全局访问点。——《设计模式》GoF

代码

版本1

 线程不安全,且内存泄漏

// 内存栈区
// 内存堆区
// 常数区
// 静态区 系统释放
// ⼆进制代码区
class Singleton{
public:
    static Singleton* GetInstance(){
        if(_instance == nullptr){
            _instance = new Singleton();
        }
        return _instance;
    }
private:
    Singleton(){} // 构造
    Singleton(const Singleton& that){} // 拷贝构造
    Singleton& operator=(const Singleton& that){} // 拷贝赋值
    static Singleton* _instance;
};
Singleton* Singleton::_instance == nullptr;// 静态成员需要初始化

版本2

class Singleton {
public:
 static Singleton * GetInstance() {
     if (_instance == nullptr) {
         _instance = new Singleton();
         atexit(Destructor);
     }
     return _instance;
 }
     ~Singleton() {}
 /*   class GC{
        ~GC(){
            delete _instance;
        }
      } */
private:
 static void Destructor() {
     if (nullptr != _instance) {
         delete _instance;
         _instance = nullptr;
     }
 }
 Singleton();//构造
 Singleton(const Singleton &cpy); //拷⻉构造
 Singleton& operator=(const Singleton&) {}
 static Singleton * _instance; 
 /* static GC gc; */
}
 Singleton* Singleton::_instance = nullptr;//静态成员需要初始化
 /* Singleton::GC gc; */
// 还可以使⽤ 内部类,智能指针来解决; 此时还有线程安全问题

版本3

#include <mutex>
class Singleton { // 懒汉模式 lazy load
public:
     static Singleton * GetInstance() {
     //std::lock_guard<std::mutex> lock(_mutex); // 3.1 切换线程   锁的粒度大
     if (_instance == nullptr) {
             std::lock_guard<std::mutex> lock(_mutex); // 3.2  
             if (_instance == nullptr) {
                 /*pthread_once_t once_control = PTHREAD_ONCE_INIT;
                 pthread_once(once_control , init);*/
                 _instance = new Singleton();  // --->   1分配内存,2调用构造函数,3赋值
                 atexit(Destructor);           // ---> 多线程环境下 cpu会进行重排
             }                                 // --->  可能调用顺序是132
     }                                         // 晚到来的线程拿到_instance不等于null
     return _instance;                         // 直接返回,此时构造函数还没执行完
 }
private:
 static void init(void){
    _instance = new Singleton();
 }
 static void Destructor() {
     if (nullptr != _instance) {
         delete _instance;
         _instance = nullptr;
     }
 }
 Singleton(){} //构造
 Singleton(const Singleton &cpy){} //拷⻉构造
 Singleton& operator=(const Singleton&) {}
 static Singleton * _instance;
 static std::mutex _mutex; }
 Singleton* Singleton::_instance = nullptr;//静态成员需要初始化
 std::mutex Singleton::_mutex; //互斥锁初始化

版本4

#include <atomic>           //懒汉式
#include <mutex>
class Singleton{
public:
    static Singleton* GetInstance(){
        Singleton* tmp = _instance.load(std::memory_order_relaxed);//把_instance取出
        std::atomic_thread_fence(std::memory_order_acquire);// 获取内存屏障
        if(tmp == nullptr){
            std::lock_guard<std::mutex> lock(_mutex);
            tmp = _instance.load(std::memory_order_relaxed);
            if(tmp == nullptr){
                tmp = new Singleton;
                std::atomic_thread_fence(std::memory_order_release);//释放内存屏障
                _instance.store(tmp , std::memory_order_relaxed);//把tmp存入_instance
                atexit(Destructor);
            }
        }
        return tmp;
    }
private:
    static void Destructor(){
        Singleton* tmp = _instance.load(std::memory_order_relaxed);
        if(nullptr != tmp){
            delete tmp;
        }
    }
    Singleton(){}
    Singleton(const Singleton& that){}
    Singleton& operator=(const Singleton& that){}
    static std::atomic<Singleton*> _instance;
    static std::mutex _mutex;
};
std::atomic<Singleton*> Singleton::_instance;
std::mutex Singleton::_mutex;

版本5

// c++11 magic static 特性:如果当静态变量在初始化的时候,并发同时进⼊声明语句,并发
线程将会阻塞等待初始化结束。
class Singleton
{
public:
 ~Singleton(){}
 static Singleton& GetInstance() {
 static Singleton instance;
 return instance;
 } 
private:              //构造函数私有,无法继承,子类无法实例化父类
 Singleton(){}       
 Singleton(const Singleton&) {}
 Singleton& operator=(const Singleton&) {}
};
// 继承 Singleton
// g++ Singleton.cpp -o singleton -std=c++11
/*该版本具备 版本5 所有优点:
1. 利⽤静态局部变量特性,延迟加载;
2. 利⽤静态局部变量特性,系统⾃动回收内存,⾃动调⽤析构函数;
3. 静态局部变量初始化时,没有 new 操作带来的cpu指令reorder操作;
4. c++11 静态局部变量初始化时,具备线程安全;
*/

版本6

template<typename T>
class Singleton {
public:
 static T& GetInstance() {
 static T instance; // 这⾥要初始化DesignPattern,需要调⽤
DesignPattern 构造函数,同时会调⽤⽗类的构造函数。
 return instance;
 }
protected:
 virtual ~Singleton() {}
 Singleton() {} // protected修饰构造函数,才能让别⼈继承
 Singleton(const Singleton&) {}
 Singleton& operator =(const Singleton&) {}
};
class DesignPattern : public Singleton<DesignPattern> {
 friend class Singleton<DesignPattern>; // friend 能让 Singleton<T> 访
问到 DesignPattern构造函数
private:
 DesignPattern(){}
 DesignPattern(const DesignPattern&) {}
 DesignPattern& operator=(const DesignPattern&) {}
}

要点

结构图

策略模式

定义

定义⼀系列算法,把它们⼀个个封装起来,并且使它们可互相替换。该模式使得算法可独⽴于使⽤

它的客户程序⽽变化。——《设计模式》GoF

背景

某商场节假⽇有固定促销活动,为了加⼤促销⼒度,现提升国庆节促销活动规格;

代码

要点

策略模式提供了⼀系列可重⽤的算法,从⽽可以使得类型在运⾏时⽅便地根据需要在各个算法

之间进⾏切换;

策略模式消除了条件判断语句;就是在解耦合;

充分体现了开闭原则;单⼀职责;

本质

分离算法,选择实现;

结构图

责任链模式

定义

使多个对象都有机会处理请求,从⽽避免请求的发送者和接收者之间的耦合关系。将这些对象连成

⼀条链,并沿着这条链传递请求,直到有⼀个对象处理它为⽌。——《设计模式》GoF

背景

请假流程,1天内需要主程序批准,3天内需要项⽬经理批准,3天以上需要⽼板批准;

代码

nginx 阶段处理

// 严格意义说是功能链

// ngx_http_init_phase_handlers 初始化责任链cmcf->phase_engine.handlers

// ngx_http_core_run_phases 调⽤责任链

要点

解耦请求⽅和处理⽅,请求⽅不知道请求是如何被处理,处理⽅的组成是由相互独⽴的⼦处理

构成,⼦处理流程通过链表的⽅式连接,⼦处理请求可以按任意顺序组合;

责任链请求强调请求最终由⼀个⼦处理流程处理;通过了各个⼦处理条件判断;

责任链扩展就是功能链,功能链强调的是,⼀个请求依次经由功能链中的⼦处理流程处理;

充分体现了单⼀职责原则;将职责以及职责顺序运⾏进⾏抽象,那么职责变化可以任意扩展,

同时职责顺序也可以任意扩展;

本质

分离职责,动态组合;

结构图

⼯⼚⽅法模式

定义

定义⼀个⽤于创建对象的接⼝,让⼦类决定实例化哪⼀个类。Factory Method使得⼀个类的实例化

延迟到⼦类。——《设计模式》GoF

背景

实现⼀个导出数据的接⼝,让客户选择数据的导出⽅式;

代码

要点

解决创建过程⽐较复杂,希望对外隐藏这些细节;

⽐如连接池,线程池;

隐藏对象真实类型;

对象创建会有很多参数来决定如何创建;

创建对象有复杂的依赖关系;

本质

延迟到⼦类来选择实现;

结构图

抽象⼯⼚模式

定义

提供⼀个接⼝,让该接⼝负责创建⼀系列相关或者相互依赖的对象,⽆需指定它们具体的类。

——《设计模式》GoF

背景

实现⼀个拥有导出导⼊数据的接⼝,让客户选择数据的导出导⼊⽅式;

代码

要点

本质

结构图

适配器模式

定义

将⼀个类的接⼝转换成客户希望的另⼀个接⼝。Adapter模式使得原本由于接⼝不兼容⽽不能⼀起

⼯作的那些类可以⼀起⼯作。——《设计模式》GoF

背景

⽇志系统,原来是通过写磁盘的⽅式进⾏存储,后来因为查询不便,需要额外添加往数据库写⽇志

的功能(写⽂件和数据库并存);

代码

要点

原来的接⼝是稳定的,新的外来的需求是变化的,那么可以通过继承原来的接⼝,让原来的接

⼝继续保持稳定,在⼦类通过组合的⽅式来扩展功能;

本质

转换匹配,复⽤功能;

结构图

代理模式

定义

为其他对象提供⼀种代理以控制对这对象的访问。——《设计模式》GoF

背景

在有些系统中,为了某些对象的纯粹性,只进⾏了功能相关封装(稳定点),后期添加了其他功能

需要对该对象进⾏额外操作(变化点),为了隔离变化点(也就是不直接在稳定点进⾏修改,这样

会让稳定点也变得不稳定),可以抽象⼀层代理层;

代码

要点

远程代理(隐藏⼀个对象存在不同的地址空间的事实),虚代理(延迟加载lazyload),保护

代理(在代理前后做额外操作,权限管理,引⽤计数等);

在分布式系统中,actor模型(skynet)等常⽤的设计模式;

本质

控制对象访问;

结构图

目录
相关文章
|
1月前
|
存储 传感器 安全
【串口通信】使用C++和Qt设计和实现串口协议解析器(二)
【串口通信】使用C++和Qt设计和实现串口协议解析器
52 0
|
1月前
|
存储 开发框架 算法
【串口通信】使用C++和Qt设计和实现串口协议解析器(一)
【串口通信】使用C++和Qt设计和实现串口协议解析器
103 0
|
3月前
|
域名解析 网络协议
IP协议, TCP协议 和DNS 服务分别是干什么的?
IP协议, TCP协议 和DNS 服务分别是干什么的?
233 0
|
3月前
|
缓存 网络协议 安全
【网络工程师】<软考中级>解析协议ARP&路由协议RIP/OSPF/BGP
【1月更文挑战第27天】【网络工程师】<软考中级>解析协议ARP&路由协议RIP/OSPF/BGP
|
3月前
|
Web App开发 网络协议 关系型数据库
深度解析TCP协议:特点、应用场景及市面上常见软件案例
深度解析TCP协议:特点、应用场景及市面上常见软件案例
70 1
深度解析TCP协议:特点、应用场景及市面上常见软件案例
|
3月前
|
Dubbo 网络协议 安全
【Dubbo 解析】Dubbo 支持哪些协议,它们的优缺点有哪些?
【1月更文挑战第11天】【Dubbo 解析】Dubbo 支持哪些协议,它们的优缺点有哪些?
|
3月前
|
存储 网络协议
【计算机网络】HTTP 协议解析
【1月更文挑战第10天】【计算机网络】HTTP 协议解析
|
3月前
|
存储 缓存 网络协议
ARP协议:地址解析协议
ARP协议:地址解析协议
42 0
|
10天前
|
域名解析 网络协议 Linux
TCP/IP协议及配置、IP地址、子网掩码、网关地址、DNS与DHCP介绍
TCP/IP协议及配置、IP地址、子网掩码、网关地址、DNS与DHCP介绍
|
1月前
|
编解码 移动开发 C++
RTMP协议深度解析:从原理到实践,掌握实时流媒体传输技术
RTMP协议深度解析:从原理到实践,掌握实时流媒体传输技术
100 0
RTMP协议深度解析:从原理到实践,掌握实时流媒体传输技术

推荐镜像

更多