网络编程与通讯协议综合解析

(一)TCP、poll、epoll

TCP(传输控制协议)

  • 是什么 :TCP 是一种面向连接、可靠的网络传输协议。它把要发送的大块数据切成一个个"小段"(称为报文段),并在发送前为每段加上序号。接收方收到后会给发送方回送确认(ACK),如果发送方在一定时间内没有收到确认,就会重新发送该段。
  • 通俗比喻:想象你在写信寄快递,每封信都有编号,收件人收到后会回一张收据。如果寄出的信件丢了,你会再寄一遍,直到收到收据为止。
  • 开发实例 :在 C/C++ 中使用 socket()connect()send()recv() 等系统调用即可实现基于 TCP 的客户端/服务器。例如,一个最简单的回显服务器会在 recv() 读取到客户端发来的数据后,直接用 send() 把相同的数据返回给客户端。

poll(轮询)

  • 是什么poll 是一种 I/O 多路复用 的系统调用。它让一个进程一次性监视 多个文件描述符(如套接字、管道、文件等)的状态(是否可读、可写、异常等),并在有任意一个描述符准备好时返回。

  • 通俗比喻:想象你是老师,要检查一堆学生的作业是否完成。你一次性把所有作业本都摆在桌子上,等到有学生把作业交上来,你立刻看到并批改,而不必一个一个去叫学生。

  • 开发实例 :在 Linux 下,使用 struct pollfd 数组把所有要监听的套接字放进去,然后调用 poll(pfds, nfds, timeout)。返回后遍历数组,找到 revents 标记为可读或可写的套接字进行相应的 recv() / send() 操作。

    c 复制代码
    struct pollfd fds[2];
    fds[0].fd = listen_fd;      // 监听套接字
    fds[0].events = POLLIN;    // 关注可读事件(新连接)
    fds[1].fd = client_fd;      // 已连接的客户端
    fds[1].events = POLLIN;    // 关注可读事件(收到数据)
    
    int ret = poll(fds, 2, -1); // 阻塞等待
    if (fds[0].revents & POLLIN) { /* accept new connection */ }
    if (fds[1].revents & POLLIN) { /* recv data */ }

epoll(高效的 I/O 多路复用)

  • 是什么epoll 是 Linux 为了解决 poll/select大规模并发 场景下性能瓶颈而推出的专用机制。它采用 事件驱动 的方式,只在真正有状态变化的文件描述符上触发回调,避免每次轮询都遍历全部描述符。

  • 通俗比喻:继续老师的例子。如果班里有几千名学生,你不可能每次都把所有作业本都搬到桌子上检查。于是你让每个学生在作业完成后主动把作业本递到老师面前,老师只需要处理递来的作业本,效率大大提升。

  • 开发实例 :使用 epoll_create1() 创建 epoll 实例,epoll_ctl() 把感兴趣的套接字加入(或删除)监视集合,epoll_wait() 阻塞等待事件。返回的事件数组只包含真正有活动的套接字。

    c 复制代码
    int efd = epoll_create1(0);
    struct epoll_event ev, events[10];
    
    ev.events = EPOLLIN;          // 关注可读事件
    ev.data.fd = listen_fd;
    epoll_ctl(efd, EPOLL_CTL_ADD, listen_fd, &ev);
    
    while (1) {
        int n = epoll_wait(efd, events, 10, -1);
        for (int i = 0; i < n; ++i) {
            if (events[i].data.fd == listen_fd) {
                // 有新连接
                int conn = accept(listen_fd, NULL, NULL);
                ev.events = EPOLLIN;
                ev.data.fd = conn;
                epoll_ctl(efd, EPOLL_CTL_ADD, conn, &ev);
            } else {
                // 已连接的客户端有数据可读
                char buf[1024];
                ssize_t cnt = read(events[i].data.fd, buf, sizeof(buf));
                // 处理数据...
            }
        }
    }

小结

名称 作用 适用场景 关键特性
TCP 可靠的点对点数据传输 需要保证数据完整性(文件传输、网页请求等) 连接、序号、确认、重传
poll 同时监视多个 I/O 对象的状态 连接数不多、代码简单的服务器 每次调用遍历全部描述符
epoll 高效监视大量 I/O 对象 高并发服务器(成千上万连接) 只返回活跃描述符,性能更好

(二)TCP、http、sse、wss、mqtt通讯协议对比

一、基本概念(通俗版)

名称 所在层次 关键特性 典型使用场景
TCP 传输层(OSI 第 4 层) 面向连接、可靠、全双工、基于字节流、通过三次握手/四次挥手建立和关闭连接 文件传输、网页请求、任何需要保证数据不丢失的场景
HTTP 应用层(基于 TCP) 请求‑响应模型、无状态、默认端口 80(HTTPS 443),支持 GET/POST 等方法 浏览器访问网页、REST API、静态资源下载
SSE(Server‑Sent Events) 基于 HTTP 的单向推送 服务器单向向浏览器推送文本/JSON,自动重连,使用普通 HTTP(或 HTTPS)长连接 新闻、股票行情、系统通知等只需要服务器"推送"而不需要客户端回传的实时更新
WSS(WebSocket Secure) 基于 TCP 的全双工协议(加密版) 在 WebSocket(ws://)之上加入 TLS/SSL 加密,URL 以 wss:// 开头,提供双向实时通信 在线聊天、实时协作、游戏等对安全有要求的双向交互
MQTT 基于 TCP(可选 TLS) 的轻量级发布‑订阅协议 采用 Broker 中转,支持 QoS 0/1/2,报文头极小,适合低带宽、低功耗设备 物联网传感器、远程监控、移动端轻量消息推送

二、技术对比与选型指南

  1. 传输可靠性 vs 交互模式

    • TCP 提供可靠的点对点传输,是所有上层协议(HTTP、WebSocket、MQTT)的基石。
    • HTTP 只负责一次请求‑响应,适合"拉取"数据的场景。
    • SSE 在 HTTP 长连接上实现单向 推送,代码只需在浏览器端 new EventSource(url),不需要自己维护心跳或重连逻辑。
    • WebSocket / WSS 实现全双工 通信,客户端 new WebSocket(url),服务器可以随时主动发送,也能随时接收客户端消息。
    • MQTT 采用发布‑订阅模型,客户端不直接相互通信,而是通过 Broker 进行主题(topic)转发,天然支持多对多广播。
  2. 性能与资源消耗

    • SSE 只支持文本(JSON)数据,协议开销极小,适合数千级别的单向推送[[6]]。
    • WebSocket(WSS)在保持一个 TCP 连接的前提下,能够以毫秒级延迟双向传输,适合高频交互(聊天、游戏)[[7]]。
    • MQTT 报文头只有 2‑4 字节,QoS 机制可以在网络不佳时自动重传或丢弃,极其适合成千上万的物联网设备[[8]]。
  3. 安全性

    • HTTPHTTPS (TLS)可加密;WebSocketWSS 同理,使用 wss:// 即可在传输层提供加密[[9]]。
    • SSE 也可以通过 HTTPS(https://)实现加密,只是协议本身不自带加密层。
    • MQTT 支持基于 TLS 的 MQTTSmqtts://),在需要机密传输的工业场景中常用。
  4. 典型开发示例(代码片段)

    • TCP(C)

      c 复制代码
      int sock = socket(AF_INET, SOCK_STREAM, 0);
      connect(sock, (struct sockaddr*)&addr, sizeof(addr));
      send(sock, "hello", 5, 0);
      recv(sock, buf, sizeof(buf), 0);
      close(sock);
    • HTTP(curl)

      bash 复制代码
      curl -X GET https://api.example.com/users
    • SSE(浏览器)

      js 复制代码
      const es = new EventSource('/sse/price');
      es.onmessage = e => console.log('price:', e.data);
    • WebSocket / WSS(浏览器)

      js 复制代码
      const ws = new WebSocket('wss://chat.example.com');
      ws.onopen = () => ws.send(JSON.stringify({type:'join',room:1}));
      ws.onmessage = e => console.log('msg:', e.data);
    • MQTT(JavaScript Paho)

      js 复制代码
      const client = new Paho.MQTT.Client('broker.example.com', 8883, 'web_' + Math.random());
      client.connect({useSSL:true, onSuccess:()=>{ client.subscribe('sensor/+/temp'); }});
      client.onMessageArrived = msg => console.log(msg.topic, msg.payloadString);
  5. 选型小结

场景 推荐协议 说明
普通网页请求、REST API HTTP/HTTPS 简单请求‑响应,易于缓存、CDN
只需要服务器单向实时推送(新闻、监控) SSE(HTTPS) 实现最简单,自动重连,浏览器原生支持
双向实时交互且对延迟敏感(聊天、协作、游戏) WebSocket / WSS 全双工、低延迟,安全版使用 WSS
大量低功耗设备、需要主题广播、带 QoS MQTT(MQTTS) 轻量、发布‑订阅、可伸缩,适合物联网
需要可靠的点对点传输(文件、流媒体) TCP(配合上层协议) 为上层协议提供可靠通道

三、总结

  • TCP 是所有网络通信的可靠基石。
  • HTTP 基于 TCP,适合一次性请求‑响应。
  • SSE 在 HTTP 长连接上实现单向推送,代码最简。
  • WSS 是加密版 WebSocket,提供全双工实时通信并保证安全。
  • MQTT 采用轻量的发布‑订阅模型,专为海量物联网设备设计。

根据业务需求(单向推送 vs 双向交互、设备规模、带宽限制、安全要求),在上述协议中挑选最合适的即可实现高效、可靠的网络通信。

(三)python实现示例

一、TCP(传输控制协议)

  • 概念 :TCP 是面向连接、可靠的传输层协议。发送方把要发送的字节流切成若干报文段 ,每段都有序号;接收方收到后会回送 ACK(确认),发送方若在超时时间内未收到 ACK 就会重新发送该段。这样可以保证数据不丢失、顺序不乱。
  • Python 示例(客户端)
python 复制代码
from socket import *

server_name = '127.0.0.1'      # 服务器 IP
server_port = 12000           # 服务器端口
client = socket(AF_INET, SOCK_STREAM)
client.connect((server_name, server_port))

msg = input('输入一句话:')
client.send(msg.encode())               # 发送
reply = client.recv(1024).decode()     # 接收
print('服务器返回:', reply)
client.close()
  • Python 示例(服务器)
python 复制代码
from socket import *

PORT = 12000
server = socket(AF_INET, SOCK_STREAM)
server.bind(('', PORT))          # 监听所有网卡
server.listen(1)
print('服务器已启动,等待连接...')

while True:
    conn, addr = server.accept()
    data = conn.recv(1024).decode()
    conn.send(data.upper().encode())   # 把收到的内容转成大写再回传
    conn.close()

二、poll 与 epoll(I/O 多路复用)

  • poll :一次性把多个文件描述符(套接字、文件等)放进 pollfd 数组,调用 poll() 后内核会检查哪些描述符已经准备好(可读、可写、异常),返回后只处理这些"活跃"的描述符。适用于几百到几千个连接,但每次调用都要遍历整个数组。
  • epoll (Linux 专有):采用 事件驱动 ,只在真正有状态变化的描述符上触发回调,内部使用红黑树 + 双向链表,避免每次遍历,能够轻松支撑 上万甚至上百万 并发连接。

Python 示例(使用 select.poll

python 复制代码
import socket, select

listen = socket.socket()
listen.bind(('0.0.0.0', 9000))
listen.listen()
poller = select.poll()
poller.register(listen.fileno(), select.POLLIN)

while True:
    events = poller.poll()
    for fd, flag in events:
        if fd == listen.fileno():
            conn, _ = listen.accept()
            poller.register(conn.fileno(), select.POLLIN)
        else:
            conn = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
            data = conn.recv(1024)
            if data:
                conn.send(b'echo: ' + data)
            else:                     # 客户端关闭
                poller.unregister(fd)
                conn.close()

Python 示例(使用 select.epoll

python 复制代码
import socket, select

listen = socket.socket()
listen.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listen.bind(('0.0.0.0', 9001))
listen.listen()
ep = select.epoll()
ep.register(listen.fileno(), select.EPOLLIN)

while True:
    for fd, event in ep.poll():
        if fd == listen.fileno():
            conn, _ = listen.accept()
            ep.register(conn.fileno(), select.EPOLLIN)
        else:
            conn = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
            data = conn.recv(1024)
            if data:
                conn.send(b'echo: ' + data)
            else:
                ep.unregister(fd)
                conn.close()

三、HTTP(超文本传输协议)

  • 概念 :基于 TCP 的请求‑响应协议。客户端(浏览器或程序)发送 GET/POST 等请求,服务器返回 状态码 + 报文体 。在 AI 业务中常用来提供 RESTful API,让前端或其他服务通过 HTTP 调用模型推理接口。
  • Python 示例(Flask 简单 HTTP 服务)
python 复制代码
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/hello')
def hello():
    name = request.args.get('name', 'World')
    return f'Hello, {name}!'

@app.route('/predict', methods=['POST'])
def predict():
    data = request.json          # 前端发送的 JSON
    # 这里可以调用模型进行推理,示例直接回显
    result = {'input': data, 'output': 'dummy_result'}
    return jsonify(result)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)   # 运行在 5000 端口

四、SSE(Server‑Sent Events)

  • 概念 :在 HTTP 长连接上单向推送数据的技术。服务器端返回 Content-Type: text/event-stream,随后不断发送 data: ...\n\n 格式的文本。浏览器端使用 EventSource 接收,适合 实时监控、日志推送、股票行情 等只需要服务器主动推送的场景。
  • Python 示例(Flask 实现 SSE)
python 复制代码
from flask import Flask, Response
import time

app = Flask(__name__)

def event_stream():
    i = 0
    while True:
        i += 1
        yield f'data: 计数 {i}\n\n'   # 每秒推送一次
        time.sleep(1)

@app.route('/counter')
def counter():
    return Response(event_stream(),
                    mimetype='text/event-stream')

if __name__ == '__main__':
    app.run(threaded=True)   # 必须开启多线程
  • 浏览器端(HTML)(仅示例,实际使用时放在前端页面)
html 复制代码
<script>
  const es = new EventSource('/counter');
  es.onmessage = e => console.log('服务器推送:', e.data);
</script>

五、WSS(WebSocket Secure)

  • 概念 :在 HTTP/HTTPS 端口上升级为全双工的 WebSocket 连接,ws:// 为明文,wss:// 为 TLS 加密版。建立一次握手后,客户端和服务器都可以随时主动发送二进制或文本帧,延迟通常在毫秒级。适用于 聊天、实时协作、在线游戏、AI 推理流式返回(如 ChatGPT 的流式输出)。
  • Python 示例(使用 websockets 库)
python 复制代码
# server.py
import asyncio, websockets

async def echo(ws, path):
    async for msg in ws:
        await ws.send(f'回显:{msg}')

start_server = websockets.serve(echo, '0.0.0.0', 8765, ssl=None)  # 若要 wss,传入 ssl.SSLContext
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
python 复制代码
# client.py
import asyncio, websockets

async def hello():
    async with websockets.connect('ws://127.0.0.1:8765') as ws:
        await ws.send('你好,服务器')
        reply = await ws.recv()
        print('服务器说:', reply)

asyncio.get_event_loop().run_until_complete(hello())

如果需要 wss (加密),只需在 websockets.servewebsockets.connect 中传入 ssl 参数,使用 ssl.SSLContext 加载证书即可。


六、MQTT(Message Queuing Telemetry Transport)

  • 概念 :轻量级的 发布‑订阅 协议,基于 TCP(可选 TLS)。客户端 publish 消息到某个 topic ,Broker 再把该 topic 的所有 subscriber 推送过去。报文头只有几字节,非常适合 物联网、边缘设备、实时数据流
  • Python 示例(使用 paho-mqtt
python 复制代码
# publisher.py
import paho.mqtt.client as mqtt

broker = 'broker.hivemq.com'   # 公共测试 broker
client = mqtt.Client()
client.connect(broker, 1883, 60)

client.publish('demo/temperature', payload='23.5', qos=0)
print('已发布温度 23.5')
client.disconnect()
python 复制代码
# subscriber.py
import paho.mqtt.client as mqtt

def on_message(client, userdata, msg):
    print(f'收到主题 {msg.topic}: {msg.payload.decode()}')

broker = 'broker.hivemq.com'
client = mqtt.Client()
client.on_message = on_message
client.connect(broker, 1883, 60)

client.subscribe('demo/temperature')
client.loop_forever()   # 持续监听
  • 适用场景
    • TCP:需要可靠、顺序的数据传输(文件、数据库同步)。
    • poll/epoll :服务器需要同时管理大量长连接,epoll 在高并发下性能最佳。
    • HTTP :一次性请求‑响应,适合 REST API、模型推理的同步调用
    • SSE:服务器单向推送实时更新,客户端不需要发送数据(如日志、监控面板)。
    • WSS :全双工、低延迟,适合 聊天、协作编辑、流式 AI 输出
    • MQTT :轻量、主题广播,适合 IoT 设备、边缘计算、海量传感器数据

小结(适用场景对照)

  • 可靠点对点TCP(如文件传输、远程调用)
  • 大量并发、需要高效轮询epoll(高并发 Web 服务、游戏服务器)
  • 一次性请求‑响应HTTP(RESTful API、模型同步推理)
  • 服务器单向推送SSE(实时监控、新闻推送)
  • 全双工实时交互WSS(聊天、协作、流式 AI)
  • 轻量发布‑订阅MQTT(物联网、传感器网络、实时数据分发)
相关推荐
bing_feilong2 小时前
ubuntu中的WIFI与自身热点切换
网络
CodeByV2 小时前
【网络】UDP 协议深度解析:从五元组标识到缓冲区
网络·网络协议·udp
虹科网络安全3 小时前
艾体宝洞察 | 利用“隐形字符”的钓鱼邮件:传统防御为何失效,AI安全意识培训如何补上最后一道防线
运维·网络·安全
石像鬼₧魂石3 小时前
Kali Linux 网络端口深度扫描
linux·运维·网络
适应规律5 小时前
UNeXt-Stripe网络架构解释
网络
纸带6 小时前
USB通信的状态
网络
无敌最俊朗@7 小时前
WebSocket与Webhook:实时通信技术对比
网络·websocket·网络协议
悟空空心7 小时前
服务器长ping,traceroute
linux·服务器·网络·ssh·ip·ping++
F133168929577 小时前
5030A 芯片 24V 转 5V 15A 大电流快充选型
网络·单片机·嵌入式硬件·物联网·汽车