/// <summary>
 /// Sends UDP packet.
 /// </summary>
 /// <param name="packet">Packet to send.</param>
 /// <param name="remoteEndPoint">Address of destination for packet. It can be broadcast address.</param>
 /// <exception cref="System.ArgumentNullException">Packet is null. -or- Remote IP end point is null.</exception>
 public static void Send(TinyPacket packet, IPEndPoint remoteEndPoint)
 {
     if (packet == null)
     {
         throw new ArgumentNullException("packet", "Packet is null.");
     }
     if (remoteEndPoint == null)
     {
         throw new ArgumentNullException("remoteEndPoint", "Remote IP end point is null.");
     }
     using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) {
         if (remoteEndPoint.Address == IPAddress.Broadcast)
         {
             socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
         }
         if (IsRunningOnMono == false)
         {
             socket.SetSocketOption(SocketOptionLevel.Udp, SocketOptionName.NoChecksum, false);
         }
         socket.SendTo(packet.GetBytes(), remoteEndPoint);
         Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "TinyMessage [{0} -> {1}]", packet, remoteEndPoint));
     }
 }
        /// <summary>
        /// Sends one UDP packet and expects another in return.
        /// Returns null if respose is not received within receiveTimeout.
        /// </summary>
        /// <param name="packet">Packet to send.</param>
        /// <param name="remoteEndPoint">Address of destination for packet. It can be broadcast address.</param>
        /// <param name="receiveTimeout">Number of milliseconds to wait for receive operation to be done. If number is zero, infinite timeout will be used.</param>
        /// <exception cref="System.ArgumentNullException">Packet is null. -or- Remote IP end point is null.</exception>
        public static TinyPacket SendAndReceive(TinyPacket packet, IPEndPoint remoteEndPoint, Int32 receiveTimeout)
        {
            if (packet == null)
            {
                throw new ArgumentNullException("packet", "Packet is null.");
            }
            if (remoteEndPoint == null)
            {
                throw new ArgumentNullException("remoteEndPoint", "Remote IP end point is null.");
            }
            using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) {
                socket.ReceiveTimeout = receiveTimeout;
                if (remoteEndPoint.Address == IPAddress.Broadcast)
                {
                    socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
                }
                if (IsRunningOnMono == false)
                {
                    socket.SetSocketOption(SocketOptionLevel.Udp, SocketOptionName.NoChecksum, false);
                }
                var bytesOut = packet.GetBytes();
                socket.SendTo(bytesOut, bytesOut.Length, SocketFlags.None, remoteEndPoint);
                Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "TinyMessage [{0} -> {1}]", packet, remoteEndPoint));

                EndPoint remoteEndPointIn = (EndPoint)(new IPEndPoint(IPAddress.Any, 0));
                var      bytesIn          = new byte[65536];
                try {
                    int len      = socket.ReceiveFrom(bytesIn, ref remoteEndPointIn);
                    var packetIn = Medo.Net.TinyPacket.Parse(bytesIn, 0, len);
                    Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "TinyMessage [{0} <- {1}]", packetIn, remoteEndPointIn));
                    return(packetIn);
                } catch (SocketException) {
                    return(null);
                }
            }
        }