예제 #1
0
        /// <summary>
        /// Delegate for asynchronously receiving UDP packets
        /// </summary>
        private void onDataRecieved(IAsyncResult asyn)
        {       //If we're not operating, abort.
            if (!_bOperating)
            {
                return;
            }

            //Use the logger
            using (LogAssume.Assume(_logger))
            {
                PacketBase packet = null;
                byte[]     data   = null;

                try
                {       //Sanity checks
                    if (!asyn.IsCompleted)
                    {   //Abort
                        Log.write(TLog.Warning, "Asynchronous socket operation not completed.");
                        return;
                    }

                    //Receive the data
                    data = _udp.EndReceive(asyn, ref _remEP);
                    int dataLen = data.Length;
                    int offset  = 0;

                    //Read in the typeID
                    ushort typeID = NetworkClient.getTypeID(data, 0);

                    //If our client is inactive, ignore this packet
                    if (!_client._bDestroyed)
                    {   //Make sure the packet is intact
                        if (!_client.checkPacket(data, ref offset, ref dataLen))
                        {
                            //Bad packet!
                            Log.write(TLog.Warning, "Bad packet received from server.");
                        }
                        else
                        {       //Transplant the data into a packet class
                            packet          = _factory.createPacket(_client, typeID, data, offset, dataLen);
                            packet._client  = _client;
                            packet._handler = this;

                            packet.Deserialize();

                            //Queue it up
                            handlePacket(packet, _client);
                            _client._lastPacketRecv = Environment.TickCount;
                        }
                    }
                }
                catch (ObjectDisposedException)
                {       //Socket was closed
                    Log.write(TLog.Inane, "Socket closed.");
                    _bOperating = false;
                    return;
                }
                catch (SocketException se)
                {       //Store the exception and exit
                    if (se.ErrorCode == 10054)
                    {
                        Log.write(TLog.Warning, "Connection to database refused.");
                    }
                    else
                    {
                        Log.write(TLog.Exception, "Socket exception[{0}]:\r\n{1}", se.ErrorCode, se.ToString());
                    }
                    _bOperating = false;
                    return;
                }
                catch (Exception ex)
                {       //Store the exception and exit
                    Log.write(TLog.Exception, "Exception on recieving data:\r\n{0}", ex.ToString());
                    if (packet != null)
                    {
                        Log.write(TLog.Inane, "Packet data:\r\n{0}", packet.DataDump);
                    }
                    else if (data != null)
                    {
                        Log.write(TLog.Inane, "Packet data:\r\n{0}", PacketBase.createDataDump(data, 0, data.Length));
                    }
                }

                try
                {       //Wait for more data
                    if (_bOperating)
                    {
                        _udp.BeginReceive(onDataRecieved, null);
                    }
                }
                catch (SocketException se)
                {       //Store the exception and exit
                    Log.write(TLog.Exception, "Socket exception[{0}]:\r\n{1}", se.ErrorCode, se.ToString());
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Delegate for asynchronously receiving UDP packets
        /// </summary>
        private void onDataRecieved(IAsyncResult asyn)
        {               //Use the logger
            using (LogAssume.Assume(_logger))
            {
                PacketBase packet = null;
                int        read   = 0;

                try
                {                       //Sanity checks
                    if (!asyn.IsCompleted)
                    {                   //Abort
                        Log.write(TLog.Warning, "Asynchronous socket operation not completed.");
                        return;
                    }

                    //Receive the data
                    read = _sock.EndReceiveFrom(asyn, ref _remEP);

                    //Read in the typeID
                    ushort typeID = NetworkClient.getTypeID(_buffer, 0);

                    //Handle the initial packet specially
                    bool bNewClient = false;

                    //Initial && system packet?
                    if (_buffer[0] == 0 && typeID == Protocol.CS_Initial.TypeID)
                    {                           //If we're receiving the initial packet, then the client will
                                                //want to begin a new connection state. Destroy the old one!
                                                //Protocol.CS_Initial init = packet as Protocol.CS_Initial;
                        bNewClient = true;
                    }

                    //Attempt to find the related NetworkClient
                    _networkLock.AcquireWriterLock(Timeout.Infinite);
                    NetworkClient client = null;

                    try
                    {                           //Form the uid for the client
                        IPEndPoint ipe = (IPEndPoint)_remEP;
                        Int64      id  = ipe.Address.Address | (((Int64)ipe.Port) << 32);

                        //Do we have a client?
                        if (bNewClient)
                        {                               //This client doesn't exist yet, let's create a new class
                            client = _clientTemplate.newInstance();
                            client._lastPacketRecv = Environment.TickCount;
                            client._ipe            = ipe;
                            client._handler        = this;

                            //Add it to our client list
                            _clients[id] = client;
                        }
                        else
                        {
                            _clients.TryGetValue(id, out client);
                        }

                        //Out of sync packet?
                        if (client == null)
                        {
                            Log.write(TLog.Inane, "Out of state packet received from {0}", _remEP);
                        }
                        //If the client is inactive, ignore
                        else if (client._bDestroyed)
                        {
                            client = null;
                        }
                    }
                    finally
                    {                           //Release our lock
                        _networkLock.ReleaseWriterLock();
                    }

                    if (client != null)
                    {                           //Make sure the packet is intact
                        int offset = 0;
                        if (!client.checkPacket(_buffer, ref offset, ref read))
                        {
                            //Bad packet!
                            Log.write(TLog.Warning, "Bad packet received from {0}", client);
                        }
                        else
                        {                               //Transplant the data into a packet class
                            packet          = _factory.createPacket(client, typeID, _buffer, offset, read);
                            packet._client  = client;
                            packet._handler = this;

                            packet.Deserialize();

                            //Queue it up
                            handlePacket(packet, client);
                            client._lastPacketRecv = Environment.TickCount;
                        }
                    }
                }
                catch (ObjectDisposedException)
                {                       //Socket was closed
                    Log.write(TLog.Inane, "Socket closed.");
                    _bOperating = false;
                    return;
                }
                catch (SocketException se)
                {                       //Store the exception and exit
                    Log.write(TLog.Exception, "Socket exception[{0}]:\r\n{1}", se.ErrorCode, se.ToString());
                }
                catch (Exception ex)
                {                       //Store the exception and exit
                    Log.write(TLog.Exception, "Exception on recieving data:\r\n{0}", ex.ToString());
                    if (packet != null)
                    {
                        Log.write(TLog.Inane, "Packet data:\r\n{0}", packet.DataDump);
                    }
                    else
                    {
                        Log.write(TLog.Inane, "Packet data:\r\n{0}", PacketBase.createDataDump(_buffer, 0, read));
                    }
                }

                try
                {                       //Wait for more data
                    _sock.BeginReceiveFrom(_buffer, 0, _buffer.Length, SocketFlags.None, ref _remEP, onDataRecieved, null);
                }
                catch (SocketException se)
                {                       //Store the exception and exit
                    Log.write(TLog.Exception, "Socket exception[{0}]:\r\n{1}", se.ErrorCode, se.ToString());
                }
            }
        }