B/S和C/S架构在服务端接收请求

B/SC/S架构在服务端接收请求的方式有显著差异。


一、基本架构对比

C/S(客户端-服务器)架构

复制代码
[专门的客户端程序] ← 自定义协议 → [服务端程序]
       ↓                            ↑
    TCP连接                       TCP监听
    二进制/自定义协议               8888端口

TCP(Transmission Control Protocol,传输控制协议)是互联网中最核心、最基础的通信协议之一。它属于传输层协议,位于IP协议之上,负责在不可靠的IP网络之上,为应用程序提供可靠的、面向连接的、基于字节流的通信服务。

B/S(浏览器-服务器)架构

复制代码
[Web浏览器] ← HTTP/HTTPS协议 → [Web服务器] ← 应用协议 → [后端服务]
     ↓              ↑                  ↓                    ↑
  HTTP请求       HTTP响应         Nginx/Apache          业务逻辑
    80/443端口                    反向代理/负载均衡

二、核心差异对比表

方面 C/S架构 B/S架构
客户端形态 专门开发的桌面/移动应用 标准Web浏览器
网络协议 通常为自定义二进制协议或RPC框架 HTTP/HTTPS(应用层协议)
连接方式 通常是长连接/连接池 通常是短连接 (HTTP/1.x)或长连接(HTTP/2/3)
数据格式 Protocol Buffers、Thrift、自定义二进制 JSON/XML、Form Data、GraphQL
服务发现 需要内置(IP:Port配置、服务注册中心) 通过域名和DNS解析
安全机制 自定义加密、SSL/TLS隧道 HTTPS、CORS、Cookie/Session、OAuth
升级维护 需推送客户端更新 服务端更新即时生效

三、服务端接收请求的具体差异

1. C/S架构的服务端接收方式

复制代码
// 典型的C/S服务端代码结构
class CS_Server {
    void start() {
        // 1. 监听固定端口
        server_socket_.bind("0.0.0.0", 8888);
        
        while (running) {
            // 2. 接受TCP连接
            ClientSocket client = server_socket_.accept();
            
            // 3. 接收自定义协议的数据包
            Packet packet = client.receivePacket();
            
            // 4. 解析自定义二进制格式
            Request req = parseCustomProtocol(packet);
            
            // 5. 处理业务逻辑
            Response resp = handleRequest(req);
            
            // 6. 按照自定义协议格式返回
            client.sendPacket(serializeResponse(resp));
        }
    }
};

特点

  • 直接TCP监听:在指定端口上直接监听

  • 协议完全可控:自定义包头、包体格式

  • 状态保持:通常保持长连接,有状态

  • 高效紧凑:二进制协议,传输量小

2. B/S架构的服务端接收方式

复制代码
// 典型的B/S服务端代码结构(以REST API为例)
class BS_Server {
    void start() {
        // 1. Web框架(如Express/Spring Boot)初始化
        app = initializeWebFramework();
        
        // 2. 定义RESTful端点(路由)
        app.post("/api/data", [](const HttpRequest& req, HttpResponse& resp) {
            // 3. 从HTTP请求中提取数据
            std::string method = req.getMethod();  // "POST"
            std::string path = req.getPath();      // "/api/data"
            std::string token = req.getHeader("Authorization");
            std::string body = req.getBody();      // JSON字符串
            
            // 4. 解析JSON(而非自定义二进制)
            Json json = Json::parse(body);
            std::string key = json["key"];
            std::string value = json["value"];
            
            // 5. 处理业务逻辑
            bool success = processBusinessLogic(key, value);
            
            // 6. 返回HTTP响应
            resp.setStatus(200);
            resp.setHeader("Content-Type", "application/json");
            resp.setBody(R"({"code":0,"message":"success"})");
        });
        
        // 7. 监听HTTP端口
        app.listen(80);
    }
};

特点

  • 通过Web服务器/框架:Nginx、Apache、Tomcat等

  • HTTP协议解析:自动解析HTTP头、方法、路径、参数

  • 无状态设计:每个HTTP请求独立,依赖Cookie/Session/Token维持状态

  • 文本协议:通常是JSON/XML,人类可读


四、架构差异对服务端设计的影响

连接管理

复制代码
// C/S:通常维护连接池或长连接
class CS_ConnectionManager {
    std::unordered_map<int, ClientConnection> active_connections_;
    // 需要实现心跳、重连、连接保活逻辑
};

// B/S:通常无连接管理(HTTP短连接)
// 或由Web服务器管理(HTTP/2长连接)

协议处理

复制代码
// C/S:需要手动实现协议栈
class CustomProtocol {
    // 自定义的封包/解包逻辑
    Packet pack(const Request& req) {
        // 包头(4字节长度) + 包体(命令号+数据)
        uint32_t total_len = sizeof(Header) + req.data.size();
        // ... 复杂的字节序处理、校验和计算
    }
};

// B/S:使用标准HTTP,框架自动处理
// 开发者只需关心业务路由和JSON解析

安全考虑

复制代码
// C/S:需要自己实现全套安全机制
class CS_Security {
    // 加密通信、防重放攻击、消息防篡改
    // 客户端身份验证、版本兼容性检查
};

// B/S:利用成熟的Web安全机制
// HTTPS、CORS、CSRF Token、SameSite Cookie
// 防火墙、WAF等基础设施

五、现代趋势:混合与融合

1. 传统C/S的Web化

  • gRPC-Web:让浏览器能调用gRPC服务

  • WebSocket:在B/S中实现全双工长连接

    // 浏览器中的WebSocket
    const ws = new WebSocket("ws://server:8888/ws");
    ws.send(JSON.stringify({cmd: "get", key: "user1"}));

2. B/S后端的API化

复制代码
// 现在很多B/S后端本身就是API服务器
// 既服务浏览器,也服务移动端App
class UniversalAPI {
    // 同一套接口,多种客户端
    // 浏览器访问:GET https://api.example.com/v1/data
    // 移动App访问:同样的HTTP接口
    // 甚至通过API网关转换为gRPC
};

3. 微服务架构下的统一

复制代码
# 在K8s微服务中,C/S和B/S的界限模糊
services:
  - name: "data-service"
    ports:
      - 8080:8080  # HTTP接口(供B/S调用)
      - 9090:9090  # gRPC接口(供C/S调用)
    # 实际业务逻辑相同,只是协议适配层不同

六、实际应用场景示例

场景1:股票交易系统(C/S典型)

复制代码
// 服务端
class StockServer {
    // 二进制协议,高频低延迟
    // 长连接,实时推送行情
    // 客户端是专业的交易软件
};

场景2:电商网站(B/S典型)

复制代码
# 服务端(Django/Spring Boot)
@app.route('/api/order', methods=['POST'])
def create_order():
    # HTTP + JSON
    # 浏览器访问,也供App调用
    # 无状态,通过JWT识别用户
    return jsonify({'order_id': 123})

场景3:实时协作工具(混合)

复制代码
// Web版用WebSocket + HTTP
// 桌面客户端用自定义协议
// 移动端用HTTP/2 + gRPC
// 后端统一业务逻辑,不同协议适配

总结

对比维度 C/S架构接收方式 B/S架构接收方式
协议层 传输层/自定义应用层 HTTP应用层协议
连接模型 主动长连接 请求-响应短连接
数据格式 紧凑二进制 文本(JSON/XML)
服务入口 IP:Port直接暴露 通过Web服务器/反向代理
客户端耦合 强耦合,协议升级需同步 松耦合,接口兼容即可
适用场景 高性能、实时性要求高 跨平台、易部署、广域网

现代实践:实际上两者界限越来越模糊。很多系统同时提供:

  1. HTTP API​ 给Web和移动端

  2. gRPC/自定义协议​ 给内部服务或专业客户端

  3. WebSocket​ 给需要实时性的Web应用

服务端设计的关键是分离协议层和业务层 ,让同一套业务逻辑能够通过不同的协议适配器对外提供服务。这正是您最初设计的DataStorageServer可以做到的------核心存储引擎是统一的,只是接入协议不同。

相关推荐
Highcharts.js18 小时前
倒置百分比堆叠面积图表示列详解|Highcharts大气成分图表代码
开发语言·信息可视化·highcharts·图表开发·面积图·图表示例·推叠图
csdn_aspnet19 小时前
C语言 Lomuto分区算法(Lomuto Partition Algorithm)
c语言·开发语言·算法
晨曦中的暮雨19 小时前
4.15腾讯 CSIG云服务产线 一面
java·开发语言
存在morning19 小时前
【GO语言开发实践】二 GO 并发快速上手
大数据·开发语言·golang
fake_ss19819 小时前
AI时代学习全栈项目开发的新范式
java·人工智能·学习·架构·个人开发·学习方法
谙弆悕博士19 小时前
【附C源码】从零实现C语言堆数据结构:原理、实现与应用
c语言·数据结构·算法··数据结构与算法
米高梅狮子20 小时前
第2章 docker容器
运维·docker·云原生·容器·架构·kubernetes·自动化
xiaoerbuyu123320 小时前
开源Java 邮箱 基于SpringBoot+Vue前后端分离的电子邮件
java·开发语言
sparEE21 小时前
c++值类别、右值引用和移动语义
开发语言·c++
zhangjw3421 小时前
第11篇:Java Map集合详解,HashMap底层原理、哈希冲突、JDK1.8优化、遍历方式彻底吃透
java·开发语言·哈希算法