Beispiel #1
0
        private int _AddClient(BaseClient h)
        {
            lock (_chs_sync)
                for (int i = 0; i < _chs.Length; i++)   //  Even with 100,000 clients, this loop won't be an issue.
                    if (_chs[i] == null)
                    {
                        h.Disconnected += h_Disconnected;
                        h.ConnectionFailed += h_ConnectionFailed;
                        //  I gotta subscribe to the event here (unfortunately, inside a lock) so it won't get added twice. This is the only code block guaranteed to run just once when this function is called.

                        if (_peering)
                            for (int j = 0; j < _chs.Length; j++)
                                if (_chs[j] != null)
                                    _chs[j].GivePeer(i);

                        _chs[i] = h;

                        return h._id = i;
                        //  I love assignment as expression!
                    }

            //  If a suitable position wasn't found...

            _DoubleClientContainer();

            return _AddClient(h);
        }
Beispiel #2
0
        private void _handleHandshakeRequest(BaseClient sender, RequestReceivedEventArgs e)
        {
            if (handshakeStep == 0)
                using (var br = new BinaryReader(e.Response.RequestPayloadStream, Encoding.UTF8))
                {
                    int vma = br.ReadInt32();
                    int vmi = br.ReadInt32();

                    if (ProtocolVersion.Major != vma || ProtocolVersion.Minor != vmi)
                        _CheckIfStopped(new NotSupportedException("vProto Protocol Version mismatch."));
                    else
                    {
                        handshakeStep = 1;

                        using (var str = new MemoryStream())
                        using (BinaryWriter bw = new BinaryWriter(str, Encoding.UTF8))
                        {
                            bw.Write(ProtocolVersion.Major);
                            bw.Write(ProtocolVersion.Minor);

                            bw.Flush();

                            e.Response.SetPayload(str, SeekOrigin.Begin).Send();
                        }
                    }
                }
            else if (handshakeStep == 1)
                using (var br = new BinaryReader(e.Response.RequestPayloadStream, Encoding.UTF8))
                {
                    this._id = br.ReadInt32();

                    int peers_cnt = br.ReadInt32();
                    int[] peers = null;

                    if (peers_cnt != -1)
                    {
                        peers = new int[peers_cnt];

                        for (int i = peers_cnt - 1; i >= 0; i--)
                            peers[i] = br.ReadInt32();
                    }

                    lock (_peers_lock)
                    {
                        _peers = new List<int>(peers);

                        if (peers != null)
                            for (int i = 0; i < _peers_queued_temp.Count; i++)
                                if (!_peers.Contains(_peers_queued_temp[i]))
                                    _peers.Add(_peers_queued_temp[i]);

                        _peers_queued_temp = null;
                    }

                    _FinishHandhake();

                    e.Response.Send();
                }
        }
Beispiel #3
0
        private void _DoubleClientContainer()
        {
            lock (_chs_sync)
            {
                BaseClient[] n = new BaseClient[_chs.Length * 2];

                _chs.CopyTo(n, 0);
                //  Indices need to be preserved...

                _chs = n;
            }
        }
Beispiel #4
0
        private void _RemoveClient(BaseClient h)
        {
            lock (_chs_sync)
                if (h._id > -1 && h._id < _chs.Length)
                {
                    _chs[h._id] = null;

                    if (_peering)
                        for (int j = 0; j < _chs.Length; j++)
                            if (_chs[j] != null)
                                _chs[j].TakePeer(h._id);
                }
                // else what the heck is going on?
        }
        //  Only internally...
        internal Request(BaseClient cl, short id)
        {
            client = cl;
            this.id = id;

            Disposed = Sent = Aborted = TimedOut = Failed = Responded = false;
        }
Beispiel #6
0
        void h_ConnectionFailed(BaseClient sender, ClientConnectionFailedEventArgs e)
        {
            _RemoveClient(sender);

            OnClientConnectionFailed(new ServerClientConnectionFailedEventArgs(e.Exception));
        }
Beispiel #7
0
        /* Events from clients...
         */



        void h_Disconnected(BaseClient sender, ClientDisconnectedEventArgs e)
        {
            _RemoveClient(sender);

            OnClientDisconnected(new ServerClientDisconnectedEventArgs(sender, e.Exception));
        }
Beispiel #8
0
        /// <summary>
        /// Integrates a new client into the server and raises appropriate events.
        /// </summary>
        /// <param name="client">The client to integrate.</param>
        protected void ClientReceived(BaseClient client)
        {
            _AddClient(client);

            OnClientConnected(new ServerClientConnectedEventArgs(client));
        }
        //  Only internally...
        internal Response(BaseClient cl, short id, short type, byte[] reqpayload, TimeSpan timeout, DateTime receivalTime)
        {
            client = cl;
            this.id = id;
            this.Type = type;

            Timeout = timeout;
            TimeRquested = receivalTime;
            TimeDue = receivalTime + timeout;

            reqarr = reqpayload;
            reqstr = new MemoryStream(reqpayload);

            Disposed = Sent = Aborted = TimedOut = Failed = false;
        }