示例#1
0
        private void OnReceive(IAsyncResult result)
        {
            SocketState state = result.AsyncState as SocketState;

            if (state == null)
            {
                Tracer.Warn("Socket state was null.");
                return;
            }

            try
            {
                Socket socket = state.Socket;
                if (socket.Connected == false)
                {
                    Disconnect();
                    return;
                }
                int length = socket.EndReceive(result);

                if (length > 0)
                {
                    byte[] buffer = state.Buffer;

                    if (m_ReceiveBuffer == null)
                    {
                        m_ReceiveBuffer = new byte[0x10000];
                    }

                    if (m_IsDecompressionEnabled)
                    {
                        int    outsize = 0;
                        byte[] data;

                        if (m_AppendNextMessage)
                        {
                            m_AppendNextMessage = false;
                            data = new byte[m_AppendData.Length + length];

                            Buffer.BlockCopy(m_AppendData, 0, data, 0, m_AppendData.Length);
                            Buffer.BlockCopy(buffer, 0, data, m_AppendData.Length, length);
                        }
                        else
                        {
                            data = new byte[length];
                            Buffer.BlockCopy(buffer, 0, data, 0, length);
                        }

                        while (m_Decompression.DecompressOnePacket(ref data, data.Length, ref m_ReceiveBuffer, ref outsize))
                        {
                            int                  realLength;
                            PacketHandler        packetHandler;
                            List <PacketHandler> packetHandlers = GetHandlers(m_ReceiveBuffer[0], m_ReceiveBuffer[1]);

                            if (!GetPacketSizeAndHandler(packetHandlers, outsize, out realLength, out packetHandler))
                            {
                                Tracer.Warn("Unhandled packet with id: 0x{0:x2}, possible subid: 0x{1:x2}", m_ReceiveBuffer[0], m_ReceiveBuffer[1]);
                                m_ReceiveBufferPosition = 0;
                                break;
                            }

                            if (realLength != outsize)
                            {
                                throw new Exception("Bad packet size!");
                            }

                            byte[] packetBuffer = new byte[realLength];
                            Buffer.BlockCopy(m_ReceiveBuffer, 0, packetBuffer, 0, realLength);

                            string name = packetHandler.Name;
                            AddPacket(name, packetHandler, packetBuffer, realLength);
                        }

                        // We've run out of data to parse, or the packet was incomplete. If the packet was incomplete,
                        // we should save what's left for socket receive event.
                        if (data.Length > 0)
                        {
                            m_AppendNextMessage = true;
                            m_AppendData        = data;
                        }
                    }
                    else
                    {
                        Buffer.BlockCopy(buffer, 0, m_ReceiveBuffer, m_ReceiveBufferPosition, length);

                        m_ReceiveBufferPosition += length;

                        int currentIndex = 0;

                        while (currentIndex < m_ReceiveBufferPosition)
                        {
                            int                  realLength;
                            PacketHandler        packetHandler;
                            List <PacketHandler> packetHandlers = GetHandlers(m_ReceiveBuffer[currentIndex], m_ReceiveBuffer[currentIndex + 1]);

                            if (!GetPacketSizeAndHandler(packetHandlers, -1, out realLength, out packetHandler))
                            {
                                currentIndex            = 0;
                                m_ReceiveBufferPosition = 0;
                                break;
                            }

                            if ((m_ReceiveBufferPosition - currentIndex) >= realLength)
                            {
                                byte[] packetBuffer = new byte[realLength];
                                Buffer.BlockCopy(m_ReceiveBuffer, currentIndex, packetBuffer, 0, realLength);

                                string name = packetHandler.Name;
                                AddPacket(name, packetHandler, packetBuffer, realLength);

                                currentIndex += realLength;
                            }
                            else
                            {
                                //Need more data
                                break;
                            }
                        }

                        m_ReceiveBufferPosition -= currentIndex;

                        if (m_ReceiveBufferPosition > 0)
                        {
                            Buffer.BlockCopy(m_ReceiveBuffer, currentIndex, m_ReceiveBuffer, 0, m_ReceiveBufferPosition);
                        }
                    }
                }

                if (m_ServerSocket != null)
                {
                    m_ServerSocket.BeginReceive(state.Buffer, 0, state.Buffer.Length, SocketFlags.None, OnReceive, state);
                }
            }
            catch (Exception e)
            {
                Tracer.Debug(e.ToString());
                Disconnect();
            }
        }
示例#2
0
        public bool Connect(string ipAddressOrHostName, int port)
        {
            lock (m_SyncRoot)
            {
                m_WorkingQueue.Clear();
            }

            m_IncompletePacket.Clear();
            m_IncompleteDecompressionPacket.Clear();

            if (IsConnected)
            {
                Disconnect();
            }

            bool success = true;

            try
            {
                if (!IPAddress.TryParse(ipAddressOrHostName, out m_ServerAddress))
                {
                    IPAddress[] ipAddresses = Dns.GetHostAddresses(ipAddressOrHostName);

                    if (ipAddresses.Length == 0)
                    {
                        throw new NetworkException("Host address was unreachable or invalid, unable to obtain an ip address.");
                    }

                    // On Vista and later, the first ip address is an empty one '::1'.
                    // This makes sure we choose the first valid ip address.
                    foreach (IPAddress address in ipAddresses)
                    {
                        if (address.ToString().Length <= 7)
                        {
                            continue;
                        }

                        m_ServerAddress = address;
                        break;
                    }
                }

                m_ServerEndPoint = new IPEndPoint(m_ServerAddress, port);

                Tracer.Debug("Connecting to {0}:{1}...", m_ServerAddress, port);

                m_ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                m_ServerSocket.Connect(m_ServerEndPoint);

                if (m_ServerSocket.Connected)
                {
                    Tracer.Debug("Connected.");
                    SocketState state = new SocketState(m_ServerSocket, m_BufferPool.AcquireBuffer());
                    m_ServerSocket.BeginReceive(state.Buffer, 0, state.Buffer.Length, SocketFlags.None, OnReceive, state);
                }
            }
            catch
            {
                success = false;
            }

            m_IsConnected = success;
            return(success);
        }
示例#3
0
        public bool Connect(string ipAddressOrHostName, int port)
        {
            m_QueuedPackets.Clear();
            if (m_ReceiveBuffer != null)
            {
                Array.Clear(m_ReceiveBuffer, 0, m_ReceiveBuffer.Length);
            }
            m_ReceiveBufferPosition = 0;
            m_AppendNextMessage     = false;

            if (IsConnected)
            {
                Disconnect();
            }

            bool success = true;

            try
            {
                if (!IPAddress.TryParse(ipAddressOrHostName, out m_ServerAddress))
                {
                    IPAddress[] ipAddresses = Dns.GetHostAddresses(ipAddressOrHostName);

                    if (ipAddresses.Length == 0)
                    {
                        throw new NetworkException("Host address was unreachable or invalid, unable to obtain an ip address.");
                    }

                    // On Vista and later, the first ip address is an empty one '::1'.
                    // This makes sure we choose the first valid ip address.
                    foreach (IPAddress address in ipAddresses)
                    {
                        if (address.ToString().Length <= 7)
                        {
                            continue;
                        }

                        m_ServerAddress = address;
                        break;
                    }
                }

                m_ServerEndPoint = new IPEndPoint(m_ServerAddress, port);

                Tracer.Debug("Connecting...");

                m_ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                m_ServerSocket.Connect(m_ServerEndPoint);

                if (m_ServerSocket.Connected)
                {
                    Tracer.Debug("Connected.");

                    SocketState state = new SocketState(m_ServerSocket, ushort.MaxValue);
                    m_ServerSocket.BeginReceive(state.Buffer, 0, state.Buffer.Length, SocketFlags.None, OnReceive, state);
                }
            }
            catch
            {
                success = false;
            }

            m_IsConnected = success;
            return(success);
        }