网口和串口通信有什么区别?各自支持的协议如何实现通信的?
作者:小编
更新时间:2025-11-19
点击数:
网口和串口是两种不同的物理通信方式,它们在通信协议、速度、距离、应用场景等方面有显著区别。
物理层差异
| 特性 | 串口 (UART/RS232/RS485) | 网口 (Ethernet) |
|---|---|---|
| 物理接口 | DB9、端子等 | RJ45 |
| 信号类型 | 电压信号 | 差分信号 |
| 传输距离 | RS232: 15m, RS485: 1200m | 100m (无中继) |
| 连接方式 | 点对点、总线式 | 星型拓扑 |
| 传输速率 | 通常 ≤ 115.2kbps | 10Mbps - 100Gbps |
| 电气隔离 | 可选 | 标准要求 |
协议栈对比
串口协议栈
应用层协议 (Modbus RTU, 自定义协议等) ↓ 数据链路层 (简单的帧结构) ↓ 物理层 (UART → RS232/RS485)
网口协议栈
应用层协议 (HTTP, MQTT, Modbus TCP等) ↓ 传输层 (TCP/UDP) ↓ 网络层 (IP) ↓ 数据链路层 (以太网帧) ↓ 物理层 (以太网PHY)
协议实现方式
串口协议实现
1. Modbus RTU 实现:
-- 在您的 data_send.lua 中function modbus_ask(channel, packet, uart_addr) -- 1. 解析Modbus RTU帧 local address, functionCode, startRegister, numRegisters, crc = parseQueryCommand(command) -- 2. 处理数据请求 local data = getDataFromDevice(startRegister, numRegisters) -- 3. 构建响应帧 local responseFrame = buildResponseFrame(address, functionCode, data) -- 4. 通过串口发送 uart_send(channel, responseFrame)end
2. 自定义ASCII协议:
function databuff_str_process(data) -- 添加起始位、结束位、校验和 local startByte = string.char(2) -- STX local endByte = string.char(3) -- ETX local dataWithMarkers = startByte .. data .. endByte local checksum = calculateChecksum(dataWithMarkers) return dataWithMarkers .. string.char(checksum)end
网口协议实现
1. TCP Socket 通信基础:
-- 假设串口屏支持网络功能function init_network() -- 初始化网络连接 network_init() -- 创建TCP服务器 tcp_server = socket_create() socket_bind(tcp_server, "0.0.0.0", 502) -- Modbus TCP端口 socket_listen(tcp_server, 5)endfunction handle_tcp_connections() while true do local client = socket_accept(tcp_server) if client then -- 在新协程中处理客户端 coroutine.create(function() process_tcp_client(client) end) end sleep(10) endend
2. Modbus TCP 实现:
function process_tcp_client(client)
while true do
local data = socket_receive(client, 1024)
if not data then break end
-- Modbus TCP帧处理 (去掉了MBAP头)
local modbus_data = string.sub(data, 7) -- 跳过6字节MBAP头 + 1字节单元标识
-- 使用现有的Modbus RTU处理逻辑
local response = modbus_ask(nil, modbus_data, unit_id)
if response then
-- 添加Modbus TCP MBAP头
local mbap_header = {
0x00, 0x01, -- 事务标识
0x00, 0x00, -- 协议标识 (0=Modbus)
(#response + 1) >> 8, (#response + 1) & 0xFF, -- 长度
unit_id -- 单元标识
}
local tcp_response = string.char(table.unpack(mbap_header)) .. string.char(table.unpack(response))
socket_send(client, tcp_response)
end
end
socket_close(client)end3. HTTP REST API 实现:
function start_http_server()
local http_server = socket_create()
socket_bind(http_server, "0.0.0.0", 80)
socket_listen(http_server, 5)
while true do
local client = socket_accept(http_server)
if client then
coroutine.create(function()
handle_http_request(client)
end)
end
endendfunction handle_http_request(client)
local request = socket_receive(client, 1024)
local method, path = parse_http_request(request)
if method == "GET" and path == "/api/sensor/data" then
-- 返回JSON格式的传感器数据
local json_data = buildMQTTData(edited_databuff)
local response = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n" .. json_data socket_send(client, response)
elseif method == "POST" and path == "/api/config" then
-- 处理配置更新
local body = extract_http_body(request)
local config = cjson.decode(body)
apply_config_changes(config)
local response = "HTTP/1.1 200 OK\r\n\r\n{\"status\":\"success\"}"
socket_send(client, response)
end
socket_close(client)end4. MQTT over TCP 实现:
function mqtt_connect()
local mqtt_client = socket_create()
socket_connect(mqtt_client, "mqtt.broker.com", 1883)
-- MQTT连接报文
local connect_packet = build_mqtt_connect_packet()
socket_send(mqtt_client, connect_packet)
return mqtt_clientendfunction mqtt_publish_data(mqtt_client)
while true do
local json_data = buildMQTTData(edited_databuff)
local publish_packet = build_mqtt_publish_packet("sensors/data", json_data)
socket_send(mqtt_client, publish_packet)
sleep(5000) -- 5秒发布一次
endend通信协议对比表
| 协议类型 | 串口实现 | 网口实现 | 适用场景 |
|---|---|---|---|
| Modbus | Modbus RTU | Modbus TCP | 工业控制 |
| 自定义协议 | 起始位+数据+校验 | TCP Socket | 专用系统 |
| HTTP/REST | 不适用 | HTTP Server | Web配置 |
| MQTT | 通过串口转发 | 直接TCP | 物联网 |
| WebSocket | 不适用 | WebSocket | 实时数据 |
