How to Get Amount of Queued Data for Udp Socket

How do I get amount of queued data for UDP socket?

As ldx mentioned, it is not supported through ioctl or getsockopt.
It seems to me that the current implementation of SIOCINQ was aimed to determine how much buffer is needed to read the entire waiting buffer (but I guess it is not so useful for that, as it can change between the read of it to the actual buffer read).

There are many other telemetries which are not supported though such system calls, I guess there is no real need in normal production usage.

You can check the drops/errors through "netstat -su" , or better using SNMP (udpInErrors) if you just want to monitor the machine state.

BTW: You always have the option to hack in the Kernel code and add this value (or others).

size of the next queued datagram - UDP

I'm going to assume that you've developed your own protocol and are expecting datagrams of a pre-known size and you want to guard yourself against rogue packets.

Since performance seems to be an issue and you want to avoid exceptions I'd have a look at the overload of Receive which returns the raw socket error instead of throwing exceptions. The MSDN documentation does (incorrectly?) state that this method too will throw an exception but I don't think that is the case. It's definitely worth a try.

SocketError error;
byte[] buffer = new byte[512]; // Custom protocol max/fixed message size
int c = this.Receive(buffer, 0, buffer.Length, SocketFlags.None, out error);

if (error != SocketError.Success)
{
if(error == SocketError.MessageSize)
{
// The message was to large to fit in our buffer
}
}

Use a buffer of a pre-known sane size and use the overload to check the SocketError error code in order to determine whether or not the read succeeded or if you sholud drop the package.

If, however your own protocol can send datagrams of unknown sizes up to the limit of the maximum datagram size you have no choice other than allocating a buffer large enough to fit the largest packet (65k) (you could use buffer pooling to avoid memory issues depending on your code).

Also check out the SocketFlags enum, it contains some members which may be of interest to you such as the Partial and Peek members.

UDP - Read data from the queue in chunks

UDP does not allow for chunked reading like TCP does. Reading a UDP message is an all-or-nothing operation, you either read the whole message in full or none of it at all. There is no in-between. Because of that, UDP-based protocols either use fixed-sized messages, or require both parties to dynamically negotiate the message sizes (like TrivialFTP does, for example).

There is no reason for a UDP protocol to require sending a byte size for each message. The message size itself implicitly dictates the size of the data inside of the message.

If you absolutely must determine the message size before actually reading the message, you could try calling recvfrom() with the MSG_PEEK flag, and give it a large buffer to copy data into (at least 64K, which a UDP message will never exceed, unless you are using IPv6 Jumbograms, but that is a separate issue). The output will tell you the actual size of the message that is still in the queue. However, if you go this route, then you may as well just drop the MSG_PEEK flag and always read using 64K buffers so there is no possibility of dropping data due to insufficient buffer sizes.



Related Topics



Leave a reply



Submit