如何使用 NodeMCU 通过 TCP 发送/接收二进制数据?

Posted

技术标签:

【中文标题】如何使用 NodeMCU 通过 TCP 发送/接收二进制数据?【英文标题】:How to send/receive binary data over TCP using NodeMCU? 【发布时间】:2017-10-11 21:34:54 【问题描述】:

我一直在尝试在 NodeMCU 平台上的 TCP 模块上安装自定义协议。但是,我尝试嵌入 TCP 数据段的协议是二进制的,而不是基于 ASCII 的(例如 HTTP),所以有时它包含一个 NULL 字符(字节 0x00)结束 TCP 模块实现中的 C 字符串,导致数据包内的部分消息丢失。

-- server listens on 80, if data received, print data to console and send "hello world" back to caller
-- 30s time out for a inactive client
sv = net.createServer(net.TCP, 30)

function receiver(sck, data)
  print(data)
  sck:close()
end

if sv then
  sv:listen(80, function(conn)
    conn:on("receive", receiver)
    conn:send("hello world")
  end)
end

*这是一个简单的例子,正如你所见,'receiver' 变量是一个回调函数,它打印监听器检索到的 TCP 段中的数据。

如何解决这个问题?有没有办法使用 NodeMCU 库来规避这个问题?还是我必须实现另一个 TCP 模块或修改当前的实现以支持数组或表作为返回值而不是使用字符串?

欢迎提出任何建议。

【问题讨论】:

您是否检查过数据是否真的被截断了?我怀疑,只有 print() 方法会在 0 字节处停止。尝试打印数据的长度看看,如果输入的时候已经被截断然后回调。 Lua 本身对嵌入 NULL 的字符串没有问题。 print 应该可以很好地处理它们。你可以用print(#data)查看data的长度。 【参考方案1】:

您在回调中收到的数据不应被截断。您可以通过如下更改代码自行检查:

function receiver(sck, data)
   print("Len: " .. #data)
   print(data)
   sck:close()
 end

您会发现,虽然数据确实只打印到第一个零字节(通过print()-函数),但整个数据都存在于 LUA 字符串 data 中,您可以对其进行处理正确使用 8 位安全(和零字节安全)方法。

虽然将print()-函数修改为零字节安全应该很容易,但我不认为这是一个错误,因为打印函数是用于文本的。如果要将二进制数据写入串口,请使用uart.write(),即

uart.write(0, data)

【讨论】:

@MatthewBurke Argh, ty ;) 确实是 print() 函数,它不是零字节安全的,不是其他任何东西。谢谢

以上是关于如何使用 NodeMCU 通过 TCP 发送/接收二进制数据?的主要内容,如果未能解决你的问题,请参考以下文章

Android & NodeMCU,从服务器接收响应不能正常工作?

使用 C++ 通过 TCP 发送文件,接收错误的大小

如何通过 TCP 和 protobuf-net 接收包

如何使用新的 SDK (NodeMCU) 发送多个数据 (conn:send())

通过 TCP 发送/接收文件 [重复]

Java:通过 TCP 发送/接收数据并从 UDP 接收图像