I use msgrcv function to read message from message queue. It works fine when I read known length data. Some cases my message length is variable. In such How can i allocate only require amount of memory and read the message from message queue without losing any data from message queue. Please give idea to overcome this issue.
Note:
In IBM message queue, when we read exceeded length data, it fills the actual size of the message into structure which we are passing mqget function. Like this, Is there any way to do this operation in message queue.
From my brief reading of the msgrcv() man page, if your buffer size is too small and you don't specify the MSG_NOERROR flag, msgrcv() will return -1 (with errno set to E2BIG) and leave the message in the queue.
In this case, you could double your buffer size (up to MSGMAX, which is 8192 on linux by default) and try again.
Related
Implementing a netlink (rtnetlink) module I ran into a problem:
Like for UDP, a part of the message (packet) is lost when the receive buffer is not big enough (e.g. when the buffer is 1024 bytes and you received 1024 bytes).
So I wondered how to prepare the "correct" receive buffer.
Initially I had the idea to MSG_PEEK just the nlmsghdr, then extract the message size from there, and next do the final receive.
As security measure I allocated one byte more, just to be able to complain if the receive size used the full buffer.
Unfortunately it did!
Is there an algorithm that will work, not needing a ridiculously huge receive buffer?
Example:
nlmsg_len was 1276, so I tried to receive 1277 bytes, and I did.
So on the next attempt I blindly added 2000 bytes to the receive buffer, and the result was 2552 bytes long (1276 bytes longer than expected).
As said above I think I cannot "continue" to receive a longer message using multiple recvs, so I must receive all at once.
I need to transfer data over a serial port. In order to ensure integrity of the data, I want a small envelope protocol around each protobuf message. I thought about the following:
message type (1 byte)
message size (2 bytes)
protobuf message (N bytes)
(checksum; optional)
The message type will mostly be a mapping between messages defined in proto files. However, if a message gets corrupted or some bytes are lost, the message size will not be correct and all subsequent bytes cannot be interpreted anymore. One way to solve this would be the introduction of limiters between messages, but for that I need to choose something that is not used by protobuf. Is there a byte sequence that is never used by any protobuf message?
I also thought about a different way. If the master finds out that packages are corrupted, it should reset the communication to a clean start. For that I want the master to send a RESTART command to the slave. The slave should answer with an ACK and then start sending complete messages again. All bytes received between RESTART and ACK are to be discarded by the master. I want to encode ACK and RESTART as special messages. But with that approach I face the same problem: I need to find byte sequences for ACK and RESTART that are not used by any protobuf messages.
Maybe I am also taking the wrong approach - feel free to suggest other approaches to deal with lost bytes.
Is there a byte sequence that is never used by any protobuf message?
No; it is a binary serializer and can contain arbitrary binary payloads (especially in the bytes type). You cannot use sentinel values. Length prefix is fine (your "message size" header), and a checksum may be a pragmatic option. Alternatively, you could impose an artificial sentinel to follow each message (maybe a guid chosen per-connection as part of the initial handshake), and use that to double-check that everything looks correct.
One way to help recover packet synchronization after a rare problem is to use synchronization words in the beginning of the message, and use the checksum to check for valid messages.
This means that you put a constant value, e.g. 0x12345678, before your message type field. Then if a message fails checksum check, you can recover by finding the next 0x12345678 in your data.
Even though that value could sometimes occur in the middle of the message, it doesn't matter much. The checksum check will very probably catch that there isn't a real message at that position, and you can search forwards until you find the next marker.
I have a driver that builds on the new serdev bus in the linux kernel.
In my driver I receive messages from an external device, all messages ends with a null byte (0x00) and the protocol ensures that there are no null bytes in my data (COBS). Now I try to have the TTY layer hand me full messages by scanning for zeros in my input and if there are none I'll just return zero in the callback that is called from the tty layer when bytes are available.
This kind of works. Or rather it works for some messages. After a while though it locks up and the tty layer keeps sending the same size of received bytes indefinitely. My guess is that this happens when one half of the tty flip buffer is full and the rest of my message is in the other half.
I have two questions:
Am I correct in that the tty layer can "hang" until I read out all data in one half of the flip buffer?
If that is so, is there some way to prevent this from happening? I'd rather not implement my own buffering scheme on top of the tty buffer already available.
Thanks
It looks like (drivers/tty/tty_buffer.c and the function flush_to_ldisc) that it is not possible to do what I attempted to do. When the tty buffer is about to flip over the consumer will have to do a read and buffer any half messages.
That is, returning zero and hoping for a larger chunk of data in your callback next time will only work up until the end of the first part of the buffer then the last bit of data must be read.
This is not a problem in userspace because a read call will have an argument that is the most bytes you want but read is free to return fewer bytes than requested.
Does anyone know what 2 parameters in the fetchMaxBytes represent?
If its represented as 1024*1024, does that mean that the consumer will fetch 1024 messages of each 1Kb? Or will it jest fetch 1Mb of messages?
I was not able to find any relevant information from the documentation except this: "The maximum bytes to include in the message set for this partition. This helps bound the size of the response."
I need this parameter to get messages one by one rather than getting a couple of messages in a single shot.
I am not familiar with node.js but I assume fetchMaxBytes corresponds to replicate.fetch.max.bytes. For this case, the value is the maximum buffer size (in bytes, ie, 1024*1024 = 1MB) for fetching messages. A buffer can contain multiple messages of arbitrary size. It basically means, wait for fetching not longer as "until a buffer got filled up".
When incoming data arrives on a TTY with a line discipline, the line discipline callback receive_buf2() is invoked to process the data. This function is meant to return the number of bytes it actually consumed. If it does not consume them all, then when will the callback be invoked again? For example, will it only be invoked again when additional incoming data is received?
I know this answer is a little late, but here it is:
According to the Kernel documentation found at https://www.kernel.org/doc/Documentation/serial/tty.txt
Driver Side Interfaces :
receive_buf() - (optional)Called by the low - level driver to hand
a buffer of received bytes to the ldisc for
processing.The number of bytes is guaranteed not
to exceed the current value of tty->receive_room.
**All bytes must be processed.**
All bytes from receive_buf() must be processed.