The size of the next datagram queue is UDP

I use the System.Net.Sockets Socket class to get UDP datagrams. I wanted to know the exact length of the datagram obtained to verify the validity of the datagram.

Socket.Receive(Byte()) method documentation says:

If you are using a socket without establishing a connection, Receive will read the first datagram from the destination address specified in the Connect method. If the received datagram is larger than the size of the buffer parameter, the buffer is filled with the first part of the message, redundant data is lost and a SocketException is thrown.

Socket.Available property gives the total number of bytes available for reading. This sums the size of all queued datagrams.

Is there any way to know the size of the next datagram?

 public static void Receive() { Byte[] buf, discardbuf; const int paklen = 32; //correct packet length int l; buf = new Byte[paklen]; discardbuf = new Byte[4096]; while (rcv_enable) { l = soc.Available; if (l == 0) continue; if (l == paklen) soc.Receive(buf); //receive the correct packet else soc.Receive(discardbuf); //discard otherwise Thread.Sleep(200); Console.WriteLine("Received {0}", l); }; } 
+6
source share
2 answers

I'm going to assume that you have developed your own protocol and expect datagrams with a predetermined size, and you want to protect yourself from rogue packets.

Since performance seems like a problem and you want to avoid exceptions, I would look at receiver overload , which returns unhandled instead of exception errors. The MSDN documentation (wrong?) States that this method will throw an exception as well, but I don't think so. It is 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 predetermined size and use overload to check the SocketError error code to determine if the reading was interrupted or if you deleted the package.

If, however, your own protocol can send datagrams of unknown sizes to the maximum datagram size limit, you have no choice but to allocate a buffer large enough for the maximum packet (65k) (you can use a buffer pool to avoid memory problems depending on your code).

Also check out the SocketFlags enumeration , it contains some elements that may interest you, such as Partial and Peek members.

+3
source

Why not just check the return value from Receive ? im sure that each call will return one datagram.

+2
source

Source: https://habr.com/ru/post/903527/


All Articles