Пример #1
0
        //----------------------------------------------------------------------------------
        /// <summary>
        /// Overridden function to disconnect by mask index instead.
        /// </summary>
        /// <param name="nMaskIndex">index of peer to be kicked.</param>
        //----------------------------------------------------------------------------------
        public void DisconnectPeer(int nMaskIndex)
        {
            ClientConnectedInfo client = null;

            //Unfortunately we have to a linear search in order to find it this way.
            foreach (ClientConnectedInfo clientInfo in m_UdpClients.Values)
            {
                if (clientInfo.NetworkID == nMaskIndex)
                {
                    client = clientInfo;
                    break;
                }
            }

            if (client != null)
            {
                m_UdpClients.Remove(client.Address);
                client.Client.Close();

                lock (m_connectionLock)
                    m_ConnectedClientsMask &= ~nMaskIndex;

                if (ClientDisconnectedCallback != null)
                {
                    ClientDisconnectedCallback(nMaskIndex);
                }
            }
        }
Пример #2
0
        //----------------------------------------------------------------------------------
        /// <summary>
        /// Kick a peer of the network.
        /// </summary>
        /// <param name="address">address of peer to be kicked.</param>
        //----------------------------------------------------------------------------------
        public void DisconnectPeer(IPAddress address)
        {
            ClientConnectedInfo clientInfo = m_UdpClients[address];
            int nMaskIndex = clientInfo.NetworkID;

            //remove address from connections.
            m_UdpClients.Remove(address);
            clientInfo.Client.Close();

            //update connected mask.
            lock (m_connectionLock)
                m_ConnectedClientsMask &= ~nMaskIndex;

            //invoke callback to tell the local machine of event.
            if (ClientDisconnectedCallback != null)
            {
                ClientDisconnectedCallback(nMaskIndex);
            }
        }
Пример #3
0
        //----------------------------------------------------------------------------------
        /// <summary>
        /// Processes the send queue and send all queued packets for the network. NOTE: This is done on a seperate thread.
        /// </summary>
        /// <param name="queue"></param>
        //----------------------------------------------------------------------------------
        private void ProcessSendQueue(object queue)
        {
            lock (m_SendQueueLock)
            {
                if (m_OrderedSendQueue.Count > 0)
                {
                    while (m_OrderedSendQueue.Count > 0)
                    {
                        NetworkSendItem   item     = m_OrderedSendQueue.Dequeue();
                        NetworkDataPacket packet   = item.Packet;
                        IPEndPoint        endpoint = null;

                        //serialise the packet to be sent.
                        byte[] data = SerializePacket(packet);
                        int    nConnectionMask;
                        int    nCounter = 50;
                        int    nSpins   = 0;
                        m_AckClientsMask = 0;

                        if (item.IPAdress != null)
                        {
                            endpoint = new IPEndPoint(item.IPAdress, m_nUdpPort);
                        }

                        if (endpoint == null)
                        {
                            //send the packet to all connected clients.
                            foreach (ClientConnectedInfo clientInfo in m_UdpClients.Values)
                            {
                                clientInfo.Client.BeginSend(data,
                                                            data.Length,
                                                            SendCompleteCallback,
                                                            clientInfo.Client);
                            }

                            //We don't obtain a double nested lock on the AckMask as
                            //we want the thread to overwrite as necessary
                            lock (m_connectionLock)
                                nConnectionMask = m_ConnectedClientsMask;

                            //We hold execution here until all acks have come back.
                            while (0 != (m_AckClientsMask ^ nConnectionMask))
                            {
                                ++nSpins;

                                if (nSpins > nCounter)
                                {
                                    //if a certain amount of time passes and not all replies have come back.
                                    // disconnect that client.
                                    int nDisconnectionMask = m_ConnectedClientsMask ^ m_AckClientsMask;

                                    for (int i = 0; i < 32; ++i)
                                    {
                                        if (0 != (m_ConnectedClientsMask & i))
                                        {
                                            DisconnectPeer(i);
                                        }
                                    }
                                }

                                //We need to keep updating this every cycle to check if anything has changed.
                                lock (m_connectionLock)
                                    nConnectionMask = m_ConnectedClientsMask;
                            }
                        }
                        else
                        {
                            //This is if we are only sending an inorder packet to a single client.
                            ClientConnectedInfo clientInfo = m_UdpClients[endpoint.Address];

                            clientInfo.Client.BeginSend(data,
                                                        data.Length,
                                                        SendCompleteCallback,
                                                        clientInfo.Client);

                            //We hold execution here till we get a response..
                            //if we dont we assume the client has disconnected.
                            while (0 != (m_AckClientsMask & clientInfo.NetworkID))
                            {
                                ++nSpins;

                                if (nSpins > nCounter)
                                {
                                    DisconnectPeer(clientInfo.Address);
                                }
                            }
                        }
                    }
                }
            }
        }