如何为Lua的tcp:send()传入正确格式的十六进制TCP数据包参数?
Lua实现TCP专有数据包发送的格式问题
我有一个专有客户端应用,可与网络设备收发如下TCP数据包:
- 发送(14字节):
01 69 80 10 01 0E 0F 00 00 00 1C 0D 64 82 - 接收(42字节):
01 69 80 10 01 2A 00 D0 DC CC 0C BB C0 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1C 0D F6 BE
我需要用Lua实现相同的请求,已经找到LuaSocket相关示例,但不清楚调用tcp:send("string")时该传入什么格式的字符串:是直接传入十六进制字符串(比如'01698010010E0F0000001C0D6482'),还是要先把十六进制转换成对应字节的字符串?如果需要转换,那些无法对应ASCII符号的0值该怎么处理?
核心结论
不能直接传十六进制字符串,必须把十六进制序列转换成原始字节流字符串。Lua的字符串本质是字节序列,完全支持包含0值(\0)这类不可打印字符,不用额外处理。
十六进制转字节流的实现
自己写个简单的转换函数就行:
function hex_to_bytes(hex_str) local bytes = "" -- 先去掉字符串里的空格(如果有的话) hex_str = hex_str:gsub("%s+", "") -- 每两个字符一组,转成对应的字节 for i = 1, #hex_str, 2 do local byte_val = tonumber(hex_str:sub(i, i+1), 16) bytes = bytes .. string.char(byte_val) end return bytes end
完整使用示例
local socket = require("socket") local tcp = socket.tcp() -- 替换成目标设备的IP和端口 local ok, err = tcp:connect("192.168.1.100", 5000) if not ok then print("连接失败:", err) return end -- 准备要发送的十六进制数据 local send_hex = "01 69 80 10 01 0E 0F 00 00 00 1C 0D 64 82" local send_data = hex_to_bytes(send_hex) -- 发送字节流 tcp:send(send_data) -- 接收42字节的响应(和你收到的数据包长度一致) local recv_data, recv_err = tcp:receive(42) if recv_data then -- 可选:把收到的字节流转回十六进制方便查看 function bytes_to_hex(bytes) local hex_str = "" for i = 1, #bytes do hex_str = hex_str .. string.format("%02X ", string.byte(bytes, i)) end return hex_str:sub(1, -2) -- 去掉最后多余的空格 end print("收到响应:\n", bytes_to_hex(recv_data)) else print("接收出错:", recv_err) end tcp:close()
关键说明
- 直接传十六进制字符串的话,设备收到的是每个字符的ASCII码(比如
'0'对应0x30,'1'对应0x31),和你需要发送的原始字节完全不符,所以必须转换。 - Lua字符串可以存储任意字节,
string.char(0)生成的就是0x00字节,发送时会正常传递给设备,不需要特殊处理。
内容的提问来源于stack exchange,提问作者Aleksandr
相关产品推荐
相关产品推荐

