⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 downloader.py

📁 一个多点下载且源码公开的P2P软件
💻 PY
📖 第 1 页 / 共 2 页
字号:
        if self.downloader.storage.am_I_complete() and have.complete():            if self.downloader.super_seeding:                self.connection.send_bitfield(have.tostring()) # be nice, show you're a seed too            self.connection.close()            self.downloader.add_disconnected_seed(self.connection.get_readable_id())            return False        self.have = have        if have.complete():            self.downloader.picker.got_seed()        else:            for i in xrange(len(have)):                if have[i]:                    self.downloader.picker.got_have(i)        if self.downloader.endgamemode and not self.downloader.paused:            for piece, begin, length in self.downloader.all_requests:                if self.have[piece]:                    self.send_interested()                    break        else:            self._check_interests()        return have.complete()    def get_rate(self):        return self.measure.get_rate()    def is_snubbed(self):        if ( self.interested and not self.choked             and clock() - self.last2 > self.downloader.snub_time ):            for index, begin, length in self.active_requests:                self.connection.send_cancel(index, begin, length)            self.got_choke()    # treat it just like a choke        return clock() - self.last > self.downloader.snub_timeclass Downloader:    def __init__(self, storage, picker, backlog, max_rate_period,                 numpieces, chunksize, measurefunc, snub_time,                 kickbans_ok, kickfunc, banfunc):        self.storage = storage        self.picker = picker        self.backlog = backlog        self.max_rate_period = max_rate_period        self.measurefunc = measurefunc        self.totalmeasure = Measure(max_rate_period*storage.piece_length/storage.request_size)        self.numpieces = numpieces        self.chunksize = chunksize        self.snub_time = snub_time        self.kickfunc = kickfunc        self.banfunc = banfunc        self.disconnectedseeds = {}        self.downloads = []        self.perip = {}        self.gotbaddata = {}        self.kicked = {}        self.banned = {}        self.kickbans_ok = kickbans_ok        self.kickbans_halted = False        self.super_seeding = False        self.endgamemode = False        self.endgame_queued_pieces = []        self.all_requests = []        self.discarded = 0L#        self.download_rate = 25000  # 25K/s test rate        self.download_rate = 0        self.bytes_requested = 0        self.last_time = clock()        self.queued_out = {}        self.requeueing = False        self.paused = False    def set_download_rate(self, rate):        self.download_rate = rate * 1000        self.bytes_requested = 0    def queue_limit(self):        if not self.download_rate:            return 10e10    # that's a big queue!        t = clock()        self.bytes_requested -= (t - self.last_time) * self.download_rate        self.last_time = t        if not self.requeueing and self.queued_out and self.bytes_requested < 0:            self.requeueing = True            q = self.queued_out.keys()            shuffle(q)            self.queued_out = {}            for d in q:                d._request_more()            self.requeueing = False        if -self.bytes_requested > 5*self.download_rate:            self.bytes_requested = -5*self.download_rate        return max(int(-self.bytes_requested/self.chunksize),0)    def chunk_requested(self, size):        self.bytes_requested += size    external_data_received = chunk_requested    def make_download(self, connection):        ip = connection.get_ip()        if self.perip.has_key(ip):            perip = self.perip[ip]        else:            perip = self.perip.setdefault(ip, PerIPStats(ip))        perip.peerid = connection.get_readable_id()        perip.numconnections += 1        d = SingleDownload(self, connection)        perip.lastdownload = d        self.downloads.append(d)        return d    def piece_flunked(self, index):        if self.paused:            return        if self.endgamemode:            if self.downloads:                while self.storage.do_I_have_requests(index):                    nb, nl = self.storage.new_request(index)                    self.all_requests.append((index, nb, nl))                for d in self.downloads:                    d.fix_download_endgame()                return            self._reset_endgame()            return        ds = [d for d in self.downloads if not d.choked]        shuffle(ds)        for d in ds:            d._request_more()        ds = [d for d in self.downloads if not d.interested and d.have[index]]        for d in ds:            d.example_interest = index            d.send_interested()    def has_downloaders(self):        return len(self.downloads)    def lost_peer(self, download):        ip = download.ip        self.perip[ip].numconnections -= 1        if self.perip[ip].lastdownload == download:            self.perip[ip].lastdownload = None        self.downloads.remove(download)        if self.endgamemode and not self.downloads: # all peers gone            self._reset_endgame()    def _reset_endgame(self):                    self.storage.reset_endgame(self.all_requests)        self.endgamemode = False        self.all_requests = []        self.endgame_queued_pieces = []    def add_disconnected_seed(self, id):#        if not self.disconnectedseeds.has_key(id):#            self.picker.seed_seen_recently()        self.disconnectedseeds[id]=clock()#	def expire_disconnected_seeds(self):    def num_disconnected_seeds(self):        # first expire old ones        expired = []        for id,t in self.disconnectedseeds.items():            if clock() - t > EXPIRE_TIME:     #Expire old seeds after so long                expired.append(id)        for id in expired:#            self.picker.seed_disappeared()            del self.disconnectedseeds[id]        return len(self.disconnectedseeds)        # if this isn't called by a stats-gathering function        # it should be scheduled to run every minute or two.    def _check_kicks_ok(self):        if len(self.gotbaddata) > 10:            self.kickbans_ok = False            self.kickbans_halted = True        return self.kickbans_ok and len(self.downloads) > 2    def try_kick(self, download):        if self._check_kicks_ok():            download.guard.download = None            ip = download.ip            id = download.connection.get_readable_id()            self.kicked[ip] = id            self.perip[ip].peerid = id            self.kickfunc(download.connection)            def try_ban(self, ip):        if self._check_kicks_ok():            self.banfunc(ip)            self.banned[ip] = self.perip[ip].peerid            if self.kicked.has_key(ip):                del self.kicked[ip]    def set_super_seed(self):        self.super_seeding = True    def check_complete(self, index):        if self.endgamemode and not self.all_requests:            self.endgamemode = False        if self.endgame_queued_pieces and not self.endgamemode:            self.requeue_piece_download()        if self.storage.am_I_complete():            assert not self.all_requests            assert not self.endgamemode            for d in [i for i in self.downloads if i.have.complete()]:                d.connection.send_have(index)   # be nice, tell the other seed you completed                self.add_disconnected_seed(d.connection.get_readable_id())                d.connection.close()            return True        return False    def too_many_partials(self):        return len(self.storage.dirty) > (len(self.downloads)/2)    def cancel_piece_download(self, pieces):        if self.endgamemode:            if self.endgame_queued_pieces:                for piece in pieces:                    try:                        self.endgame_queued_pieces.remove(piece)                    except:                        pass            new_all_requests = []            for index, nb, nl in self.all_requests:                if index in pieces:                    self.storage.request_lost(index, nb, nl)                else:                    new_all_requests.append((index, nb, nl))            self.all_requests = new_all_requests        for d in self.downloads:            hit = False            for index, nb, nl in d.active_requests:                if index in pieces:                    hit = True                    d.connection.send_cancel(index, nb, nl)                    if not self.endgamemode:                        self.storage.request_lost(index, nb, nl)            if hit:                d.active_requests = [ r for r in d.active_requests                                      if r[0] not in pieces ]                d._request_more()            if not self.endgamemode and d.choked:                d._check_interests()    def requeue_piece_download(self, pieces = []):        if self.endgame_queued_pieces:            for piece in pieces:                if not piece in self.endgame_queued_pieces:                    self.endgame_queued_pieces.append(piece)            pieces = self.endgame_queued_pieces        if self.endgamemode:            if self.all_requests:                self.endgame_queued_pieces = pieces                return            self.endgamemode = False            self.endgame_queued_pieces = None                   ds = [d for d in self.downloads]        shuffle(ds)        for d in ds:            if d.choked:                d._check_interests()            else:                d._request_more()    def start_endgame(self):        assert not self.endgamemode        self.endgamemode = True        assert not self.all_requests        for d in self.downloads:            if d.active_requests:                assert d.interested and not d.choked            for request in d.active_requests:                assert not request in self.all_requests                self.all_requests.append(request)        for d in self.downloads:            d.fix_download_endgame()    def pause(self, flag):        self.paused = flag        if flag:            for d in self.downloads:                for index, begin, length in d.active_requests:                    d.connection.send_cancel(index, begin, length)                d._letgo()                d.send_not_interested()            if self.endgamemode:                self._reset_endgame()        else:            shuffle(self.downloads)            for d in self.downloads:                d._check_interests()                if d.interested and not d.choked:                    d._request_more()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -