Exemplo n.º 1
0
    def terminate(self):

        self.f.close()
        for s in self.sockset:
            #if not s==sys.stdin:
            s.close()
        print(self.getName(), " is going to terinate\n")
        print("Pieces sent:", UserLib.BlocksSent)
        print("Messages Sent:", UserLib.MessagesSent)
        print("Interested Received:", UserLib.InterestedReceived)
        print("Uninterested Received:", UserLib.UninterestedReceived)
        print("Interested Sent:", UserLib.InterestedSent)
        print("Uninterested Sent:", UserLib.UninterestedSent)
        print("Optimistic Unchokes Received:", UserLib.OptUnchokesReceived)
        print("Regular Unchokes Received:", UserLib.RegUnchokesReceived)
        if not UserLib.OptUnchokesReceived == 0:
            print("Interested connected peers per Opt Unchoke:%.2f" %
                  (UserLib.InterestedPeersAtOpt / UserLib.OptUnchokesReceived))
        print("OptUnchokeTimes:", UserLib.OptUnchokeTimes)
        print("RegUnchokeTimes:", UserLib.RegUnchokeTimes)
        print("Uploading_t:", UserLib.Uploading_t)
        print("Downloading_t:", UserLib.Downloading_t)
        print("InterestedMsgReceived_t:", UserLib.InterestedMsgReceived_t)
        msg = {'type': 'leave'}
        SocketLevel.send_msg(-1, self.tracker, [], msg)
        return
Exemplo n.º 2
0
	def terminate(self):

		self.f.close()
		for s in self.sockset:
			#if not s==sys.stdin:
			s.close()
		print(self.getName()," is going to terinate\n")
		print("Pieces sent:",UserLib.BlocksSent)
		print("Messages Sent:",UserLib.MessagesSent)
		print("Interested Received:",UserLib.InterestedReceived)
		print("Uninterested Received:",UserLib.UninterestedReceived)
		print("Interested Sent:",UserLib.InterestedSent)
		print("Uninterested Sent:",UserLib.UninterestedSent)
		print("Optimistic Unchokes Received:",UserLib.OptUnchokesReceived)
		print("Regular Unchokes Received:",UserLib.RegUnchokesReceived)
		if not UserLib.OptUnchokesReceived == 0:
			print("Interested connected peers per Opt Unchoke:%.2f"%(UserLib.InterestedPeersAtOpt/UserLib.OptUnchokesReceived))
		print("OptUnchokeTimes:",UserLib.OptUnchokeTimes)
		print("RegUnchokeTimes:",UserLib.RegUnchokeTimes)
		print("Uploading_t:",UserLib.Uploading_t)
		print("Downloading_t:",UserLib.Downloading_t)
		print("InterestedMsgReceived_t:",UserLib.InterestedMsgReceived_t)
		msg={'type':'leave'}
		SocketLevel.send_msg(-1, self.tracker, [],msg)
		return
Exemplo n.º 3
0
	def get_peerset(self):
	
		#remove port's and ip's from your set.
		self.listeningports=[]
		self.listeningips=[]
		#request a new peer set.
		while UserDefs.Run:
			#prepare message
			self.peer_request()
			#try to send it to coordinator
			try:
				SocketLevel.send_msg(-1, self.tracker, [], self.msg)
			except Exception as detail:
				print("<get_peerset>:: 1.Exception while contacting coordinator.:",detail)
				raise
			#receive request from coordinator
			try:	
				msg=SocketLevel.recv_msg(-1, self.tracker, [])					
				#for each peer of the received set keep its ip,port and id.
				self.listeningports=msg['listeningports']
				self.listeningips=msg['listeningips']
				self.peerids=msg['peerids']
				i=len(self.listeningports)-1
				while i>=0:
					if self.listeningports[i] in [ temp[0] for temp in UserLib.TimedOutPeers ] \
					and self.listeningips[i]  in [ temp[1] for temp in UserLib.TimedOutPeers ]:
						del self.listeningports[i]
						del self.listeningips[i]
						del self.peerids[i]
					i-=1
				#if identifier of current peer is present in received set
				try:
					mypos=self.peerids.index(UserLib.mypeerid)
				except ValueError as detail:
					print("<get_peerset>::wtf???",detail)
					pass
				#remove it, and its ip and its port, since it is useless to try
				#to establish connection with tself.
				else:
					del self.listeningports[mypos]
					del self.listeningips[mypos]
					del self.peerids[mypos]
			#Uppon Exception raise it
			except Exception as detail:
				print("<get_peerset>:: 2.Exception in while contacting coordinator.",detail)
				raise
			if not self.listeningports:
				#if there is no peer in swarm wait 15 seconds 
				#before you ask again a list of listening peers.
				time.sleep(UserDefs.PeerListReqInterval)
			else:	
				break
		#print("--------------")
		#print('active peer set:','\n',self.listeningports,'\n',self.listeningips,'\n',self.peerids)
		#print("-------------")
		if not UserDefs.Run:
			raise UserLib.TerminateThread
			return
Exemplo n.º 4
0
def main():

    global msg, msg_r
    if not len(sys.argv) in [7, 8]:
        print(
            "Usage:", sys.argv[0],
            "(<trackerip> <trackerport>) <listeningport> <seed/peer> <filename> <optimistic/optimal> [<create metadata file>]"
        )
        return

    #assign command line arguments to local variables
    trackerip = socket.gethostbyname(sys.argv[1])
    trackerport = int(sys.argv[2])
    listeningport = int(sys.argv[3])
    hostname = socket.gethostname()
    listeningip = socket.gethostbyname(hostname)
    mode = sys.argv[4]
    filename = sys.argv[5]
    choice = sys.argv[6]
    print(trackerip, trackerport, listeningip, listeningport, mode, filename,
          choice)

    #The first uploader is also the creator of metadata file.
    #All other peers receiving metadata file from a site
    #acting as a global directory.
    if len(sys.argv) == 8 and sys.argv[7] == "create":
        metadata_dict = metadataLib.create_metadatafile(filename)
    else:
        metadata_dict = metadataLib.read_metadatafile(filename)
    print("size of metadata")

    if mode == "peer":
        #create file so that following server and leecher thread open it.
        try:
            filename = filename + str(listeningport)
            f = open(filename, 'wb+')
        #Uppon Exception, make clen up job and terminatethread.
        except IOError as detail:
            print("IOError:", detail)
            return
        #Uppon Exception, make clen up job and terminate thread.
        except Exception as detail:
            print("0.Unexpected exception:", detail)
            return
        else:
            f.close()

    #initialize bitmap, sha1's of each chunk and file identifier(metadata hash).
    UserLib.BMPLENGTH = math.ceil(metadata_dict['filesize'] /
                                  UserDefs.PieceSize)
    bitmap.bmp_init(UserLib.bmp, UserLib.BMPLENGTH)
    UserLib.sha1s_map = metadata_dict['sha1s_map']
    UserLib.metadata_hash = metadata_dict['metadata_hash']
    #print("metadata_hash",UserLib.metadata_hash)
    #In seeder mode all blocks are available.
    if mode == "seed":
        bitmap.bmp_setallvalid(UserLib.bmp, UserLib.BMPLENGTH)

    #creation of a socket to establish  TCP connection with coordinator.
    try:
        tracker = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        tracker.connect((trackerip, trackerport))
    except socket.error as detail:
        print("Tracker communication Socket error", detail)
        return
    except Exception as detail:
        print("Unexpected Exception:", detail)
        return

    #prepare a "join_swarm" message" to send to coordinator.
    join_swarm(metadata_dict['filename'], metadata_dict['filesize'],
               metadata_dict['FileMd5'], listeningip, listeningport)
    try:
        SocketLevel.send_msg(-1, tracker, [], msg)
    except Exception as detail:
        print("Unexpected Exception:", detail)
        tracker.close()
        return

    #receive a "join_response" message from coordinator.
    try:
        msg_r = SocketLevel.recv_msg(-1, tracker, [])
    except Exception as detail:
        print("Unexpected Exception:", detail)
        tracker.close()
        return
    #upon successful communication retrieve your peer identifier.
    else:
        UserLib.mypeerid = msg_r['peerid']

    #constructor of "ServerThread" for that peer
    #size, md5 and name of file to seed
    #port and ip listening for requests of TCP connections
    #socket of established connection with coordinator.
    Sthread = ServerThread.ServerThread(metadata_dict['filesize'],
                                        metadata_dict['FileMd5'], filename,
                                        listeningport, listeningip, mode,
                                        choice, tracker)
    Sthread.start()

    #constructor of "LeecherThread" for that peer-if not in seeder mode.
    if mode == "peer":
        Lthread = LeecherThread.LeecherThread(metadata_dict['filesize'],
                                              metadata_dict['FileMd5'],
                                              filename, listeningport,
                                              listeningip, tracker)
        Lthread.start()

    #Main Thread waiting threads to terminate.
    Sthread.join()
    if sys.argv[3] == "peer":
        Lthread.join()
    tracker.close()
    print('Programm is going to terminate')
    return
Exemplo n.º 5
0
    def get_peerset(self):

        #remove port's and ip's from your set.
        self.listeningports = []
        self.listeningips = []
        #request a new peer set.
        while UserDefs.Run:
            #prepare message
            self.peer_request()
            #try to send it to coordinator
            try:
                SocketLevel.send_msg(-1, self.tracker, [], self.msg)
            except Exception as detail:
                print(
                    "<get_peerset>:: 1.Exception while contacting coordinator.:",
                    detail)
                raise
            #receive request from coordinator
            try:
                msg = SocketLevel.recv_msg(-1, self.tracker, [])
                #for each peer of the received set keep its ip,port and id.
                self.listeningports = msg['listeningports']
                self.listeningips = msg['listeningips']
                self.peerids = msg['peerids']
                i = len(self.listeningports) - 1
                while i >= 0:
                    if self.listeningports[i] in [ temp[0] for temp in UserLib.TimedOutPeers ] \
                    and self.listeningips[i]  in [ temp[1] for temp in UserLib.TimedOutPeers ]:
                        del self.listeningports[i]
                        del self.listeningips[i]
                        del self.peerids[i]
                    i -= 1
                #if identifier of current peer is present in received set
                try:
                    mypos = self.peerids.index(UserLib.mypeerid)
                except ValueError as detail:
                    print("<get_peerset>::wtf???", detail)
                    pass
                #remove it, and its ip and its port, since it is useless to try
                #to establish connection with tself.
                else:
                    del self.listeningports[mypos]
                    del self.listeningips[mypos]
                    del self.peerids[mypos]
            #Uppon Exception raise it
            except Exception as detail:
                print(
                    "<get_peerset>:: 2.Exception in while contacting coordinator.",
                    detail)
                raise
            if not self.listeningports:
                #if there is no peer in swarm wait 15 seconds
                #before you ask again a list of listening peers.
                time.sleep(UserDefs.PeerListReqInterval)
            else:
                break
        #print("--------------")
        #print('active peer set:','\n',self.listeningports,'\n',self.listeningips,'\n',self.peerids)
        #print("-------------")
        if not UserDefs.Run:
            raise UserLib.TerminateThread
            return
Exemplo n.º 6
0
 def run(self):
     print("my peer id:", UserLib.mypeerid)
     #keep beginning time
     self.begtime = time.time()
     random.seed(time.time())  #self.begtime)
     #try to open file to write received chunks.
     try:
         self.f = open(self.filename, 'wb')
     #Uppon Exception, make clen up job and terminatethread.
     except IOError as detail:
         print("IOError at Leecher thread:", detail)
         self.terminate()
         return
     #Uppon Exception, make clen up job and terminate thread.
     except Exception as detail:
         print("0.Unexpected exception in Leecher thread:", detail)
         self.terminate()
         return
     #while thread should not terminate.
     t = self.begtime
     while UserDefs.Run:
         #If there are no peers in peer set, new connections should be established.
         #THIS WILL BE DONE IF CONNECTIONS ARE LESS THAN A THREASHOLD.
         if time.time(
         ) - t > UserDefs.PeerListReqInterval or not UserLib.DownConn_map:
             t = time.time()
             if not UserLib.DownConn_map:
                 print("Empty connections")
             try:
                 self.establish_connections()
             except UserLib.EstablishConnError as detail:
                 print("establish connections error at Leecher thread:",
                       detail)
                 time.sleep(UserDefs.PeerListReqInterval)
                 continue
             except UserLib.TerminateThread:
                 break
             except Exception as detail:
                 print("2.Unexpected Exception in Leecher thread:", detail)
                 time.sleep(UserDefs.PeerListReqInterval)
                 continue
         #NOW WE HAVE AS MUCH AS MAXDOWNCONN established connections and tokens to send requests.
         #but connections are choked.So watch the set to receive unchoke messages.
         self.sockset = [temp[0] for temp in UserLib.DownConn_map]
         try:
             inputready, outputready, exceptionready = select.select(
                 self.sockset, [], [], UserDefs.SelectTimeout)
         except (ValueError, select.error) as detail:
             print("Select Exception in Leecher thread:", detail)
             continue
         #1.) In case a descripitor from your set has data that is state oriented msg.
         for s in inputready:
             #find position of socket having data into downloading connections map
             try:
                 ind = [temp[0] == s
                        for temp in UserLib.DownConn_map].index(True)
             except ValueError as detail:
                 print("Value Error at Leecher Thread:", detail, s)
                 continue
             #try to receive message via socket indexed by ind.
             try:
                 UserLib.SocketLock.acquire()
                 self.msg_r = SocketLevel.recv_msg(ind, -1,
                                                   UserLib.DownConn_map,
                                                   True)
             #Uppon Exception socket indexed by ind had been removed from "recv_msg".
             except UserLib.ConnectionResetedByPeer:
                 print("3.ConnectionResetedByPeer in Leecher thread:")
                 continue
             except Exception as detail:
                 print("3.Unexpected Exception in Leecher thread:", detail)
                 continue
             finally:
                 UserLib.SocketLock.release()
             try:
                 msgtype = self.msg_r['type']
             except Exception as detail:
                 print("4.Unexpected Exception in Leecher thread:", detail)
                 continue
             if msgtype == 'unchoke':
                 if self.unchokes == 0:
                     print(
                         "First unchoke after:%.2f" %
                         (time.time() - self.begtime), "seconds")
                 self.unchokes += 1
                 UserLib.DownConn_map[ind][5] = 'unchoked'
             elif msgtype == 'choke':
                 UserLib.DownConn_map[ind][5] = 'choked'
                 #delete pending requests to chocking remote peer.
                 UserLib.requests = [
                     r for r in UserLib.requests
                     if not r[1] == UserLib.DownConn_map[ind][4]
                 ]
             elif msgtype == 'have':
                 #update bitmap of peer having a new piece
                 try:
                     bitmap.bmp_setvalid(UserLib.DownConn_map[ind][3],
                                         self.msg_r['chunkno'], -1)
                     #check if you are interested in this peer
                     state = bitmap.interested(UserLib.bmp,
                                               UserLib.DownConn_map[ind][3],
                                               UserLib.BMPLENGTH,
                                               UserLib.lock)
                     #if there is a change in your state about this peer
                 except Exception:
                     continue
                 if UserLib.DownConn_map[ind][
                         6] == 'uninterested' and state == 'interested':
                     #inform your map
                     UserLib.DownConn_map[ind][6] = state
                     #inform remote peer
                     try:
                         self.interested()
                         UserLib.SocketLock.acquire()
                         SocketLevel.send_msg(ind, -1, UserLib.DownConn_map,
                                              self.msg, True)
                     except Exception as detail:
                         print("5.Unexpected Exception in Leecher thread:",
                               detail)
                         continue
                     finally:
                         UserLib.SocketLock.release()
             #if received message is "block respose"
             #try to write block to resective position in file.:
             elif msgtype == 'block':
                 chunkno = self.msg_r['chunkpos']
                 try:
                     self.block(ind, self.msg_r)
                 #Exception indication requested block is not available
                 #to peer last request was send.
                 except UserLib.BlockCorrupted:
                     print("6.BlockCorrupted in Leecher thread:")
                     continue
                 except UserLib.UnexpectedBlock:
                     #print("6.UnexpectedBlock in Leecher thread:")
                     continue
                 #Uppon Exception Terminate thread
                 except Exception as detail:
                     print("6.Unexpected Exception in Leecher thread:",
                           detail)
                     continue
                 self.have(chunkno)
                 try:
                     UserLib.SocketLock.acquire()
                     SocketLevel.send_msg(ind, -1, UserLib.DownConn_map,
                                          self.msg, True)
                 except Exception as detail:
                     print("7.1.Unexpected Exception in Leecher thread:",
                           detail)
                     continue
                 finally:
                     UserLib.SocketLock.release()
                 i = len(UserLib.UpConn_map) - 1
                 UserLib.SocketLock.acquire()
                 while i >= 0:
                     try:
                         if UserLib.DownConn_map[ind][
                                 4] == UserLib.UpConn_map[i][2]:
                             i -= 1
                             continue
                     except Exception as detail:
                         i -= 1
                         print(
                             "7.1.2.Unexpected Exception in Lecher thread:",
                             detail, ind, UserLib.UpConn_map,
                             UserLib.DownConn_map)
                         continue
                     #inform all downloaders directly conected to you that you
                     #receive a new piece.
                     try:
                         #UserLib.SocketLock.acquire()
                         SocketLevel.send_msg(i, -1, UserLib.UpConn_map,
                                              self.msg)
                     except Exception as detail:
                         i = len(UserLib.UpConn_map) - 1
                         print("7.2.Unexpected Exception in Lecher thread:",
                               detail, i, len(UserLib.UpConn_map))
                     else:
                         i -= 1
                     #finally:
                     #	UserLib.SocketLock.release()
                 UserLib.SocketLock.release()
                 for i in range(0, len(UserLib.DownConn_map)):
                     try:
                         state = bitmap.interested(
                             UserLib.bmp, UserLib.DownConn_map[i][3],
                             UserLib.BMPLENGTH, UserLib.lock)
                     except Exception:
                         continue
                     if UserLib.DownConn_map[i][
                             6] == 'interested' and state == 'uninterested':
                         UserLib.DownConn_map[i][6] = state
                         try:
                             #print("here",UserLib.DownConn_map,UserLib.bmp)
                             self.uninterested()
                             UserLib.SocketLock.acquire()
                             SocketLevel.send_msg(i, -1,
                                                  UserLib.DownConn_map,
                                                  self.msg, True)
                         except Exception as detail:
                             print(
                                 "9.Unexpected Exception in Leecher thread:",
                                 detail)
                             continue
                         finally:
                             UserLib.SocketLock.release()
         #select block and uploader.
         try:
             ind, self.blockno = self.select_block()
         except UserLib.FileCompletelyDownloaded:
             break
         except UserLib.AllConnectionsChoked:
             #print("11.AllConnectionsChoked or unintetresting in Leecher thread")
             continue
         except UserLib.MaxRequestsSent:
             #print("11.MaxRequestsSent in Leecher thread")
             continue
         except Exception as detail:
             print("11.Unexpected Exception in Leecher thread:", detail)
             break
         #if it is a pending block request, dont do anything.
         #prepare request for the selected block.
         self.request(self.blockno)
         try:
             UserLib.SocketLock.acquire()
             SocketLevel.send_msg(ind, -1, UserLib.DownConn_map, self.msg,
                                  True)
         except Exception as detail:
             print("12.Unexpected Exception in Leecher thread:", detail)
             continue
         else:
             UserLib.requests.append(
                 [self.blockno, UserLib.DownConn_map[ind][4], 0])
         finally:
             UserLib.SocketLock.release()
     #while Run
     #make "clen up" job and terminate thread.
     self.terminate()
     return
Exemplo n.º 7
0
 def run(self):
     random.seed(time.time())
     #create a socket, bind it to your listening ip and port
     #in order to listen for incoming TCP connection requests.
     try:
         server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
         server.bind((self.listeningip, self.listeningport))
         server.listen(1)
     #Uppon Exception close listening socket and terminate thread.
     except (socket.error, socket.gaierror, OverflowError) as detail:
         print("Listening Socket error:", detail)
         server.close()
         UserDefs.Run = False
         return
     #Open file to seed.
     try:
         self.f = open(self.filename, 'rb')
     except IOError as detail:
         print("IOError Opening File", detail)
         self.terminate()
     except Exception as detail:
         print("Unexpected Exception opening file at server thread:",
               detail)
         self.terminate()
     #Loop forever
     while UserDefs.Run:
         self.sockset = [temp[0] for temp in UserLib.UpConn_map]
         if len(UserLib.UpConn_map) == UserDefs.ActiveSetSize:
             #print("max size")
             self.sockset = self.sockset + [sys.stdin]
         else:
             self.sockset = self.sockset + [server, sys.stdin]
         # wait till a socket has data.
         try:
             inputready, outputready, exceptionready = select.select(
                 self.sockset, [], [])
         except ValueError as detail:
             print("select at server thread:", detail, self.sockset)
         #search on which socket there are available data.
         for s in inputready:
             #if it is in server socket, it is a TCP connection request.
             if s == server:
                 if len(UserLib.UpConn_map) == UserDefs.ActiveSetSize:
                     continue
                 try:
                     conn, addr = server.accept()
                     conn.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,
                                     1)
                 except socket.timeout:
                     print("timeout")
                     pass
                 except Exception as detail:
                     print("Accepting connection error:", detail)
                 #Uppon success, append socket into watched set.
                 #append socket, peer ip and port, peer id and connection's
                 #state info to Uploading connections map.
                 else:
                     #if len(UserLib.UpConn_map)>=UserDefs.ActiveSetSize:
                     #	print("here")
                     #	conn.close()
                     #	continue
                     self.sockset.append(conn)
                     UserLib.UpConn_map.append([
                         conn,
                         conn.getpeername(), 0, 'choked', 'uninterested',
                         False, 0, 0, 0
                     ])
             elif s == sys.stdin:
                 ##command = s.readline()
                 ##if command == 'quit\n':
                 UserDefs.Run = False
                 break
             #otherwise there are data in socket of an established connection.
             else:
                 #find position of current socket into uploading connections map
                 try:
                     ind = [temp[0] == s
                            for temp in UserLib.UpConn_map].index(True)
                 except ValueError as detail:
                     print("Unable to index connection at server Thread:",
                           detail, s)
                     continue
                 #try to receive message via socket indexed by ind.
                 try:
                     UserLib.SocketLock.acquire()
                     self.msg_r = SocketLevel.recv_msg(
                         ind, -1, UserLib.UpConn_map)
                 #Uppon Exception socket indexed by ind had been removed from "recv_msg".
                 except UserLib.ConnectionResetedByPeer:
                     print("2. ConnectionResetedByPeer at Server Thread:")
                     UserLib.SocketLock.release()
                     self.unchoke()
                     continue
                 except Exception as detail:
                     print("2. Unexpected exception at Server Thread:",
                           detail)
                     UserLib.SocketLock.release()
                     self.unchoke()
                     continue
                 else:
                     UserLib.SocketLock.release()
                 try:
                     msgtype = self.msg_r['type']
                 except Exception as detail:
                     print("Key error at Server Thread:", detail)
                     self.unchoke()
                     continue
                 #if message is a "block request"
                 if msgtype == 'request':
                     #create and send response via socket s.
                     try:
                         self.block(self.msg_r)
                         UserLib.SocketLock.acquire()
                         SocketLevel.send_msg(ind, -1, UserLib.UpConn_map,
                                              self.msg)
                         UserLib.UpConn_map[ind][7] += 1
                     #Uppon Exception socket indexed by ind had been removed from "send_msg".
                     except Exception as detail:
                         print("3. Unexpected exception at Server Thread:",
                               detail)
                         UserLib.SocketLock.release()
                         self.unchoke()
                         continue
                     else:
                         UserLib.SocketLock.release()
                 #if message is a "handshake request"
                 elif msgtype == 'handshake':
                     #check file id of requested file.
                     #Connection should be closed
                     if not self.msg_r[
                             'metadata_hash'] == UserLib.metadata_hash:
                         print("Unable to seed requested file")
                         s.close()
                         del UserLib.UpConn_map[ind]
                         continue
                     #response including peer id of current peer.
                     try:
                         self.handshake_response()
                         UserLib.SocketLock.acquire()
                         SocketLevel.send_msg(ind, -1, UserLib.UpConn_map,
                                              self.msg)
                     #Uppon Exception socket indexed by ind had been removed from "send_msg".
                     except Exception as detail:
                         print("4. Unexpected exception at Server Thread:",
                               detail)
                         UserLib.SocketLock.release()
                         self.unchoke()
                         continue
                     else:
                         UserLib.SocketLock.release()
                     #send bitmap to remote peer.
                     try:
                         self.bitfield()
                         UserLib.SocketLock.acquire()
                         SocketLevel.send_msg(ind, -1, UserLib.UpConn_map,
                                              self.msg)
                     #Uppon Exception socket indexed by ind had been removed from "send_msg".
                     except Exception as detail:
                         print("5. Unexpected exception at Server Thread:",
                               detail)
                         UserLib.SocketLock.release()
                         self.unchoke()
                         continue
                     else:
                         UserLib.SocketLock.release()
                     UserLib.UpConn_map[ind][5] = True
                     try:
                         print('\nNew Leecher:', s.getpeername(),
                               "#accepted connections:",
                               len(UserLib.UpConn_map), " ", time.time())
                     except Exception as detail:
                         print("5.1 Unexpected exception at Server Thread:",
                               detail)
                         pass
                     #and add peer identifier after a successful handshake.
                     UserLib.UpConn_map[ind][2] = self.msg_r['peer_id']
                 elif msgtype == 'interested':
                     UserLib.UpConn_map[ind][4] = 'interested'
                     if UserLib.UpConn_map[ind][5] == 'unchoked':
                         self.unchoke()
                     if self.unchokeinvoked == 0:
                         self.unchoke()
                         self.unchokeinvoked = 1
                 elif msgtype == 'uninterested':
                     UserLib.UpConn_map[ind][4] = 'uninterested'
                     if UserLib.UpConn_map[ind][3] == 'unchoked':
                         self.unchoke()
                 #acknowledgment received.
                 elif msgtype == 'have':
                     UserLib.UpConn_map[ind][6] = self.msg_r['interested']
                     #iii=[]
                     #for i in range(0,len(UserLib.UpConn_map)):
                     #	if UserLib.UpConn_map[i][4]=='interested':
                     #		iii.append(UserLib.UpConn_map[i][6])
                     #print("iii:",iii)
                     continue
                 #unexpected message.
                 else:
                     print('Unexpected message type:', msgtype)
                     continue
     #make "clean up" job.
     self.terminate()
     return
Exemplo n.º 8
0
    def unchoke(self):
        #reset timer
        self.timer.cancel()
        ##if there are active connections to your uploading set cancel and reset unchoke.
        if not UserLib.UpConn_map:
            self.unchokeflag = 0
            self.unchokeinvoked = 0
            return
        UserLib.SocketLock.acquire()

        if self.mode == 'seed':
            suggestedOpt = -1
            mymin = 10000
            #remote peers (downloaders) that were recently (less than 20 seconds) unchoked
            remotedownloaders1 = []
            #rest of remote peer
            remotedownloaders2 = []
            curtime = time.time()
            for i in range(0, len(UserLib.UpConn_map)):
                unchoketime = UserLib.UpConn_map[i][8]
                if curtime - unchoketime < UserDefs.RecentUnchokeInterval:
                    remotedownloaders1.append([unchoketime, i])
                else:
                    remotedownloaders2.append([UserLib.UpConn_map[i][7], i])
                if UserLib.UpConn_map[i][6] < mymin:
                    mymin = UserLib.UpConn_map[i][6]
                    suggestedOpt = [0, i]
            remotedownloaders1.sort(reverse=True)
            remotedownloaders2.sort(reverse=True)
            remotedownloaders = remotedownloaders1 + remotedownloaders2
            if self.unchokeflag in [0, 1]:
                if time.time(
                ) - self.lastunchoketime >= 3 * UserDefs.UnchokeInterval:
                    self.lastunchoketime = time.time()
                    if self.choice == 'optimistic':
                        self.plannedOpt = random.choice(remotedownloaders)
                    elif self.choice == 'optimal':
                        self.plannedOpt = suggestedOpt

                    try:
                        peerpos = self.plannedOpt[1]
                        UserLib.UpConn_map[peerpos][3] = 'unchoked'
                        SocketLevel.send_msg(peerpos, -1, UserLib.UpConn_map, {
                            'type': 'unchoke',
                            'mode': 'opt'
                        })
                        UserLib.UpConn_map[peerpos][8] = time.time()
                    except Exception as detail:
                        print("<unchoke>::1.Unexpected exception: ", detail)
                for i in range(0, len(remotedownloaders)):
                    peerpos = remotedownloaders[i][1]
                    if not self.plannedOpt:
                        continue
                    elif self.plannedOpt[1] == remotedownloaders[i][1]:
                        continue
                    if i < UserDefs.RegularUnchokedNum:
                        try:
                            UserLib.UpConn_map[peerpos][3] = 'unchoked'
                        except Exception as detail:
                            print("<unchoke>:: 2.Unexpected exception:",
                                  detail)
                            continue
                        msg = {'type': 'unchoke', 'mode': 'reg'}
                    else:
                        try:
                            UserLib.UpConn_map[peerpos][3] = 'choked'
                        except Exception as detail:
                            print("<unchoke>:: 2.Unexpected exception:",
                                  detail)
                            continue
                        msg = {'type': 'choke'}
                    try:
                        SocketLevel.send_msg(peerpos, -1, UserLib.UpConn_map,
                                             msg)
                        if msg['type'] == 'unchoke':
                            UserLib.UpConn_map[peerpos][8] = time.time()
                    except Exception as detail:
                        print("<unchoke>:: Unexpected exception: ", detail)
                        continue
            else:
                for i in range(0, len(remotedownloaders)):
                    peerpos = remotedownloaders[i][1]
                    if i < UserDefs.RegularUnchokedNum + 1:
                        #print("296:",peerpos,len(UserLib.UpConn_map))
                        try:
                            UserLib.UpConn_map[peerpos][3] = 'unchoked'
                        except Exception as detail:
                            print("<unchoke>:: 3.Unexpected exception:",
                                  detail)
                            continue
                        msg = {'type': 'unchoke', 'mode': 'reg'}
                    else:
                        try:
                            UserLib.UpConn_map[peerpos][3] = 'choked'
                        except Exception as detail:
                            print("<unchoke>:: 4.Unexpected exception:",
                                  detail)
                            continue
                        msg = {'type': 'choke'}
                    try:
                        SocketLevel.send_msg(peerpos, -1, UserLib.UpConn_map,
                                             msg)
                        if msg['type'] == 'unchoke':
                            UserLib.UpConn_map[peerpos][8] = time.time()
                    except Exception as detail:
                        print("<unchoke>:: Unexpected exception: ", detail)
                        continue
            #####---------------
        else:
            interestedpeers = []
            remoteuploaders = []
            suggestedOpt = -1
            mymin = 10000
            for i in range(0, len(UserLib.UpConn_map)):
                #for all remote peers (downloaders) that are interested to your content
                if UserLib.UpConn_map[i][4] == 'interested':
                    #keep their peer identifier
                    peerid = UserLib.UpConn_map[i][2]
                    interestedpeers.append([0, peerid, i])
                    if UserLib.UpConn_map[i][6] < mymin:
                        mymin = UserLib.UpConn_map[i][6]
                        suggestedOpt = [0, peerid, i]
                    #and if they are also uploaders to you
                    if peerid in [s[4] for s in UserLib.DownConn_map]:
                        #find their position in the map of your downloaders
                        peerpos = [
                            peerid == s[4] for s in UserLib.DownConn_map
                        ].index(True)
                        #and for everyone that have send you at least one block at the last 30 seconds
                        if UserLib.DownConn_map[peerpos][2] > 0 and time.time(
                        ) - UserLib.DownConn_map[peerpos][
                                8] < 3 * UserDefs.UnchokeInterval:
                            #keep position in uploading map, their peer id and number of blocks having sent to you.
                            remoteuploaders.append(
                                [UserLib.DownConn_map[peerpos][2], peerid, i])
            if len(interestedpeers) > 0:
                if self.unchokeflag == 0 and time.time(
                ) - self.lastunchoketime >= 3 * UserDefs.UnchokeInterval:
                    self.lastunchoketime = time.time()
                    if self.choice == 'optimistic':
                        self.plannedOpt = random.choice(interestedpeers)
                    elif self.choice == 'optimal':
                        self.plannedOpt = suggestedOpt
                    msg = {'type': 'unchoke', 'mode': 'opt'}
                    #print("1-->",self.plannedOpt,interestedpeers)
                    #print("Opt unchoke",peerpos);
                    try:
                        peerpos = self.plannedOpt[2]
                        UserLib.UpConn_map[peerpos][3] = 'unchoked'
                        SocketLevel.send_msg(peerpos, -1, UserLib.UpConn_map,
                                             msg)
                        UserLib.UpConn_map[peerpos][8] = time.time()
                    except Exception as detail:
                        print("<unchoke>:: 5.Unexpected exception: ", detail)
                #remote uploaders consists of [#blocks received, peerid, position at map of uploaders] for every remote uploader.
                remoteuploaders.sort(reverse=True)
                regularunchoked = []
                if not remoteuploaders:
                    regularunchoked = []
                elif len(remoteuploaders) <= UserDefs.RegularUnchokedNum:
                    regularunchoked = remoteuploaders
                else:
                    for i in range(0, UserDefs.RegularUnchokedNum):
                        regularunchoked.append(remoteuploaders[i])
                #print("remote uploaders:",remoteuploaders)
                #print("The three fastest peers(Regular Unchoked) are:",regularunchoked)
                #print("planned optimistic unchoked:",self.plannedOpt)
                #print("2-->",self.plannedOpt)
                for i in range(0, len(remoteuploaders)):
                    if remoteuploaders[i] == self.plannedOpt:
                        continue
                    try:
                        peerpos = remoteuploaders[i][2]
                        if remoteuploaders[i] in regularunchoked:
                            msg = {'type': 'unchoke', 'mode': 'reg'}
                            UserLib.UpConn_map[peerpos][3] = 'unchoked'
                        else:
                            msg = {'type': 'choke'}
                            UserLib.UpConn_map[peerpos][3] = 'choked'
                    except IndexError:
                        continue
                    try:
                        SocketLevel.send_msg(peerpos, -1, UserLib.UpConn_map,
                                             msg)
                        if msg['type'] == 'unchoke':
                            UserLib.UpConn_map[peerpos][8] = time.time()
                    except Exception as detail:
                        print("<unchoke>:: Unexpected exception: ", detail)
                        continue
                if not self.plannedOpt:
                    pass
                elif self.plannedOpt[1] in [s[1] for s in regularunchoked]:
                    while True:
                        peerpos = random.randint(0,
                                                 len(UserLib.UpConn_map) - 1)
                        peerid = UserLib.UpConn_map[peerpos][2]
                        self.plannedOpt = [0, peerid, peerpos]
                        msg = {'type': 'unchoke', 'mode': 'reg'}
                        UserLib.UpConn_map[peerpos][3] = 'unchoked'
                        try:
                            SocketLevel.send_msg(peerpos, -1,
                                                 UserLib.UpConn_map, msg)
                            UserLib.UpConn_map[peerpos][8] = time.time()
                        except Exception as detail:
                            print("<unchoke>:: Unexpected exception: ", detail)
                            continue
                        if UserLib.UpConn_map[peerpos][4] == 'interested':
                            break
        UserLib.SocketLock.release()
        #if thread has not terminated
        if UserDefs.Run:
            self.timer = threading.Timer(UserDefs.UnchokeInterval,
                                         self.unchoke)
            self.timer.start()
        self.unchokeflag = (self.unchokeflag + 1) % 3
Exemplo n.º 9
0
	def run ( self ):
		print("my peer id:",UserLib.mypeerid)
		#keep beginning time
		self.begtime=time.time()    
		random.seed(time.time())#self.begtime)
		#try to open file to write received chunks.                                                      
		try:
			self.f=open(self.filename,'wb') 
		#Uppon Exception, make clen up job and terminatethread.                  
		except IOError as detail:
			print("IOError at Leecher thread:",detail)
			self.terminate()
			return
		#Uppon Exception, make clen up job and terminate thread.
		except  Exception as detail:
			print("0.Unexpected exception in Leecher thread:",detail)
			self.terminate()
			return	
		#while thread should not terminate.
		t=self.begtime
		while UserDefs.Run:
			#If there are no peers in peer set, new connections should be established.
			#THIS WILL BE DONE IF CONNECTIONS ARE LESS THAN A THREASHOLD.
			if time.time()-t > UserDefs.PeerListReqInterval or not UserLib.DownConn_map:
				t=time.time()
				if not UserLib.DownConn_map:
					print("Empty connections")
				try:
					self.establish_connections()
				except UserLib.EstablishConnError as detail:
					print("establish connections error at Leecher thread:",detail)
					time.sleep(UserDefs.PeerListReqInterval)
					continue
				except UserLib.TerminateThread:
					break
				except Exception as detail:
					print("2.Unexpected Exception in Leecher thread:",detail)
					time.sleep(UserDefs.PeerListReqInterval)
					continue
			#NOW WE HAVE AS MUCH AS MAXDOWNCONN established connections and tokens to send requests.
			#but connections are choked.So watch the set to receive unchoke messages.
			self.sockset=[ temp[0] for temp in UserLib.DownConn_map ]
			try:
				inputready, outputready, exceptionready = select.select(self.sockset,[],[],UserDefs.SelectTimeout)
			except (ValueError, select.error) as detail:
				print("Select Exception in Leecher thread:",detail)
				continue
			#1.) In case a descripitor from your set has data that is state oriented msg. 
			for s in inputready:
				#find position of socket having data into downloading connections map
				try:
					ind=[ temp[0]==s for temp in UserLib.DownConn_map].index(True)
				except ValueError as detail:
					print("Value Error at Leecher Thread:",detail,s)
					continue
				#try to receive message via socket indexed by ind.
				try:
					UserLib.SocketLock.acquire()
					self.msg_r=SocketLevel.recv_msg(ind, -1, UserLib.DownConn_map,True)
				#Uppon Exception socket indexed by ind had been removed from "recv_msg".	
				except UserLib.ConnectionResetedByPeer:
					print("3.ConnectionResetedByPeer in Leecher thread:")
					continue
				except Exception as detail:
					print("3.Unexpected Exception in Leecher thread:",detail)
					continue
				finally:
					UserLib.SocketLock.release()
				try:
					msgtype=self.msg_r['type']
				except Exception as detail:
					print("4.Unexpected Exception in Leecher thread:",detail)
					continue
				if msgtype == 'unchoke':
					if self.unchokes == 0:
						print("First unchoke after:%.2f"%(time.time()-self.begtime),"seconds")
					self.unchokes+=1
					UserLib.DownConn_map[ind][5]='unchoked'
				elif msgtype == 'choke':
					UserLib.DownConn_map[ind][5]='choked'
					#delete pending requests to chocking remote peer.
					UserLib.requests=[ r for r in UserLib.requests if not r[1] == UserLib.DownConn_map[ind][4]]
				elif msgtype == 'have':
					#update bitmap of peer having a new piece
					try:
						bitmap.bmp_setvalid(UserLib.DownConn_map[ind][3],self.msg_r['chunkno'],-1)
						#check if you are interested in this peer
						state=bitmap.interested(UserLib.bmp,UserLib.DownConn_map[ind][3],UserLib.BMPLENGTH,UserLib.lock)
						#if there is a change in your state about this peer
					except Exception:
						continue
					if UserLib.DownConn_map[ind][6]== 'uninterested' and state=='interested':
						#inform your map
						UserLib.DownConn_map[ind][6]=state
						#inform remote peer
						try:
							self.interested()
							UserLib.SocketLock.acquire()
							SocketLevel.send_msg(ind,-1,UserLib.DownConn_map,self.msg,True)
						except Exception as detail:
							print("5.Unexpected Exception in Leecher thread:",detail)
							continue
						finally:
							UserLib.SocketLock.release()
				#if received message is "block respose" 
				#try to write block to resective position in file.:
				elif msgtype == 'block':
					chunkno=self.msg_r['chunkpos']
					try:
						self.block(ind,self.msg_r)
					#Exception indication requested block is not available
					#to peer last request was send.
					except UserLib.BlockCorrupted:
						print("6.BlockCorrupted in Leecher thread:")
						continue
					except UserLib.UnexpectedBlock:
						#print("6.UnexpectedBlock in Leecher thread:")
						continue
					#Uppon Exception Terminate thread
					except Exception as detail:
						print("6.Unexpected Exception in Leecher thread:",detail)
						continue
					self.have(chunkno)
					try:
						UserLib.SocketLock.acquire()
						SocketLevel.send_msg(ind,-1,UserLib.DownConn_map,self.msg,True)
					except Exception as detail:
						print("7.1.Unexpected Exception in Leecher thread:",detail)
						continue
					finally:
						UserLib.SocketLock.release()
					i=len(UserLib.UpConn_map)-1
					UserLib.SocketLock.acquire()
					while i >=0:
						try:
							if UserLib.DownConn_map[ind][4]==UserLib.UpConn_map[i][2]:
								i-=1
								continue
						except Exception as detail:
							i-=1
							print("7.1.2.Unexpected Exception in Lecher thread:",detail,ind,UserLib.UpConn_map,UserLib.DownConn_map)
							continue
						#inform all downloaders directly conected to you that you
						#receive a new piece.
						try:
							#UserLib.SocketLock.acquire()
							SocketLevel.send_msg(i,-1,UserLib.UpConn_map,self.msg)
						except Exception as detail:
							i=len(UserLib.UpConn_map)-1
							print("7.2.Unexpected Exception in Lecher thread:",detail,i,len(UserLib.UpConn_map))
						else:
							i-=1
						#finally:
						#	UserLib.SocketLock.release()	
					UserLib.SocketLock.release()
					for i in range(0,len(UserLib.DownConn_map)):		
						try:
							state=bitmap.interested(UserLib.bmp,UserLib.DownConn_map[i][3],UserLib.BMPLENGTH,UserLib.lock)
						except Exception:
							continue
						if UserLib.DownConn_map[i][6]=='interested' and state=='uninterested':
							UserLib.DownConn_map[i][6]=state
							try:
								#print("here",UserLib.DownConn_map,UserLib.bmp)
								self.uninterested()
								UserLib.SocketLock.acquire()
								SocketLevel.send_msg(i,-1,UserLib.DownConn_map,self.msg,True)
							except Exception as detail:
								print("9.Unexpected Exception in Leecher thread:",detail)
								continue
							finally:
								UserLib.SocketLock.release()
			#select block and uploader.
			try:
				ind, self.blockno =self.select_block()
			except UserLib.FileCompletelyDownloaded:
				break
			except  UserLib.AllConnectionsChoked:
				#print("11.AllConnectionsChoked or unintetresting in Leecher thread")
				continue
			except  UserLib.MaxRequestsSent:
				#print("11.MaxRequestsSent in Leecher thread")
				continue
			except Exception as detail:
				print("11.Unexpected Exception in Leecher thread:",detail)
				break
			#if it is a pending block request, dont do anything.
			#prepare request for the selected block.
			self.request(self.blockno)
			try:
				UserLib.SocketLock.acquire()
				SocketLevel.send_msg(ind,-1,UserLib.DownConn_map,self.msg,True)
			except Exception as detail:
				print("12.Unexpected Exception in Leecher thread:",detail)
				continue
			else:
				UserLib.requests.append([self.blockno,UserLib.DownConn_map[ind][4],0])
			finally:
				UserLib.SocketLock.release()
		#while Run
		#make "clen up" job and terminate thread.
		self.terminate()
		return
Exemplo n.º 10
0
def main():

	global msg, msg_r	
	if not  len(sys.argv) in [7,8]:
		print("Usage:",sys.argv[0],"(<trackerip> <trackerport>) <listeningport> <seed/peer> <filename> <optimistic/optimal> [<create metadata file>]")
		return

	#assign command line arguments to local variables
	trackerip=socket.gethostbyname(sys.argv[1])
	trackerport=int(sys.argv[2])
	listeningport=int(sys.argv[3])	
	hostname=socket.gethostname()
	listeningip=socket.gethostbyname(hostname)
	mode=sys.argv[4]
	filename=sys.argv[5]
	choice=sys.argv[6]
	print(trackerip,trackerport,listeningip,listeningport,mode,filename,choice)

	#The first uploader is also the creator of metadata file.
	#All other peers receiving metadata file from a site
	#acting as a global directory.
	if len(sys.argv) == 8 and  sys.argv[7] == "create":		
		metadata_dict=metadataLib.create_metadatafile(filename)
	else:
		metadata_dict=metadataLib.read_metadatafile(filename)		
	print("size of metadata")
	
	if mode == "peer":
	      #create file so that following server and leecher thread open it.
	      try:
		      filename=filename+str(listeningport)
		      f=open(filename,'wb+')
	      #Uppon Exception, make clen up job and terminatethread.                  
	      except IOError as detail:
		      print("IOError:",detail)
		      return
	      #Uppon Exception, make clen up job and terminate thread.
	      except  Exception as detail:
		      print("0.Unexpected exception:",detail)
		      return
	      else:
		      f.close()


	
	
	#initialize bitmap, sha1's of each chunk and file identifier(metadata hash).	
	UserLib.BMPLENGTH=math.ceil(metadata_dict['filesize']/UserDefs.PieceSize)
	bitmap.bmp_init(UserLib.bmp,UserLib.BMPLENGTH)     
	UserLib.sha1s_map=metadata_dict['sha1s_map']
	UserLib.metadata_hash=metadata_dict['metadata_hash']
	#print("metadata_hash",UserLib.metadata_hash)
	#In seeder mode all blocks are available. 
	if mode == "seed":            	
		bitmap.bmp_setallvalid(UserLib.bmp,UserLib.BMPLENGTH)			

	#creation of a socket to establish  TCP connection with coordinator.
	try:
		tracker = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )     
		tracker.connect((trackerip,trackerport ))                   	
	except socket.error as detail:
		print("Tracker communication Socket error",detail)
		return
	except Exception as detail:
		print("Unexpected Exception:",detail)
		return	
	
	#prepare a "join_swarm" message" to send to coordinator. 
	join_swarm(metadata_dict['filename'],metadata_dict['filesize'],metadata_dict['FileMd5'],listeningip,listeningport)	
	try:	
		SocketLevel.send_msg(-1,tracker,[],msg)
	except Exception as detail:
		print("Unexpected Exception:",detail)
		tracker.close()
		return

	#receive a "join_response" message from coordinator.
	try:	
		msg_r=SocketLevel.recv_msg(-1,tracker,[])
	except Exception as detail:
		print("Unexpected Exception:",detail)
		tracker.close()
		return		
	#upon successful communication retrieve your peer identifier.
	else:
		UserLib.mypeerid=msg_r['peerid']

	#constructor of "ServerThread" for that peer
	#size, md5 and name of file to seed
	#port and ip listening for requests of TCP connections
	#socket of established connection with coordinator.
	Sthread=ServerThread.ServerThread(metadata_dict['filesize'],metadata_dict['FileMd5'],filename,listeningport,listeningip,mode,choice,tracker)
	Sthread.start()

	#constructor of "LeecherThread" for that peer-if not in seeder mode.
	if mode == "peer":                                      
		Lthread=LeecherThread.LeecherThread(metadata_dict['filesize'],metadata_dict['FileMd5'],filename,listeningport,listeningip,tracker)
		Lthread.start()

	#Main Thread waiting threads to terminate.
	Sthread.join()
	if sys.argv[3] == "peer":
		Lthread.join()
	tracker.close()
	print('Programm is going to terminate')
	return
Exemplo n.º 11
0
def establish_connection(listeningports,listeningips,peerids,connections,i):

	#try to create a socket and send a TCP connection request to each peer of the set.
	try:
		newsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
		newsock.connect ((listeningips[i], listeningports[i]))
	#Uppon Exception close recently created socket and raise Exception.
	except socket.error:
		print("<establish_connection>:: Socket Error Unable to establish connection with peer at port:",listeningports[i])
		newsock.close()
		raise
	#Uppon Exception close recently created socket and raise Exception.
	except Exception as detail:
		print("<establish_connection>:: Unexpected exception Unable to establish connection with peer at port:",listeningports[i],":",detail)
		newsock.close()
		raise
	#Uppon success, append to connections map a tuple containing (socket, port, 
	#counter of blocks received, bitmap, peerid, and state info) of recently 
	#established connection.
	connections.append([newsock,listeningports[i],0,[],0,'choked','',listeningips[i],0])
	#create and send handshake message
	msg={'type':'handshake'
		,'metadata_hash':UserLib.metadata_hash
		,'peer_id':UserLib.mypeerid
	}
	try:
		SocketLevel.send_msg(len(connections)-1,-1,connections,msg, True)
	except Exception as detail: 
		print("<establish_connection>:: 1.Unable to establish connection with peer at port:",listeningports[i],":",detail)
		raise
	#receive handshake response
	try:	
		msg_r=SocketLevel.recv_msg(len(connections)-1, -1, connections, True)
	except Exception as detail:  
		print("<establish_connection>:: 2.Unable to establish connection with peer at port:",listeningports[i],":",detail)
		raise
	else:	
		#if not a handshake response received, ro peed id received is not valid.	
		if not msg_r['type'] == 'handshake_response' or not msg_r['peerid'] in peerids:
			print("------------------------>",msg_r)
			newsock.close()
			#remove socket from connections map.
			del connections[-1]
			raise UserLib.UnexpectedMessage
		else:	
			#keep peer id from last message.
			peerid=msg_r['peerid']
			#receive bitmap of recently appened peer.
			try:	
				msg_r=SocketLevel.recv_msg(len(connections)-1, -1, connections,True)
			except Exception as detail:  
				print("<establish_connection>:: 4.Unable to establish connection with peer at port:",listeningports[i],":",detail)
				raise
			if not msg_r['type'] == 'bitfield':
				newsock.close()
				#remove socket from connections map.
				del connections[-1]
				raise UserLib.UnexpectedMessage
			connections[-1][3]=msg_r['bmp']   
			connections[-1][4]=peerid
			#check if u are interested in blocks of this remote peer or not.
			try:
				connections[-1][6]=bitmap.interested(UserLib.bmp,msg_r['bmp'],msg_r['bmplen'],UserLib.lock)
			except Exception as detail:
				print("<establish_connection>:: 5.Unable to establish connection with peer at port:",listeningports[i],":",detail)
				#remove socket from connections map.
				del connections[-1]
				raise
			if connections[-1][6]=='uninterested':
				msg={'type':'uninterested'}	
			else:
				msg={'type':'interested'}
			#inform this remote peer if interested or not.
			try:
				SocketLevel.send_msg(len(connections)-1,-1,connections,msg,True)
			except Exception as detail: 
				print("<establish_connection>:: 6.Unable to establish connection with peer at port:",listeningports[i],":",detail)
				raise
Exemplo n.º 12
0
	def run (self):
		random.seed(time.time())
		#create a socket, bind it to your listening ip and port 
		#in order to listen for incoming TCP connection requests.
		try:
			server = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )   
			server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
			server.bind((self.listeningip, self.listeningport))
			server.listen ( 1 )
		#Uppon Exception close listening socket and terminate thread.
		except (socket.error,socket.gaierror,OverflowError) as detail:
			print("Listening Socket error:",detail)
			server.close()
			UserDefs.Run=False
			return			
		#Open file to seed.
		try:
			self.f=open(self.filename,'rb')
		except IOError as detail:
			print("IOError Opening File",detail)
			self.terminate()
		except Exception as detail:
			print("Unexpected Exception opening file at server thread:",detail)
			self.terminate()
		#Loop forever
		while UserDefs.Run:
			self.sockset=[ temp[0] for temp in UserLib.UpConn_map ]
			if len(UserLib.UpConn_map)==UserDefs.ActiveSetSize:
				#print("max size")
				self.sockset=self.sockset+[sys.stdin]
			else:
				self.sockset=self.sockset+[server,sys.stdin]
			# wait till a socket has data.
			try:
				inputready, outputready, exceptionready = select.select(self.sockset,[],[])
			except ValueError as detail:
				print("select at server thread:",detail,self.sockset)		
			#search on which socket there are available data.
			for s in inputready:
				#if it is in server socket, it is a TCP connection request.
				if s == server:
					if len(UserLib.UpConn_map)==UserDefs.ActiveSetSize:
						continue
					try:
						conn, addr=server.accept()
						conn.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
					except socket.timeout:
						print("timeout")
						pass
					except Exception as detail: 	
						print("Accepting connection error:",detail)
					#Uppon success, append socket into watched set.	
					#append socket, peer ip and port, peer id and connection's
					#state info to Uploading connections map.
					else:
						#if len(UserLib.UpConn_map)>=UserDefs.ActiveSetSize:
						#	print("here")
						#	conn.close()
						#	continue						
						self.sockset.append(conn)
						UserLib.UpConn_map.append([conn,conn.getpeername(),0,'choked','uninterested',False,0,0,0])
				elif s == sys.stdin:
					##command = s.readline()
					##if command == 'quit\n':
					UserDefs.Run=False
					break
				#otherwise there are data in socket of an established connection.
				else:	
					#find position of current socket into uploading connections map
					try:
						ind=[ temp[0]==s for temp in UserLib.UpConn_map].index(True)
					except ValueError as detail:
						print("Unable to index connection at server Thread:",detail,s)
						continue
					#try to receive message via socket indexed by ind.
					try:
						UserLib.SocketLock.acquire()
						self.msg_r=SocketLevel.recv_msg(ind, -1, UserLib.UpConn_map)
					#Uppon Exception socket indexed by ind had been removed from "recv_msg".
					except UserLib.ConnectionResetedByPeer:
						print("2. ConnectionResetedByPeer at Server Thread:")
						UserLib.SocketLock.release()
						self.unchoke()
						continue	
					except Exception as detail:
						print("2. Unexpected exception at Server Thread:",detail)
						UserLib.SocketLock.release()
						self.unchoke()
						continue
					else:
						UserLib.SocketLock.release()
					try:
						msgtype = self.msg_r['type']
					except Exception as detail:
						print("Key error at Server Thread:",detail)
						self.unchoke()
						continue
					#if message is a "block request"
					if msgtype == 'request':
						#create and send response via socket s.
						try:
							self.block(self.msg_r)
							UserLib.SocketLock.acquire()
							SocketLevel.send_msg(ind,-1,UserLib.UpConn_map,self.msg)
							UserLib.UpConn_map[ind][7]+=1
						#Uppon Exception socket indexed by ind had been removed from "send_msg".
						except Exception as detail:
							print("3. Unexpected exception at Server Thread:",detail)
							UserLib.SocketLock.release()
							self.unchoke()
							continue
						else:
							UserLib.SocketLock.release()
					#if message is a "handshake request"
					elif msgtype == 'handshake':
						#check file id of requested file.
						#Connection should be closed	
						if not self.msg_r['metadata_hash'] == UserLib.metadata_hash :
							print("Unable to seed requested file")
							s.close()
							del UserLib.UpConn_map[ind]
							continue	
						#response including peer id of current peer.
						try:
							self.handshake_response()
							UserLib.SocketLock.acquire()
							SocketLevel.send_msg(ind,-1,UserLib.UpConn_map,self.msg)
						#Uppon Exception socket indexed by ind had been removed from "send_msg".
						except Exception as detail:
							print("4. Unexpected exception at Server Thread:",detail)
							UserLib.SocketLock.release()
							self.unchoke()
							continue
						else:
							UserLib.SocketLock.release()
						#send bitmap to remote peer.
						try:
							self.bitfield()
							UserLib.SocketLock.acquire()
							SocketLevel.send_msg(ind,-1,UserLib.UpConn_map,self.msg)
						#Uppon Exception socket indexed by ind had been removed from "send_msg".
						except Exception as detail:
							print("5. Unexpected exception at Server Thread:",detail)
							UserLib.SocketLock.release()
							self.unchoke()
							continue
						else:
							UserLib.SocketLock.release()
						UserLib.UpConn_map[ind][5]=True
						try:
							print('\nNew Leecher:',s.getpeername(),"#accepted connections:",len(UserLib.UpConn_map)," ",time.time())
						except Exception as detail:
							print("5.1 Unexpected exception at Server Thread:",detail)
							pass
						#and add peer identifier after a successful handshake.
						UserLib.UpConn_map[ind][2]=self.msg_r['peer_id']
					elif msgtype == 'interested':
						UserLib.UpConn_map[ind][4]='interested'	
						if UserLib.UpConn_map[ind][5]=='unchoked':
							self.unchoke()
						if self.unchokeinvoked == 0:
							self.unchoke()
							self.unchokeinvoked=1
					elif msgtype == 'uninterested':
						UserLib.UpConn_map[ind][4]='uninterested'
						if UserLib.UpConn_map[ind][3]=='unchoked':
							self.unchoke()
					#acknowledgment received.
					elif msgtype == 'have':
						UserLib.UpConn_map[ind][6]=self.msg_r['interested']
						#iii=[]
						#for i in range(0,len(UserLib.UpConn_map)):
						#	if UserLib.UpConn_map[i][4]=='interested':
						#		iii.append(UserLib.UpConn_map[i][6])
						#print("iii:",iii)
						continue
					#unexpected message.				
					else:
						print('Unexpected message type:',msgtype)
						continue	
		#make "clean up" job.	
		self.terminate()
		return
Exemplo n.º 13
0
	def unchoke(self):
		#reset timer
		self.timer.cancel()
		##if there are active connections to your uploading set cancel and reset unchoke.
		if not UserLib.UpConn_map:
			self.unchokeflag=0
			self.unchokeinvoked=0
			return
		UserLib.SocketLock.acquire()
		
		if self.mode == 'seed':
			suggestedOpt=-1
			mymin=10000
			#remote peers (downloaders) that were recently (less than 20 seconds) unchoked
			remotedownloaders1=[]	
			#rest of remote peer
			remotedownloaders2=[]			
			curtime=time.time()			
			for i in range(0,len(UserLib.UpConn_map)):
				unchoketime=UserLib.UpConn_map[i][8]
				if curtime-unchoketime<UserDefs.RecentUnchokeInterval:
					remotedownloaders1.append([unchoketime,i])
				else:
					remotedownloaders2.append([UserLib.UpConn_map[i][7],i])
				if UserLib.UpConn_map[i][6]<mymin:
					mymin=UserLib.UpConn_map[i][6]
					suggestedOpt=[0,i]
			remotedownloaders1.sort(reverse=True)
			remotedownloaders2.sort(reverse=True)
			remotedownloaders=remotedownloaders1+remotedownloaders2
			if self.unchokeflag in [0,1]:
				if time.time()-self.lastunchoketime>=3*UserDefs.UnchokeInterval:
					self.lastunchoketime=time.time()
					if self.choice == 'optimistic':
						self.plannedOpt=random.choice(remotedownloaders)
					elif self.choice == 'optimal':
						self.plannedOpt=suggestedOpt
					
					try:
						peerpos=self.plannedOpt[1]
						UserLib.UpConn_map[peerpos][3]='unchoked'
						SocketLevel.send_msg(peerpos,-1,UserLib.UpConn_map,{'type':'unchoke','mode':'opt'})
						UserLib.UpConn_map[peerpos][8]=time.time()
					except Exception as detail:
						print("<unchoke>::1.Unexpected exception: ",detail) 
				for i in range(0,len(remotedownloaders)):
					peerpos=remotedownloaders[i][1]
					if not self.plannedOpt:
						continue
					elif self.plannedOpt[1]==remotedownloaders[i][1]:
						continue
					if i<UserDefs.RegularUnchokedNum:
						try:
							UserLib.UpConn_map[peerpos][3]='unchoked'
						except Exception as detail:
							print("<unchoke>:: 2.Unexpected exception:",detail)
							continue
						msg={'type':'unchoke','mode':'reg'}
					else:
						try:
							UserLib.UpConn_map[peerpos][3]='choked'
						except Exception as detail:
							print("<unchoke>:: 2.Unexpected exception:",detail)
							continue
						msg={'type':'choke'}
					try:
						SocketLevel.send_msg(peerpos,-1,UserLib.UpConn_map,msg)
						if msg['type'] == 'unchoke':
							UserLib.UpConn_map[peerpos][8]=time.time()
					except Exception as detail:
						print("<unchoke>:: Unexpected exception: ",detail) 
						continue
			else:
				for i in range(0,len(remotedownloaders)):
					peerpos=remotedownloaders[i][1]
					if i<UserDefs.RegularUnchokedNum+1:
						#print("296:",peerpos,len(UserLib.UpConn_map))
						try:
							UserLib.UpConn_map[peerpos][3]='unchoked'
						except Exception as detail:
							print("<unchoke>:: 3.Unexpected exception:",detail)
							continue
						msg={'type':'unchoke','mode':'reg'}
					else:
						try:
							UserLib.UpConn_map[peerpos][3]='choked'
						except Exception as detail:
							print("<unchoke>:: 4.Unexpected exception:",detail)
							continue
						msg={'type':'choke'}
					try:
						SocketLevel.send_msg(peerpos,-1,UserLib.UpConn_map,msg)
						if msg['type'] == 'unchoke':
							UserLib.UpConn_map[peerpos][8]=time.time()
					except Exception as detail:
						print("<unchoke>:: Unexpected exception: ",detail) 
						continue			
			#####---------------
		else:
			interestedpeers=[]
			remoteuploaders=[]
			suggestedOpt=-1
			mymin=10000
			for i in range(0,len(UserLib.UpConn_map)):
				#for all remote peers (downloaders) that are interested to your content
				if UserLib.UpConn_map[i][4]=='interested':
					#keep their peer identifier
					peerid=UserLib.UpConn_map[i][2]
					interestedpeers.append([0,peerid,i])
					if UserLib.UpConn_map[i][6]<mymin:
						mymin=UserLib.UpConn_map[i][6]
						suggestedOpt=[0,peerid,i]
					#and if they are also uploaders to you
					if peerid in [ s[4] for s in UserLib.DownConn_map ]:
						#find their position in the map of your downloaders
						peerpos=[ peerid==s[4] for s in UserLib.DownConn_map].index(True)
						#and for everyone that have send you at least one block at the last 30 seconds
						if UserLib.DownConn_map[peerpos][2]>0 and time.time()-UserLib.DownConn_map[peerpos][8]<3*UserDefs.UnchokeInterval:
							#keep position in uploading map, their peer id and number of blocks having sent to you.
							remoteuploaders.append([UserLib.DownConn_map[peerpos][2],peerid,i])
			if len(interestedpeers)>0:
				if self.unchokeflag==0 and time.time()-self.lastunchoketime>=3*UserDefs.UnchokeInterval:
					self.lastunchoketime=time.time()
					if self.choice == 'optimistic':
						self.plannedOpt=random.choice(interestedpeers)
					elif self.choice == 'optimal':
						self.plannedOpt=suggestedOpt
					msg={'type':'unchoke','mode':'opt'}
					#print("1-->",self.plannedOpt,interestedpeers)
					#print("Opt unchoke",peerpos);
					try:
						peerpos=self.plannedOpt[2]
						UserLib.UpConn_map[peerpos][3]='unchoked'
						SocketLevel.send_msg(peerpos,-1,UserLib.UpConn_map,msg)
						UserLib.UpConn_map[peerpos][8]=time.time()
					except Exception as detail:
						print("<unchoke>:: 5.Unexpected exception: ",detail) 
				#remote uploaders consists of [#blocks received, peerid, position at map of uploaders] for every remote uploader.
				remoteuploaders.sort(reverse=True)
				regularunchoked=[]	
				if not remoteuploaders:
					regularunchoked=[]
				elif len(remoteuploaders)<=UserDefs.RegularUnchokedNum:
					regularunchoked=remoteuploaders
				else:
					for i in range(0,UserDefs.RegularUnchokedNum):
						regularunchoked.append(remoteuploaders[i])
				#print("remote uploaders:",remoteuploaders)
				#print("The three fastest peers(Regular Unchoked) are:",regularunchoked)
				#print("planned optimistic unchoked:",self.plannedOpt)
				#print("2-->",self.plannedOpt)
				for i in range(0,len(remoteuploaders)):
					if remoteuploaders[i] == self.plannedOpt:
						continue
					try:
						peerpos=remoteuploaders[i][2]
						if remoteuploaders[i] in regularunchoked:
							msg={'type':'unchoke','mode':'reg'}
							UserLib.UpConn_map[peerpos][3]='unchoked'
						else:
							msg={'type':'choke'}
							UserLib.UpConn_map[peerpos][3]='choked'
					except IndexError:
						continue
					try:
						SocketLevel.send_msg(peerpos,-1,UserLib.UpConn_map,msg)
						if msg['type']=='unchoke':
							UserLib.UpConn_map[peerpos][8]=time.time()
					except Exception as detail:
						print("<unchoke>:: Unexpected exception: ",detail) 
						continue
				if not self.plannedOpt:
					pass
				elif self.plannedOpt[1] in  [ s[1] for s in regularunchoked ]:
					while True:
						peerpos=random.randint(0,len(UserLib.UpConn_map)-1)
						peerid=UserLib.UpConn_map[peerpos][2]
						self.plannedOpt=[0,peerid,peerpos]
						msg={'type':'unchoke','mode':'reg'}
						UserLib.UpConn_map[peerpos][3]='unchoked'
						try:
							SocketLevel.send_msg(peerpos,-1,UserLib.UpConn_map,msg)	
							UserLib.UpConn_map[peerpos][8]=time.time()
						except Exception as detail:
							print("<unchoke>:: Unexpected exception: ",detail) 
							continue
						if UserLib.UpConn_map[peerpos][4] == 'interested':
							break	
		UserLib.SocketLock.release()
		#if thread has not terminated
		if UserDefs.Run:
			self.timer=threading.Timer(UserDefs.UnchokeInterval,self.unchoke)
			self.timer.start()
		self.unchokeflag=(self.unchokeflag+1)%3