2

I've been trying to mount a custom protocol over the TCP module on the NodeMCU platform. However, the protocol I try to embed inside the TCP data segment is binary, not ASCII-based(like HTTP for example), so sometimes it contains a NULL char (byte 0x00) ending the C string inside the TCP module implementation, causing that part of the message inside the packet get lost.

-- 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

*This is a simple example which, as you can see, the 'receiver' variable is a callback function which prints the data from the TCP segment retrieved by the listener.

How can this be fixed? is there a way to circumvent this using the NodeMCU library? Or do I have to implement another TCP module or modify the current one's implementation to support arrays or tables as a return value instead of using strings?

Any suggestion is appreciated.

dda
  • 6,030
  • 2
  • 25
  • 34
thePiGrepper
  • 183
  • 7
  • 1
    Have you checked, if the data is _really_ truncated? I suspect, that only the print()-method will stop on a 0-byte. Try to print the length of the data to see, if it is truncated already when entering then callback. – Ctx May 12 '17 at 14:41
  • Lua itself doesn't have a problem with strings with NULLs embedded. And `print` should handle them fine. You can check the length of `data` with `print(#data)`. – Matthew Burke May 12 '17 at 14:50

1 Answers1

1

The data you receive in the callback should not be truncated. You can check this for yourself by altering the code as follows:

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

You will observe, that, while the data is indeed only printed up to the first zero byte (by the print()-function), the whole data is present in the LUA-String data and you can process it properly with 8-bit-safe (and zerobyte-safe) methods.

While it should be easy to modify the print()-function to also be zerobyte-safe, I do not consider this as a bug, since the print function is meant for texts. If you want to write binary data to serial, use uart.write(), i.e.

uart.write(0, data)
Ctx
  • 18,090
  • 24
  • 36
  • 51