public void DisconnectPeer(SocketPeer peer)
        {
            lock (peerLock)
            {
                if (_peers.Contains(peer))
                {
                    _peers.Remove(peer);
                }

                peer.Dispose();
            }
        }
        private void FreeUpPiece(SocketPeer peer)
        {
            lock (_pieceLock)
            {
                var piecePeers = _pendingPieces.Where(p => p.Value == peer);
                if (piecePeers.Any())
                {
                    var piecePeerPair = piecePeers.First();
                    _pendingPieces.Remove(piecePeerPair.Key);

                    peer.PieceRequestComplete();
                }
            }
        }
        public bool TryConnectToPeer(Peer peer, EventHandler <PeerEventArgs> eventHandler = null)
        {
            lock (peerLock)
            {
                if (IsPeerConnected(peer))
                {
                    return(false);
                }

                if (_peers.Count + PendingPeers.Count >= Constants.MaxPeers)
                {
                    return(false);
                }

                PendingPeers.Add(peer);
            }

            if (!TcpSocketHelper.TryEstablishConnection(peer.Ip, peer.Port, out Socket socket))
            {
                lock (peerLock)
                {
                    PendingPeers.Remove(peer);
                    return(false);
                }
            }

            var socketPeer = new SocketPeer(PeerEventDataFactory, peer, socket, TorrentInfo, PeerId);

            if (!socketPeer.TryInitiateHandsake())
            {
                PendingPeers.Remove(peer);
                DisconnectPeer(socketPeer);
                return(false);
            }

            socketPeer.PeerEventHandler += OnPeerEvent;
            socketPeer.PeerEventHandler += eventHandler;
            lock (peerLock)
            {
                _peers.Add(socketPeer);
                PendingPeers.Remove(peer);
            }

            socketPeer.StartReceive();

            return(true);
        }