0

I have a proprietary client application that sends and receives TCP data packets to|from the network device like this:

Sent: [14 bytes] 01 69 80 10 01 0E 0F 00 00 00 1C 0D 64 82 .i..........d.

Received: [42 bytes] [+00:000] 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 .i...*.......@.................. 00 00 00 00 00 00 1C 0D F6 BE .......... or see the picture

I need to make same requests with Lua. I've found some working examples (for ex) for such communications, but I can't understand what string should I give as an argument for

tcp:send("string");

Should I give it a string of hex? I.e. '01698010010E0F0000001C0D6482'

Or first convert hex to ACSII? If so, then how (zeroes doesn't convert to symbols)?

Aleksandr
  • 1
  • 3
  • You need to give any kind of string as an argument. For example, `tcp:send("hello world!");` – SAL Jul 26 '22 at 13:15
  • this is a binary protocol. it consists mainly of non-printing characters. I strongly recommend you learn how serial communication works. befor you attempt to emulate tcp clients. – Piglet Jul 26 '22 at 13:22
  • That's binary protocol packed inside TCP message. – Aleksandr Jul 26 '22 at 13:26

1 Answers1

0

You should give it the string you want to send. If you write "016980..." it's a string containing decimal values 48 (ascii digit 0), 49 (ascii digit 1), 54 (ascii digit 6), and so on. Which is not what you want to send. You want to send decimal values 1, 105 (hex 69), 128 (hex 80) and so on.

Luckily, Lua strings can hold any bytes (unlike e.g. Python strings). So you just have to write a string with those bytes. You can write any byte into a string using \x and then a 2-digit hex code. So you could write your call like this:

tcp:send("\x01\x69\x80\x10\x01\x0E\x0F\x00\x00\x00\x1C\x0D\x64\x82")

If you are using a Lua version older than 5.2, \x is not available, but you can still use \ and a 3-digit decimal code.

user253751
  • 57,427
  • 7
  • 48
  • 90
  • It worked, TY. Now I need to figure out how to deal with the answer. Print() cuts the string at zeroes. – Aleksandr Jul 26 '22 at 13:58
  • @Aleksandr try https://stackoverflow.com/a/71896879/106104 – user253751 Jul 26 '22 at 14:38
  • Hi! TY. I used this: `code` for i = 1, string.len(strout) do charstring = charstring .. string.format("0x%02X", string.byte(strout,i)) end `code` Problem is, string.len gives length of 41 bytes, not 42, as it should be and consequently strout doesn't contain last byte. I wonder where this byte could go... – Aleksandr Jul 27 '22 at 08:20
  • I discovered that when I send another request with shorter answer, for ex. 18 bytes, then all bytes are present, but with long response of 42 bytes, last byte is lost. – Aleksandr Jul 27 '22 at 08:45
  • @Aleksandr what is the last byte? do you know its value? if string.len returns 41 it means 41 is the length of the string - how do you know it's supposed to be 42? – user253751 Jul 27 '22 at 11:50
  • Because as defined by binary protocol 6th byte defines length of message and it is 0x2A i.e. 42 decimal. See example of request|response in the post. Issue resolved by itself. Now I got 42 bytes, but I can't understand what I changed. When I'll figure it out, I'll write how I lost 1 last byte. TY very much for your help. – Aleksandr Jul 27 '22 at 12:39
  • is it possibly because you only call receive once per response and the 42nd byte was in the next receive call instead? – user253751 Jul 27 '22 at 12:41