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可以做到的------核心存储引擎是统一的,只是接入协议不同。

相关推荐
niceffking2 小时前
C++内部类的ISO约定和语法细节
开发语言·c++
wjs20242 小时前
C# 常量
开发语言
Ma_Hong_Kai2 小时前
CMFCRibbonBar
开发语言·visualstudio·mfc
jaysee-sjc2 小时前
【练习十二】Java实现年会红包雨小游戏
java·开发语言·算法·游戏·intellij-idea
LONGZETECH2 小时前
新能源汽车充电设备装配与调试仿真教学软件 技术解析与教学落地
开发语言·系统架构·汽车·汽车教学软件·智能网联汽车软件
User_芊芊君子2 小时前
2026最新Python+AI入门指南:从零基础到实战落地,避开90%新手坑
开发语言·人工智能·python
分享牛2 小时前
Operaton入门到精通21-Operaton2 核心特性与架构升级指南
架构
篮l球场2 小时前
Trie(字典树/前缀树)
开发语言·c#
似水明俊德3 小时前
15-C#
android·开发语言·c#