internal SSPError SendUdpMessage(IMessage message, UdpPAcketId packetId)
 {
     lock (UdpHandle)
     {
         PayloadWriter pw = new PayloadWriter();
         pw.WriteDecimal(this.ClientId);
         pw.WriteByte((byte)packetId);
         pw.WriteUInteger(Connection.messageHandler.GetMessageId(message.GetType()));
         message.WritePacket(message, ref pw);
         this.UdpHandle.SendTo(pw.GetBuffer(), 0, pw.Length, SocketFlags.None, this.UdpEndPoint);
         return(SSPError.ErrorSuccess);
     }
 }
        internal unsafe void AsyncSocketCallback(object o, SocketAsyncEventArgs e)
        {
            if (e.LastOperation == SocketAsyncOperation.ReceiveFrom)
            {
                try
                {
                    if (e.BytesTransferred >= 21)
                    {
                        if (!Connected)
                        {
                            return; //TCP Client is disconnected so don't process UDP packets
                        }
                        //before we process the packet, does the IP/LocalPort match ?
                        if (UdpHandshaked && BitConverter.ToUInt32(this.UdpEndPoint.Address.GetAddressBytes(), 0) !=
                            BitConverter.ToUInt32(((IPEndPoint)e.RemoteEndPoint).Address.GetAddressBytes(), 0))
                        {
                            //simply skip and don't disconnect TCP
                            //I'll add later a option to the server to disconnect or not just for safety reasons ;)
                            return;
                        }

                        //decrypt traffic here
                        PayloadReader pr       = new PayloadReader(e.Buffer);
                        decimal       clientId = pr.ReadDecimal();

                        //extra check
                        if (this.ClientId != clientId)
                        {
                            return;
                        }

                        UdpPAcketId packetId  = (UdpPAcketId)pr.ReadByte();
                        uint        MessageId = pr.ReadUInteger();

                        IMessage message = null;
                        try
                        {
                            message = Connection.messageHandler.HandleUdpMessage(pr, MessageId);

                            if (message != null)
                            {
                                message.RawSize = e.BytesTransferred;
                            }
                        }
                        catch (Exception ex)
                        {
                            return;
                        }


                        //process packet
                        if (UdpHandshaked)
                        {
                            switch (packetId)
                            {
                            case UdpPAcketId.Payload:
                            {
                                //onReceiveUdpMessage(message);
                                break;
                            }
                            }
                        }
                        else
                        {
                            MsgUdpHandshake HandshakeMsg = message as MsgUdpHandshake;
                            if (HandshakeMsg != null)
                            {
                                fixed(byte *ptr = HandshakeMsg.HandshakeCode, ptr2 = this.UdpHandshakeCode)
                                {
                                    if (NativeMethods.memcmp(ptr, ptr2, (uint)this.UdpHandshakeCode.Length) == 0)
                                    {
                                        this.UdpEndPoint = e.RemoteEndPoint as IPEndPoint;
                                        Connection.SendPayload(new MsgUdpValidation(new byte[] { 0x8F, 0xFF, 0x46, 0x4F, 0x37 }), PacketId.Unknown);
                                        UdpHandshaked       = true;
                                        UdpSyncObject.Value = true;
                                        UdpSyncObject.Pulse();
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    onException(ex, ErrorType.Core);
                }

                if (PeerSide == SecureSocketProtocol2.PeerSide.Client)
                {
                    if (!UdpHandle.ReceiveFromAsync(UdpAsyncReceiveEvent))
                    {
                        AsyncSocketCallback(null, UdpAsyncReceiveEvent);
                    }
                }
            }
            else
            {
            }
        }