Is there any need to allocate a memory space with encoded length size, to send a message with exact byte amount? This question comes from the use of chr() in example code to send 1 byte messages, instead of 4 bytes with 3 of them all 0.
1 byte without chr(): 00000000000000000000000011111111
1 byte using chr(): 11111111
Yeah, you need to send the exact amount of bytes that the encoded length is. In other words, that second approach is the correct one. Padding it with zero bytes will make RouterOS think the length is 0.
Will this make any difference on any side (client or server/router)? Why does example client uses self.writeStr(chr(l)) instead of simply self.writeStr(l) or self.writeStr(l & 0xff), at least on fist if block (< 0x80)?
Because the author of the original client was somewhat lazy, and writing it byte by byte is easier than allocating the correct number of bytes, processing the string into the correct value, and sending the entire string.
Ok. But what should I do when send() returns different quantity from what I sent? I guess send it again can cause problems…
You check how many bytes were sent, and resend from that byte onwards to the end.
Similarly when receiving - you check how many bytes were received, and keep receiving until the length is satisfied.
Side note: This sort of “quirk” is actually why MikroTik have defined the length in such terms - the very first byte tells how many more bytes to wait for, so you know how much to receive a length, and then the length tells you how much to receive the word. Without such consistency, you wouldn’t know for sure where the length ends and when the content begins. The alternative consistent solution would’ve been to have the length be “fixed” to 4 bytes, which would work, except that it forbids potential future expansion (which are currently possible via the currently unused “control bytes”), plus, in most cases you write words with 1 byte length, so this adds unnecessary 3 bytes to each word, requiring more bandwidth between client and RouterOS.
Although it’s possible to use C code within C++ applications, it’s not a good practice, since C does things in old and bad way.
I would’ve suggested making a C++ wrapper around that C client, but come to think of it, that client, while better than the Wiki one in every way, is not THAT perfect to warrant this.
If you want to make a RouterOS API client useful beyond C++, I’d suggest you make a new C client, and wrap the C++ code around that.
Why do that? Because other languages (I’m thinking PHP) can be extended by C only, though others can use either C or C++ (JAVA, C#…). Of course, as far as C++ apps go, I guess a pure C++ application would be “cleaner” (in terms of code base; in terms of compiled code, I’m sure it could be optimized to the point where there’s absolutely no measurable difference), so it’s your call.