Exemple #1
0
        /// <summary>
        /// Send a single, out-of-band unreliable message
        /// </summary>
        internal void DoSendOutOfBandMessage(NetBuffer data, IPEndPoint recipient)
        {
            m_sendBuffer.Reset();

            // message type and channel
            m_sendBuffer.Write((byte)((int)NetMessageLibraryType.OutOfBand | ((int)NetChannel.Unreliable << 3)));
            m_sendBuffer.Write((ushort)0);

            // payload length; variable byte encoded
            if (data == null)
            {
                m_sendBuffer.WriteVariableUInt32((uint)0);
            }
            else
            {
                int dataLen = data.LengthBytes;
                m_sendBuffer.WriteVariableUInt32((uint)(dataLen));
                m_sendBuffer.Write(data.Data, 0, dataLen);
            }

            SendPacket(recipient);

            // unreliable; we can recycle this immediately
            RecycleBuffer(data);
        }
        private void InitiateDisconnect()
        {
            if (m_requestSendGoodbye)
            {
                NetBuffer scratch = m_owner.m_scratchBuffer;
                scratch.Reset();
                scratch.Write(string.IsNullOrEmpty(m_futureDisconnectReason) ? "" : m_futureDisconnectReason);
                m_owner.SendSingleUnreliableSystemMessage(
                    NetSystemType.Disconnect,
                    scratch,
                    m_remoteEndPoint,
                    false
                    );
            }

            if (m_requestLinger <= 0)
            {
                SetStatus(NetConnectionStatus.Disconnected, m_futureDisconnectReason);
                FinalizeDisconnect();
                m_futureClose = double.MaxValue;
            }
            else
            {
                SetStatus(NetConnectionStatus.Disconnecting, m_futureDisconnectReason);
                m_futureClose = NetTime.Now + m_requestLinger;
            }

            m_requestDisconnect = false;
        }
        internal static void QueuePing(NetBase netBase, IPEndPoint toEndPoint, double now)
        {
            ushort    nowEnc = NetTime.Encoded(now);
            NetBuffer buffer = netBase.m_scratchBuffer;

            buffer.Reset();
            buffer.Write(nowEnc);
            netBase.QueueSingleUnreliableSystemMessage(
                NetSystemType.Ping,
                buffer,
                toEndPoint,
                false
                );
        }
Exemple #4
0
        /// <summary>
        /// Reads all packets and create messages
        /// </summary>
        protected void BaseHeartbeat(double now)
        {
            if (!m_isBound)
            {
                return;
            }

            // discovery
            m_discovery.Heartbeat(now);

            // hole punching
            if (m_holePunches != null)
            {
                if (now > m_lastHolePunch + NetConstants.HolePunchingFrequency)
                {
                    if (m_holePunches.Count <= 0)
                    {
                        m_holePunches = null;
                    }
                    else
                    {
                        IPEndPoint dest = m_holePunches[0];
                        m_holePunches.RemoveAt(0);
                        NotifyApplication(NetMessageType.DebugMessage, "Sending hole punch to " + dest, null);
                        NetConnection.SendPing(this, dest, now);
                        if (m_holePunches.Count < 1)
                        {
                            m_holePunches = null;
                        }
                        m_lastHolePunch = now;
                    }
                }
            }

            // Send queued system messages
            if (m_susmQueue.Count > 0)
            {
                lock (m_susmQueue)
                {
                    while (m_susmQueue.Count > 0)
                    {
                        SUSystemMessage su = m_susmQueue.Dequeue();
                        SendSingleUnreliableSystemMessage(su.Type, su.Data, su.Destination, su.UseBroadcast);
                    }
                }
            }

            // Send out-of-band messages
            if (m_unsentOutOfBandMessages.Count > 0)
            {
                lock (m_unsentOutOfBandMessages)
                {
                    while (m_unsentOutOfBandMessages.Count > 0)
                    {
                        NetBuffer  buf = m_unsentOutOfBandMessages.Dequeue();
                        IPEndPoint ep  = m_unsentOutOfBandRecipients.Dequeue();
                        DoSendOutOfBandMessage(buf, ep);
                    }
                }
            }

            try
            {
#if DEBUG
                SendDelayedPackets(now);
#endif

                while (true)
                {
                    if (m_socket == null || m_socket.Available < 1)
                    {
                        return;
                    }
                    m_receiveBuffer.Reset();

                    int bytesReceived = 0;
                    try
                    {
                        bytesReceived = m_socket.ReceiveFrom(m_receiveBuffer.Data, 0, m_receiveBuffer.Data.Length, SocketFlags.None, ref m_senderRemote);
                    }
                    catch (SocketException)
                    {
                        // no good response to this yet
                        return;
                    }
                    if (bytesReceived < 1)
                    {
                        return;
                    }
                    if (bytesReceived > 0)
                    {
                        m_statistics.CountPacketReceived(bytesReceived);
                    }
                    m_receiveBuffer.LengthBits = bytesReceived * 8;

                    //LogVerbose("Read packet: " + bytesReceived + " bytes");

                    IPEndPoint ipsender = (IPEndPoint)m_senderRemote;

                    NetConnection sender = GetConnection(ipsender);
                    if (sender != null)
                    {
                        sender.m_statistics.CountPacketReceived(bytesReceived, now);
                    }

                    // create messages from packet
                    while (m_receiveBuffer.Position < m_receiveBuffer.LengthBits)
                    {
                        int beginPosition = m_receiveBuffer.Position;

                        // read message header
                        IncomingNetMessage msg = CreateIncomingMessage();
                        msg.m_sender = sender;
                        msg.ReadFrom(m_receiveBuffer, ipsender);

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

                        // handle message
                        HandleReceivedMessage(msg, ipsender);
                    }
                }
            }
            catch (SocketException sex)
            {
                if (sex.ErrorCode == 10054)
                {
                    // forcibly closed; but m_senderRemote is unreliable, we can't trust it!
                    //NetConnection conn = GetConnection((IPEndPoint)m_senderRemote);
                    //HandleConnectionForciblyClosed(conn, sex);
                    return;
                }
            }
            catch (Exception ex)
            {
                throw new NetException("ReadPacket() exception", ex);
            }
        }
        internal void SendUnsentMessages(double now)
        {
            // Add any acknowledges to unsent messages
            if (m_acknowledgesToSend.Count > 0)
            {
                if (m_unsentMessages.Count < 1)
                {
                    // Wait before sending acknowledges?
                    if (m_ackMaxDelayTime > 0.0f)
                    {
                        if (m_ackWithholdingStarted == 0.0)
                        {
                            m_ackWithholdingStarted = now;
                        }
                        else
                        {
                            if (now - m_ackWithholdingStarted < m_ackMaxDelayTime)
                            {
                                return;                                 // don't send (only) acks just yet
                            }
                            // send acks "explicitly" ie. without any other message being sent
                            m_ackWithholdingStarted = 0.0;
                        }
                    }
                }

                // create ack messages and add to m_unsentMessages
                CreateAckMessages();
            }

            if (m_unsentMessages.Count < 1)
            {
                return;
            }

            // throttling
            float throttle     = m_owner.m_config.ThrottleBytesPerSecond;
            float maxSendBytes = float.MaxValue;

            if (throttle > 0)
            {
                double frameLength = now - m_lastSentUnsentMessages;

                //int wasDebt = (int)m_throttleDebt;
                if (m_throttleDebt > 0)
                {
                    m_throttleDebt -= (float)(frameLength * (double)m_owner.m_config.ThrottleBytesPerSecond);
                }
                //int nowDebt = (int)m_throttleDebt;
                //if (nowDebt != wasDebt)
                //	LogWrite("THROTTLE worked off -" + (nowDebt - wasDebt) + " bytes = " + m_throttleDebt);

                m_lastSentUnsentMessages = now;

                maxSendBytes = throttle - m_throttleDebt;
                if (maxSendBytes < 0)
                {
                    return;                     // throttling; no bytes allowed to be sent
                }
            }

            int  mtu           = m_owner.Configuration.MaximumTransmissionUnit;
            bool useCoalescing = m_owner.Configuration.UseMessageCoalescing;

            int       messagesInPacket = 0;
            NetBuffer sendBuffer       = m_owner.m_sendBuffer;

            sendBuffer.Reset();
            while (m_unsentMessages.Count > 0)
            {
                OutgoingNetMessage msg   = m_unsentMessages.Peek();
                int estimatedMessageSize = msg.m_data.LengthBytes + 5;

                // check if this message fits the throttle window
                if (estimatedMessageSize > maxSendBytes)                 // TODO: Allow at last one message if no debt
                {
                    break;
                }

                // need to send packet and start a new one?
                if (messagesInPacket > 0)
                {
                    if (!useCoalescing || (sendBuffer.LengthBytes + estimatedMessageSize > mtu))
                    {
                        m_owner.SendPacket(m_remoteEndPoint);
                        int sendLen = sendBuffer.LengthBytes;
                        m_statistics.CountPacketSent(sendLen);
                        //LogWrite("THROTTLE Send packet +" + sendLen + " bytes = " + m_throttleDebt + " (maxSendBytes " + maxSendBytes + " estimated " + estimatedMessageSize + ")");
                        m_throttleDebt += sendLen;
                        sendBuffer.Reset();
                    }
                }

                if (msg.m_sequenceNumber == -1)
                {
                    AssignSequenceNumber(msg);
                }

                // pop and encode message
                m_unsentMessages.Dequeue();
                int pre = sendBuffer.m_bitLength;
                msg.m_data.m_readPosition = 0;
                msg.Encode(sendBuffer);

                int encLen = (sendBuffer.m_bitLength - pre) / 8;
                m_statistics.CountMessageSent(msg, encLen);
                maxSendBytes -= encLen;

                if (msg.m_sequenceChannel >= NetChannel.ReliableUnordered)
                {
                    // reliable; store message (incl. buffer)
                    msg.m_numSent++;
                    StoreMessage(now, msg);
                }
                else
                {
                    // not reliable, don't store - recycle...
                    NetBuffer b = msg.m_data;
                    b.m_refCount--;

                    msg.m_data = null;

                    // ... unless someone else is using the buffer
                    if (b.m_refCount <= 0)
                    {
                        m_owner.RecycleBuffer(b);
                    }

                    //m_owner.m_messagePool.Push(msg);
                }
                messagesInPacket++;
            }

            // send current packet
            if (messagesInPacket > 0)
            {
                m_owner.SendPacket(m_remoteEndPoint);
                int sendLen = sendBuffer.LengthBytes;
                m_statistics.CountPacketSent(sendLen);
                //LogWrite("THROTTLE Send packet +" + sendLen + " bytes = " + m_throttleDebt);
                m_throttleDebt += sendLen;
            }
        }
Exemple #6
0
		static unsafe void Main(string[] args)
		{
			// JIT stuff
			NetBuffer msg = new NetBuffer(20);
			msg.Write((short)short.MaxValue);
			
			// Go
			double timeStart = NetTime.Now;

			msg = new NetBuffer(20);
			for (int n = 0; n < 10000; n++)
			{
				msg.Reset();

				msg.Write((short)short.MaxValue);
				msg.Write((short)short.MinValue);
				msg.Write((short)-42);

				msg.Write(421);
				msg.Write((byte)7);
				msg.Write(-42.8f);

				if (msg.LengthBytes != 15)
					throw new Exception("Bad message length");

				msg.Write("duke of earl");

				int bytesWritten;
				bytesWritten = msg.WriteVariableInt32(-1);
				bytesWritten = msg.WriteVariableInt32(5);
				bytesWritten = msg.WriteVariableInt32(-18);
				bytesWritten = msg.WriteVariableInt32(42);
				bytesWritten = msg.WriteVariableInt32(-420);

				msg.Write((uint)9991);

				// byte boundary kept until here

				msg.Write(true);
				msg.Write((uint)3, 5);
				msg.Write(8.111f);
				msg.Write("again");
				byte[] arr = new byte[] { 1, 6, 12, 24 };
				msg.Write(arr);
				msg.Write((byte)7, 7);
				msg.Write(Int32.MinValue);
				msg.Write(UInt32.MaxValue);
				msg.WriteRangedSingle(21.0f, -10, 50, 12);

				// test reduced bit signed writing
				msg.Write(15, 5);
				msg.Write(2, 5);
				msg.Write(0, 5);
				msg.Write(-1, 5);
				msg.Write(-2, 5);
				msg.Write(-15, 5);

				msg.Write(UInt64.MaxValue);
				msg.Write(Int64.MaxValue);
				msg.Write(Int64.MinValue);

				msg.Write(42);
				msg.WritePadBits();

				int numBits = msg.WriteRangedInteger(0, 10, 5);
				if (numBits != 4)
					throw new Exception("Ack WriteRangedInteger failed");

				// verify
				msg.Position = 0;

				short a = msg.ReadInt16();
				short b = msg.ReadInt16();
				short c = msg.ReadInt16();

				if (a != short.MaxValue || b != short.MinValue || c != -42)
					throw new Exception("Ack thpth short failed");

				if (msg.ReadInt32() != 421)
					throw new Exception("Ack thphth 1");
				if (msg.ReadByte() != (byte)7)
					throw new Exception("Ack thphth 2");
				if (msg.ReadSingle() != -42.8f)
					throw new Exception("Ack thphth 3");
				if (msg.ReadString() != "duke of earl")
					throw new Exception("Ack thphth 4");

				if (msg.ReadVariableInt32() != -1) throw new Exception("ReadVariableInt32 failed 1");
				if (msg.ReadVariableInt32() != 5) throw new Exception("ReadVariableInt32 failed 2");
				if (msg.ReadVariableInt32() != -18) throw new Exception("ReadVariableInt32 failed 3");
				if (msg.ReadVariableInt32() != 42) throw new Exception("ReadVariableInt32 failed 4");
				if (msg.ReadVariableInt32() != -420) throw new Exception("ReadVariableInt32 failed 5");

				if (msg.ReadUInt32() != 9991)
					throw new Exception("Ack thphth 4.5");

				if (msg.ReadBoolean() != true)
					throw new Exception("Ack thphth 5");
				if (msg.ReadUInt32(5) != (uint)3)
					throw new Exception("Ack thphth 6");
				if (msg.ReadSingle() != 8.111f)
					throw new Exception("Ack thphth 7");
				if (msg.ReadString() != "again")
					throw new Exception("Ack thphth 8");
				byte[] rrr = msg.ReadBytes(4);
				if (rrr[0] != arr[0] || rrr[1] != arr[1] || rrr[2] != arr[2] || rrr[3] != arr[3])
					throw new Exception("Ack thphth 9");
				if (msg.ReadByte(7) != 7)
					throw new Exception("Ack thphth 10");
				if (msg.ReadInt32() != Int32.MinValue)
					throw new Exception("Ack thphth 11");
				if (msg.ReadUInt32() != UInt32.MaxValue)
					throw new Exception("Ack thphth 12");

				float v = msg.ReadRangedSingle(-10, 50, 12);
				// v should be close to, but not necessarily exactly, 21.0f
				if ((float)Math.Abs(21.0f - v) > 0.1f)
					throw new Exception("Ack thphth *RangedSingle() failed");

				if (msg.ReadInt32(5) != 15)
					throw new Exception("Ack thphth ReadInt32 1");
				if (msg.ReadInt32(5) != 2)
					throw new Exception("Ack thphth ReadInt32 2");
				if (msg.ReadInt32(5) != 0)
					throw new Exception("Ack thphth ReadInt32 3");
				if (msg.ReadInt32(5) != -1)
					throw new Exception("Ack thphth ReadInt32 4");
				if (msg.ReadInt32(5) != -2)
					throw new Exception("Ack thphth ReadInt32 5");
				if (msg.ReadInt32(5) != -15)
					throw new Exception("Ack thphth ReadInt32 6");

				UInt64 longVal = msg.ReadUInt64();
				if (longVal != UInt64.MaxValue)
					throw new Exception("Ack thphth UInt64");
				if (msg.ReadInt64() != Int64.MaxValue)
					throw new Exception("Ack thphth Int64");
				if (msg.ReadInt64() != Int64.MinValue)
					throw new Exception("Ack thphth Int64");

				if (msg.ReadInt32() != 42)
					throw new Exception("Ack thphth end");

				msg.SkipPadBits();

				if (msg.ReadRangedInteger(0, 10) != 5)
					throw new Exception("Ack thphth ranged integer");
			}

			// test writevariableuint64
			NetBuffer largeBuffer = new NetBuffer(100 * 8);
			UInt64[] largeNumbers = new ulong[100];
			for (int i = 0; i < 100; i++)
			{
				largeNumbers[i] = ((ulong)NetRandom.Instance.NextUInt() << 32) | (ulong)NetRandom.Instance.NextUInt();
				largeBuffer.WriteVariableUInt64(largeNumbers[i]);
			}

			largeBuffer.Position = 0;
			for (int i = 0; i < 100; i++)
			{
				UInt64 ln = largeBuffer.ReadVariableUInt64();
				if (ln != largeNumbers[i])
					throw new Exception("large fail");
			}

			//
			// Extended tests on padbits
			//
			for (int i = 1; i < 31; i++)
			{
				NetBuffer buf = new NetBuffer();
				buf.Write((int)1, i);

				if (buf.LengthBits != i)
					throw new Exception("Bad length!");

				buf.WritePadBits();
				int wholeBytes = buf.LengthBits / 8;
				if (wholeBytes * 8 != buf.LengthBits)
					throw new Exception("WritePadBits failed! Length is " + buf.LengthBits);
			}

			NetBuffer small = new NetBuffer(100);
			byte[] rnd = new byte[24];
			int[] bits = new int[24];
			for (int i = 0; i < 24; i++)
			{
				rnd[i] = (byte)NetRandom.Instance.Next(0, 65);
				bits[i] = NetUtility.BitsToHoldUInt((uint)rnd[i]);

				small.Write(rnd[i], bits[i]);
			}

			small.Position = 0;
			for (int i = 0; i < 24; i++)
			{
				byte got = small.ReadByte(bits[i]);
				if (got != rnd[i])
					throw new Exception("Failed small allocation test");
			}

			double timeEnd = NetTime.Now;
			double timeSpan = timeEnd - timeStart;

			Console.WriteLine("Trivial tests passed in " + (timeSpan * 1000.0) + " milliseconds");

			Console.WriteLine("Creating client and server for live testing...");

			NetConfiguration config = new NetConfiguration("unittest");
			config.Port = 14242;
			NetServer server = new NetServer(config);
			NetBuffer serverBuffer = new NetBuffer();
			server.Start();

			config = new NetConfiguration("unittest");
			NetClient client = new NetClient(config);
			client.SetMessageTypeEnabled(NetMessageType.Receipt, true);
			NetBuffer clientBuffer = client.CreateBuffer();
			client.Start();

			client.Connect("127.0.0.1", 14242);

			List<string> events = new List<string>();

			double end = double.MaxValue;
			double disconnect = double.MaxValue;

			while (NetTime.Now < end)
			{
				double now = NetTime.Now;

				NetMessageType nmt;
				NetConnection sender;

				//
				// client
				//
				if (client.ReadMessage(clientBuffer, out nmt))
				{
					switch (nmt)
					{
						case NetMessageType.StatusChanged:
							Console.WriteLine("Client: " + client.Status + " (" + clientBuffer.ReadString() + ")");
							events.Add("CStatus " + client.Status);
							if (client.Status == NetConnectionStatus.Connected)
							{
								// send reliable message
								NetBuffer buf = client.CreateBuffer();
								buf.Write(true);
								buf.Write((int)52, 7);
								buf.Write("Hallon");

								client.SendMessage(buf, NetChannel.ReliableInOrder1, new NetBuffer("kokos"));
							}

							if (client.Status == NetConnectionStatus.Disconnected)
								end = NetTime.Now + 1.0; // end in one second

							break;
						case NetMessageType.Receipt:
							events.Add("CReceipt " + clientBuffer.ReadString());
							break;
						case NetMessageType.ConnectionRejected:
						case NetMessageType.BadMessageReceived:
							throw new Exception("Failed: " + nmt);
						case NetMessageType.DebugMessage:
							// silently ignore
							break;
						default:
							// ignore
							Console.WriteLine("Ignored: " + nmt);
							break;
					}
				}

				//
				// server
				//
				if (server.ReadMessage(serverBuffer, out nmt, out sender))
				{
					switch (nmt)
					{
						case NetMessageType.StatusChanged:
							events.Add("SStatus " + sender.Status);
							Console.WriteLine("Server: " + sender.Status + " (" + serverBuffer.ReadString() + ")");
							break;
						case NetMessageType.ConnectionRejected:
						case NetMessageType.BadMessageReceived:
							throw new Exception("Failed: " + nmt);
						case NetMessageType.Data:
							events.Add("DataRec " + serverBuffer.LengthBits);
							bool shouldBeTrue = serverBuffer.ReadBoolean();
							int shouldBeFifthTwo = serverBuffer.ReadInt32(7);
							string shouldBeHallon = serverBuffer.ReadString();

							if (shouldBeTrue != true ||
								shouldBeFifthTwo != 52 ||
								shouldBeHallon != "Hallon")
								throw new Exception("Bad data transmission");

							disconnect = now + 1.0;
							break;
						case NetMessageType.DebugMessage:
							// silently ignore
							break;
						default:
							// ignore
							Console.WriteLine("Ignored: " + nmt);
							break;
					}
				}

				if (now > disconnect)
				{
					server.Connections[0].Disconnect("Bye", 0.1f);
					disconnect = double.MaxValue;
				}
			}

			// verify events
			string[] expected = new string[] {
				"CStatus Connecting",
				"SStatus Connecting",
				"CStatus Connected",
				"SStatus Connected",
				"DataRec 64",
				"CReceipt kokos",
				"SStatus Disconnecting",
				"CStatus Disconnecting",
				"SStatus Disconnected",
				"CStatus Disconnected"
			};

			if (events.Count != expected.Length)
				throw new Exception("Mismatch in events count! Expected " + expected.Length + ", got " + events.Count);

			for(int i=0;i<expected.Length;i++)
			{
				if (events[i] != expected[i])
					throw new Exception("Event " + i + " (" + expected[i] + ") mismatched!");
			}

			Console.WriteLine("All tests successful");

			Console.ReadKey();

			server.Shutdown("App exiting");
			client.Shutdown("App exiting");
		}
        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);
                }
            }
        }
 internal NetBuffer GetTempBuffer()
 {
     m_tempBuffer.Reset();
     return(m_tempBuffer);
 }