def block(self, connection_ind, msg): #IF BLOCK IF FOUND THIS WILL BE REMOVED #and it is not corrupted, try to write it to #the respective position in file,]. l = -1 for s in UserLib.requests: if s[0] == msg['chunkpos']: l = 0 UserLib.requests.remove(s) break if l == -1 or bitmap.bmp_isvalid(UserLib.bmp, msg['chunkpos'], UserLib.lock): raise UserLib.UnexpectedBlock if mysha1lib.mysha1( msg['chunk']) == UserLib.sha1s_map[msg['chunkpos']]: try: self.f.seek(int(msg['chunkpos']) * UserDefs.PieceSize) self.f.write(msg['chunk']) #if an Exception occurs close file stream and raise it. except IOError as detail: print("<block>:: File Error at Leecher thread:", detail) self.f.close() raise #if an Exception occurs close file stream and raise it. except Exception as detail: print("<block>:: Unexpected Exception :", detail) self.f.close() raise try: # mutual exclusion before informing bitmap. bitmap.bmp_setvalid(UserLib.bmp, msg['chunkpos'], UserLib.lock) except Exception as detail: print("<block>:: Unexpected Exception while setting bitmap:", detail) raise # increase chunks downloaded from current connection. UserLib.DownConn_map[connection_ind][2] += 1 UserLib.DownConn_map[connection_ind][8] = time.time() # inclease total chunks downloaded. UserLib.PiecesDownloaded += 1 sys.stderr.flush() sys.stderr.write( "%.2f%%\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" % (100 * UserLib.PiecesDownloaded / UserLib.BMPLENGTH)) else: print("Received corrupted block") raise UserLib.BlockCorrupted
def block(self,connection_ind,msg): #IF BLOCK IF FOUND THIS WILL BE REMOVED #and it is not corrupted, try to write it to #the respective position in file,]. l=-1 for s in UserLib.requests: if s[0] == msg['chunkpos']: l=0 UserLib.requests.remove(s) break if l == -1 or bitmap.bmp_isvalid(UserLib.bmp,msg['chunkpos'],UserLib.lock) : raise UserLib.UnexpectedBlock if mysha1lib.mysha1(msg['chunk'])==UserLib.sha1s_map[msg['chunkpos']]: try: self.f.seek(int(msg['chunkpos'])*UserDefs.PieceSize) self.f.write(msg['chunk']) #if an Exception occurs close file stream and raise it. except IOError as detail: print("<block>:: File Error at Leecher thread:",detail) self.f.close() raise #if an Exception occurs close file stream and raise it. except Exception as detail: print("<block>:: Unexpected Exception :",detail) self.f.close() raise try: # mutual exclusion before informing bitmap. bitmap.bmp_setvalid(UserLib.bmp,msg['chunkpos'],UserLib.lock) except Exception as detail: print("<block>:: Unexpected Exception while setting bitmap:",detail) raise # increase chunks downloaded from current connection. UserLib.DownConn_map[connection_ind][2]+=1 UserLib.DownConn_map[connection_ind][8]=time.time() # inclease total chunks downloaded. UserLib.PiecesDownloaded+=1 sys.stderr.flush() sys.stderr.write("%.2f%%\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"%(100*UserLib.PiecesDownloaded/UserLib.BMPLENGTH)) else: print("Received corrupted block") raise UserLib.BlockCorrupted
def select_block(self): #aging pipelined requests. for i in range(0, len(UserLib.requests)): UserLib.requests[i][2] += 1 if UserLib.PiecesDownloaded == UserLib.BMPLENGTH: raise UserLib.FileCompletelyDownloaded #if there is no space to send new requests, delete aged requests. elif len(UserLib.requests) == UserDefs.MaxPendingReq: UserLib.requests = [ r for r in UserLib.requests if r[2] < UserDefs.AgedRequestLimit ] raise UserLib.MaxRequestsSent #print("-----------------------------------------") #for i,con in enumerate(UserLib.DownConn_map): # print("connection:",i,con[3],con[5],con[6]) #print("-----------------------------------------") ind = -1 chunks_available = [] #for each chunk append to list: [its occurence, its number, ind of connections that has this chunk]. for i in range(0, UserLib.BMPLENGTH): chunks_available.append([0, i, []]) for i in range(0, len(UserLib.DownConn_map)): if UserLib.DownConn_map[i][ 6] == 'interested' and UserLib.DownConn_map[i][ 5] == 'unchoked': for j in range(0, UserLib.BMPLENGTH): if bitmap.bmp_isvalid(UserLib.DownConn_map[i][3], j, -1): ind = 1 chunks_available[j][0] += 1 chunks_available[j][2].append(i) ######################################################################################### # In example: [[2, 0, [0, 2]], [3, 1, [0, 1, 2]], [3, 2, [0, 1, 2]], [2, 3, [1, 2]]] # # # # 2 connections: 0,2 have piece 0 # # 3 connections: 0,1,2 have piece 1 # # 3 connections: 0,1,2 have piece 2 # # 2 connections: 1,2 have piece 3 # # # # After sort: [[2, 0, [0, 2]], [2, 3, [1, 2]], [3, 1, [0, 1, 2]], [3, 2, [0, 1, 2]]] # ######################################################################################### #if there is no connection to send block request. if ind == -1: raise UserLib.AllConnectionsChoked #Random Policy #for the first chunks: #find a random chunk from list #if you do have it or noone else has it, choose another one. #Repeat till you find a chunk some peers have but you don't. if UserLib.PiecesDownloaded < UserDefs.RandomChunks: i = random.randint(0, len(chunks_available) - 1) for reps in range(0, len(chunks_available)): try: isvalid = bitmap.bmp_isvalid(UserLib.bmp, chunks_available[i][1], UserLib.lock) except exception as detail: print("<select_block>: ", i, detail) raise if not isvalid and chunks_available[i][ 0] > 0 and chunks_available[i][1] not in [ r[0] for r in UserLib.requests ]: return random.choice( chunks_available[i][2]), chunks_available[i][1] i = (i + 1) % len(chunks_available) else: chunks_available.sort() #Rarest First policy #chunks are sorted increasingly according to their occurence #request the rarest chunk that you dont have, from a randlom #peer that posses it. if UserLib.BMPLENGTH - UserLib.PiecesDownloaded > UserDefs.MaxPendingReq: for i in range(0, UserLib.BMPLENGTH): isvalid = bitmap.bmp_isvalid(UserLib.bmp, chunks_available[i][1], UserLib.lock) if not isvalid and chunks_available[i][ 0] > 0 and chunks_available[i][1] not in [ r[0] for r in UserLib.requests ]: return random.choice( chunks_available[i][2]), chunks_available[i][1] #if less than MaxPendingReq pieces remain #request to everyone. #End Game Mode LIKE else: for i in range(0, UserLib.BMPLENGTH): isvalid = bitmap.bmp_isvalid(UserLib.bmp, chunks_available[i][1], UserLib.lock) if not isvalid and chunks_available[i][0] > 0: return random.choice( chunks_available[i][2]), chunks_available[i][1] raise UserLib.MaxRequestsSent
def select_block(self): #aging pipelined requests. for i in range(0,len(UserLib.requests)): UserLib.requests[i][2]+=1 if UserLib.PiecesDownloaded == UserLib.BMPLENGTH: raise UserLib.FileCompletelyDownloaded #if there is no space to send new requests, delete aged requests. elif len(UserLib.requests) == UserDefs.MaxPendingReq: UserLib.requests=[ r for r in UserLib.requests if r[2] < UserDefs.AgedRequestLimit] raise UserLib.MaxRequestsSent #print("-----------------------------------------") #for i,con in enumerate(UserLib.DownConn_map): # print("connection:",i,con[3],con[5],con[6]) #print("-----------------------------------------") ind=-1 chunks_available=[] #for each chunk append to list: [its occurence, its number, ind of connections that has this chunk]. for i in range(0,UserLib.BMPLENGTH): chunks_available.append([0,i,[]]) for i in range(0,len(UserLib.DownConn_map)): if UserLib.DownConn_map[i][6]=='interested' and UserLib.DownConn_map[i][5]=='unchoked': for j in range(0,UserLib.BMPLENGTH): if bitmap.bmp_isvalid(UserLib.DownConn_map[i][3],j,-1): ind=1 chunks_available[j][0]+=1 chunks_available[j][2].append(i) ######################################################################################### # In example: [[2, 0, [0, 2]], [3, 1, [0, 1, 2]], [3, 2, [0, 1, 2]], [2, 3, [1, 2]]] # # # # 2 connections: 0,2 have piece 0 # # 3 connections: 0,1,2 have piece 1 # # 3 connections: 0,1,2 have piece 2 # # 2 connections: 1,2 have piece 3 # # # # After sort: [[2, 0, [0, 2]], [2, 3, [1, 2]], [3, 1, [0, 1, 2]], [3, 2, [0, 1, 2]]] # ######################################################################################### #if there is no connection to send block request. if ind == -1: raise UserLib.AllConnectionsChoked #Random Policy #for the first chunks: #find a random chunk from list #if you do have it or noone else has it, choose another one. #Repeat till you find a chunk some peers have but you don't. if UserLib.PiecesDownloaded < UserDefs.RandomChunks: i=random.randint(0,len(chunks_available)-1) for reps in range(0,len(chunks_available)): try: isvalid=bitmap.bmp_isvalid(UserLib.bmp,chunks_available[i][1],UserLib.lock) except exception as detail: print("<select_block>: ",i,detail) raise if not isvalid and chunks_available[i][0]>0 and chunks_available[i][1] not in [r[0] for r in UserLib.requests]: return random.choice(chunks_available[i][2]), chunks_available[i][1] i=(i+1)%len(chunks_available) else: chunks_available.sort() #Rarest First policy #chunks are sorted increasingly according to their occurence #request the rarest chunk that you dont have, from a randlom #peer that posses it. if UserLib.BMPLENGTH-UserLib.PiecesDownloaded > UserDefs.MaxPendingReq: for i in range(0,UserLib.BMPLENGTH): isvalid=bitmap.bmp_isvalid(UserLib.bmp,chunks_available[i][1],UserLib.lock) if not isvalid and chunks_available[i][0]>0 and chunks_available[i][1] not in [r[0] for r in UserLib.requests]: return random.choice(chunks_available[i][2]), chunks_available[i][1] #if less than MaxPendingReq pieces remain #request to everyone. #End Game Mode LIKE else: for i in range(0,UserLib.BMPLENGTH): isvalid=bitmap.bmp_isvalid(UserLib.bmp,chunks_available[i][1],UserLib.lock) if not isvalid and chunks_available[i][0]>0: return random.choice(chunks_available[i][2]), chunks_available[i][1] raise UserLib.MaxRequestsSent