private void ReceivePackets(double now)
        {
            int networkResets    = 0;
            int connectionResets = 0;
            int availableData    = 0;

            try
            {
                for (;;)
                {
                    try
                    {
                        if (m_socket == null)
                        {
                            return;
                        }

                        availableData = m_socket.availableData;
                        if (availableData <= 0)
                        {
                            return;
                        }

                        m_receiveBuffer.Reset();

                        double localTimeRecv;
                        int    bytesReceived = m_socket.ReceivePacket(m_receiveBuffer.Data, 0, m_receiveBuffer.Data.Length, out m_senderRemote, out localTimeRecv);
                        if (bytesReceived <= 0)
                        {
                            continue;
                        }

                        m_statistics.CountPacketReceived(bytesReceived);
                        m_receiveBuffer.LengthBits = bytesReceived * 8;

                        var ipsender = (NetworkEndPoint)m_senderRemote;

                        if (localTimeRecv == 0)
                        {
                            localTimeRecv = NetTime.Now;
                        }

                        // lookup the endpoint (if we have a connection)
                        var sender = GetConnection(ipsender);
                        if (sender != null)
                        {
                            sender.m_statistics.CountPacketReceived(bytesReceived, localTimeRecv);
                            sender.m_lastPongReceived = localTimeRecv;                             // TODO: fulhack!
                        }

                        // try parsing the packet
                        try
                        {
                            // create messages from packet
                            while (m_receiveBuffer.PositionBits < m_receiveBuffer.LengthBits)
                            {
                                int beginPosition = m_receiveBuffer.PositionBits;

                                // read message header
                                var msg = CreateIncomingMessage();
                                msg.m_sender = sender;
                                if (!msg.ReadFrom(m_receiveBuffer, ipsender))
                                {
                                    break;
                                }

                                // statistics
                                if (sender != null)
                                {
                                    sender.m_statistics.CountMessageReceived(msg.m_type, msg.m_sequenceChannel, (m_receiveBuffer.PositionBits - beginPosition) / 8, now);
                                }

                                // handle message
                                HandleReceivedMessage(msg, ipsender, localTimeRecv);
                            }
                        }
                        catch (Exception e)                         // silent exception handlers make debugging impossible, comment out when you wonder "WTF is happening???"
                        {
                            // TODO: fix so logging doesn't allocate an argument array (for using params object[]).
                            // Enabling us to hopefully do to log calls without overhead, if the log level isn't on.

#if DEBUG // NOTE: in production it might not be desirable to log bad packets, because of targeted DoS attacks.
                            Log.Error(LogFlags.Socket, "Failed parsing an incoming packet from ", ipsender, ": ", e);
#endif
                        }
                    }
                    catch (SocketException sex)
                    {
                        if (sex.ErrorCode == 10040 || sex.SocketErrorCode == SocketError.MessageSize)
                        {
                            int bufferSize = m_receiveBuffer.Data.Length;
                            Log.Error(LogFlags.Socket, "Failed to read available data (", availableData, " bytes) because it's larger than the receive buffer (", bufferSize, " bytes). This might indicate that the socket receive buffer size is not correctly configured: ", sex);
                        }

                        if (sex.ErrorCode == 10052 || sex.SocketErrorCode == SocketError.NetworkReset)
                        {
                            networkResets++;
                            if (networkResets > 2000)
                            {
                                break;
                            }
                        }
                        else if (sex.ErrorCode == 10054 || sex.SocketErrorCode == SocketError.ConnectionReset)
                        {
                            connectionResets++;
                            if (connectionResets > 2000)
                            {
                                break;
                            }
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
            }
            catch (SocketException sex)
            {
                if (sex.ErrorCode == 10035 || sex.SocketErrorCode == SocketError.WouldBlock)
                {
                    // NOTE: add independent ability to log warnings instead of this hack.
                    Log.Warning(LogFlags.Socket, "Receive Buffer is empty, ignore error: ", sex.Message);

                    return;
                }

                throw new NetException(NetTime.Now + " (" + DateTime.Now + "): Could not receive packet", sex);
            }
            catch (Exception ex)
            {
                throw new NetException(NetTime.Now + " (" + DateTime.Now + "): Could not receive packet", ex);
            }
            finally
            {
                if (networkResets > 0)
                {
                    Log.Debug(LogFlags.Socket, NetTime.Now, " (", DateTime.Now, "): Ignored number of socket network reset errors: ", networkResets);
                }

                if (connectionResets > 0)
                {
                    Log.Debug(LogFlags.Socket, NetTime.Now, " (", DateTime.Now, "): Ignored number of socket connection reset errors: ", connectionResets);
                }
            }
        }