Esempio n. 1
0
    def __init__(self, cwd):
        self.__cwd = cwd  # current working directory
        self.__BootedasUser = True
        self.__tcpTracSock = Mytcpsocket()
        self.__tcpListenSock = Mytcpsocket()
        self.__MaxNumConn = MAX_PEER_CONNECTION
        self.__Addr = (([
            ip for ip in gethostbyname_ex(gethostname())[2]
            if not ip.startswith("127.")
        ][0]), choice(range(50000, 60000)))

        self.__tcpCliSockets = []
        self.__ServerNeighborhood = []
        self.__ServerConnectionIPs = []
        self.__ServerConnectionSocks = []
        self.__NumofConnections = 0
        self.__ExcludedServerAddr = []
        self.__choketimer = 30
        self.__StartWaiting = False

        self.__receivedFile = None  # streaming file object
        self.__avaiMovieList = {}  # available movie list from the tracker
        self.__movieHashNames = {}
        self.__currentvid = 'None'  # current video that is being watched
        self.__NumofChunks = 0
        self.__NumofLeftPieces = 0

        self.__neighborLock = thread.allocate_lock(
        )  # lock for the neighborhood update
        self.__connectionLock = thread.allocate_lock()
        self.__timerLock = thread.allocate_lock()
        self.__streamingStatLock = thread.allocate_lock()
        self.__bufferStatLock = thread.allocate_lock()
        self.__emptyAvailable = threading.Event()
        self.__emptyAvailable.clear()
        # one of the download chunks is waiting for other corresponding threads to finish that chunk
        self.__DownloadWait = threading.Event()
        self.__DownloadWait.clear()
        # wait till download is finished
        self.__BufferFullWait = threading.Event()
        self.__BufferFullWait.clear()
        # buffer too much, wait before download
        self.__BufferEmptyWait = threading.Event()
        self.__BufferEmptyWait.clear()
        # buffer not enough, download from server
        self.__streamingWait = threading.Event()
        self.__streamingWait.clear()
        # wait till buffer is ready to stream
        self.__downloadthreads = []
        self.__EXIT = False
Esempio n. 2
0
 def __Connect2Client(self, number):
     self.__connectionLock.acquire()
     self.__neighborLock.acquire()
     Neighborhood = lminus(self.__ClientNeighborhood,
                           self.__ClientConnectionIPs)
     potentialconnect = sample(Neighborhood, min(len(Neighborhood), number))
     for eachClient in potentialconnect:
         if self.__NumofConnections < self.__MaxNumConn:
             if eachClient not in self.__ClientConnectionIPs:
                 cliSock = Mytcpsocket()
                 ack1 = cliSock.Connect2Server(eachClient)
                 ack2 = cliSock.sendmsg(self.__Addr[1])
                 ack3 = cliSock.recvmsg(BUFSIZ)  # receive ACK
                 if ack1 and ack2 and ack3 != 'closed':
                     self.__NumofConnections += 1
                     self.__ClientConnectionSocks.append(cliSock)
                     self.__ClientConnectionIPs.append(eachClient)
                     t = MyThread(self.__upload, (cliSock, eachClient),
                                  self.__upload.__name__)
                     self.__UploadThreadsLock.acquire()
                     self.__UploadThreads.append(t)
                     self.__UploadThreadsLock.release()
                     self.__BWControlBoot.set()
                     # start BW control
                     self.__RateAllocBoot.set()
                     # start rate allocation
                     t.start()
                     sleep(PROCESS_TIME)
                 else:
                     self.__ClientNeighborhood.remove(eachClient)
         else:
             break
     self.__connectionLock.release()
     self.__neighborLock.release()
Esempio n. 3
0
 def __Connect2Server(self, *targs):
     args = targs[0]
     number = args[0]
     videohash = args[1]
     self.__connectionLock.acquire()
     self.__neighborLock.acquire()
     Neighborhood = lminus(self.__ServerNeighborhood,
                           self.__ServerConnectionIPs)
     potentialconnect = sample(Neighborhood, min(len(Neighborhood), number))
     for eachServer in potentialconnect:
         if self.__NumofConnections < self.__MaxNumConn:
             if eachServer not in self.__ServerConnectionIPs:
                 servSock = Mytcpsocket()
                 ack1 = servSock.Connect2Server(eachServer)
                 ack2 = servSock.sendmsg(self.__Addr[1])
                 ack3 = servSock.recvmsg(BUFSIZ)  # receive ACK
                 if ack1 and ack2 and ack3 != 'closed':
                     self.__NumofConnections += 1
                     self.__ServerConnectionSocks.append(servSock)
                     self.__ServerConnectionIPs.append(eachServer)
                     t = MyThread(self.__download,
                                  (servSock, eachServer, videohash),
                                  self.__download.__name__)
                     t.start()
                     sleep(PROCESS_TIME)
                     self.__downloadthreads.append(t)
                 else:
                     self.__ServerNeighborhood.remove(eachServer)
         else:
             break
     self.__connectionLock.release()
     self.__neighborLock.release()
Esempio n. 4
0
 def __WaitforConnection(self, *targs):
     self.__tcpListenSock.InitServSock(self.__Addr, self.__MaxNumConn)
     while True:
         if self.__EXIT:
             return
         (tcpServSock, SERVER_ADDR) = self.__tcpListenSock.WaitforConn()
         self.__connectionLock.acquire()
         servtcpsock = Mytcpsocket(tcpServSock)
         if self.__NumofConnections < self.__MaxNumConn:
             servport = servtcpsock.recvmsg(BUFSIZ)
             ack = servtcpsock.sendmsg('ACK')  # send ACK
             SERVER_SERV_ADDR = (SERVER_ADDR[0], servport)
             if ((SERVER_SERV_ADDR in self.__ServerConnectionIPs)
                     or (SERVER_SERV_ADDR == self.__ExcludedServerAddr)
                     or (not ack) or servport == 'closed'):
                 servtcpsock.close()
             else:
                 self.__ServerConnectionSocks.append(servtcpsock)
                 self.__ServerConnectionIPs.append(SERVER_SERV_ADDR)
                 self.__NumofConnections += 1
                 if VERBOSE:
                     print "...connected from:", SERVER_SERV_ADDR
                 t = MyThread(
                     self.__download,
                     (servtcpsock, SERVER_SERV_ADDR, self.__currentvid),
                     self.__download.__name__)
                 t.start()
                 sleep(PROCESS_TIME)
                 self.__downloadthreads.append(t)
         else:
             servtcpsock.close(
             )  # close if the number of connections exceeds max
         self.__connectionLock.release()
Esempio n. 5
0
 def __init__(self, Tracker_Addr=TRACKER_ADDRESS):
     self.__socket = Mytcpsocket()  # a new socket
     self.__Addr = Tracker_Addr  # IP address + port
     self.__MaxNumConn = MAX_TRAC_CONNECTION
     self.__userDict = {}  # connecting addresses of active (estimate) users
     self.__servDict = {
     }  # connecting addresses of active (estimate) helpers
     #self.__servDict[MEDIA_SERVER_ADDRESS] = 1      # the central server
     self.__inputLock = thread.allocate_lock(
     )  # lock for the input variables
     self.__EXIT = 0  # exit the system or not
     self.__movieList = {}  # list of movie names
Esempio n. 6
0
 def __commtotracker(self, *targs):
     ack = False
     while not ack:
         ack = self.__tcpTracSock.Connect2Server(TRACKER_ADDRESS)
         if ack:
             countdown = 0
             while True:
                 if countdown == 0:
                     ack = self.__tcpTracSock.sendmsg('serv+' +
                                                      repr(self.__Addr[1]))
                     newneighborhood = self.__tcpTracSock.recvmsg(BUFSIZ)
                     avaiMovieList = self.__tcpTracSock.recvmsg(BUFSIZ)
                     if (
                             not ack
                     ) or newneighborhood == 'closed' or avaiMovieList == 'closed':
                         ack = False
                         break
                     ACK = 'ACK'
                     if self.__isserver:
                         movienames = ""
                         for fhash, fname in self.__movieList.iteritems():
                             movienames = (movienames + '+' + fname + '#' +
                                           self.__videoStat[fhash][0] +
                                           '#' + self.__videoStat[fhash][1])
                         ack = self.__tcpTracSock.sendmsg('list' +
                                                          movienames)
                         ACK = self.__tcpTracSock.recvmsg(BUFSIZ)
                         if (not ack) or ACK == 'closed':
                             ack = False
                             break
                     else:
                         del self.__videoStat
                         self.__videoStat = {}
                         for eachmovie in avaiMovieList.keys():
                             self.__videoStat[hashlib.md5(
                                 eachmovie).hexdigest(
                                 )] = avaiMovieList[eachmovie]
                     self.__neighborLock.acquire()
                     self.__ClientNeighborhood = union(
                         self.__ClientNeighborhood, newneighborhood)
                     ## might have to set a maximum limit of neighborhood ##
                     self.__neighborLock.release()
                     countdown = OBTAIN_NEIGHBOR_PERIOD / INTERVAL_TRACKER_COMMUNICATION
                 else:
                     ack = self.__tcpTracSock.sendmsg('alive')
                     if not ack:
                         break
                     sleep(INTERVAL_TRACKER_COMMUNICATION)
                     countdown -= 1
         sleep(TRY_INTERVAL)
         del self.__tcpTracSock
         self.__tcpTracSock = Mytcpsocket()
Esempio n. 7
0
 def __commtotracker(self, *targs):
     ack = False
     while not ack:
         if self.__EXIT:
             return
         ack = self.__tcpTracSock.Connect2Server(TRACKER_ADDRESS)
         #print TRACKER_ADDRESS
         if ack:
             countdown = 0
             while True:
                 if self.__EXIT:
                     return
                 if countdown == 0:
                     ack = self.__tcpTracSock.sendmsg('user+' +
                                                      repr(self.__Addr[1]))
                     newneighborhood = self.__tcpTracSock.recvmsg(BUFSIZ)
                     self.__avaiMovieList = self.__tcpTracSock.recvmsg(
                         BUFSIZ)
                     if (
                             not ack
                     ) or newneighborhood == 'closed' or self.__avaiMovieList == 'closed':
                         ack = False
                         break
                     del self.__movieHashNames
                     self.__movieHashNames = {}
                     for eachmovie in self.__avaiMovieList.keys():
                         self.__movieHashNames[hashlib.md5(
                             eachmovie).hexdigest(
                             )] = self.__avaiMovieList[eachmovie]
                     self.__neighborLock.acquire()
                     ## might have to set a maximum limit of neighborhood ##
                     self.__ServerNeighborhood = union(
                         self.__ServerNeighborhood, newneighborhood)
                     self.__ServerNeighborhood = lminus(
                         self.__ServerNeighborhood,
                         self.__ExcludedServerAddr)
                     self.__neighborLock.release()
                     countdown = OBTAIN_NEIGHBOR_PERIOD / INTERVAL_TRACKER_COMMUNICATION
                 else:
                     ack = self.__tcpTracSock.sendmsg('alive')
                     if not ack:
                         break
                     sleep(INTERVAL_TRACKER_COMMUNICATION)
                     countdown -= 1
                     # send alive msg interval
         sleep(TRY_INTERVAL)  # obtain neighborhood/movielist interval
         del self.__tcpTracSock
         self.__tcpTracSock = Mytcpsocket()
Esempio n. 8
0
 def __registerpeer(
         self, *targs
 ):  # register the peer and obtain a list of potential neighbors
     args = targs[0]
     CliSocket = args[0]
     CliAddr = args[1]
     myClisock = Mytcpsocket(CliSocket)
     IS_SERV = -1
     while True:
         data = myClisock.recvmsg(BUFSIZ)
         if 'serv' in str.lower(data):
             IS_SERV = 1
             CliAddr = (CliAddr[0], int(data.split('+')[1]))
             self.__servDict[CliAddr] = 1
             pc = self.__potentialconn(
                 CliAddr, self.__userDict
             )  # return a list of user addresses \ itself
             myClisock.sendmsg(pc)
             myClisock.sendmsg(self.__movieList)  # send movie list to watch
         elif 'user' in str.lower(data):
             IS_SERV = 0
             CliAddr = (CliAddr[0], int(data.split('+')[1]))
             self.__userDict[CliAddr] = 1
             pc = self.__potentialconn(
                 CliAddr, self.__servDict
             )  # return a list of serv addresses \ itself
             myClisock.sendmsg(pc)
             myClisock.sendmsg(self.__movieList)  # send movie list to watch
         elif 'list' in str.lower(data):
             data = data.split('+')
             for i in range(1, len(data)):
                 videostat = data[i].split('#')
                 self.__movieList[videostat[0]] = [
                     int(videostat[1]),
                     int(videostat[2])
                 ]
             myClisock.sendmsg('ACK')
         elif str.lower(data) == 'alive':  # still alive
             print data, ' from ', CliAddr
             pass
         else:
             if IS_SERV == 1:
                 self.__servDict.pop(CliAddr)
             elif IS_SERV == 0:
                 self.__userDict.pop(CliAddr)
             myClisock.close()  # close the connection
             break
Esempio n. 9
0
 def __WaitforConnection(self, *targs):
     self.__tcpSerSock.InitServSock(self.__Addr, self.__MaxNumConn)
     if VERBOSE:
         print "Waiting for connection..."
     while True:
         (tcpClientSock, CLIENT_ADDR) = self.__tcpSerSock.WaitforConn()
         self.__connectionLock.acquire()
         clitcpsock = Mytcpsocket(tcpClientSock)
         if self.__NumofConnections < self.__MaxNumConn:
             servport = clitcpsock.recvmsg(BUFSIZ)
             ack = clitcpsock.sendmsg('ACK')
             CLIENT_SERV_ADDR = (CLIENT_ADDR[0], servport)
             if ((CLIENT_SERV_ADDR in self.__ClientConnectionIPs)
                     or (not ack) or servport == 'closed'):
                 clitcpsock.close()
             else:
                 self.__ClientConnectionSocks.append(clitcpsock)
                 self.__ClientConnectionIPs.append(CLIENT_SERV_ADDR)
                 self.__NumofConnections += 1
                 if VERBOSE:
                     print "...connected from:", CLIENT_ADDR
                 t = MyThread(self.__upload, (clitcpsock, CLIENT_SERV_ADDR),
                              self.__upload.__name__)
                 self.__UploadThreadsLock.acquire()
                 self.__UploadThreads.append(t)
                 self.__UploadThreadsLock.release()
                 self.__BWControlBoot.set()
                 # start BW control
                 self.__RateAllocBoot.set()
                 # start rate allocation
                 t.start()
                 sleep(PROCESS_TIME)
         else:
             clitcpsock.close(
             )  # close if the number of connections exceeds max
         self.__connectionLock.release()
Esempio n. 10
0
    def __init__(self, cwd, IS_SERVER=1):
        self.__cwd = cwd  # current working directory
        self.__isserver = IS_SERVER  # I mean the True server, not helper
        self.__tcpSerSock = Mytcpsocket()  # initiate server socket
        self.__tcpTracSock = Mytcpsocket()  # initiate tracker socket
        self.__PATH = self.__cwd + os.sep + SERVER_PATH + os.sep  # set up video caching directory
        if not os.path.exists(self.__PATH):
            os.makedirs(self.__PATH)

        # movieList: vhash: vname; videoDict: vhash: vpath; videoStat: vhash: [NumofChunks, NumofLeftOverPieces]
        self.__movieList = {}
        self.__videoDict = {}
        self.__videoStat = {}
        # storeAlloc: vhash: vsize; storePrices: vhash: vprice
        self.__storeAlloc = {}
        self.__storePrices = {}
        # mediaReaders: vhash: [a list of open file readers for vhash]; mediaUpdaters: vhash: file writer
        self.__mediaReaders = {}
        self.__mediaUpdaters = {}

        if IS_SERVER:
            self.__MaxNumConn = MAX_SERV_CONNECTION
            self.__Addr = MEDIA_SERVER_ADDRESS
            # read all the movies and convert newly added movies
            f = open(self.__PATH + 'movielist.txt', 'r+')
            allLines = f.readlines()
            f.close()
            for eachmovie in allLines:
                moviename = eachmovie.split('\n')[0]
                self.__movieList[hashlib.md5(
                    moviename).hexdigest()] = moviename  #vhash: vname
            dirList = os.listdir(self.__PATH)
            for dname in dirList:
                if (
                        not os.path.isdir(self.__PATH + dname)
                ) and dname != 'movielist.txt':  # if video not converted, convert
                    hashname = hashlib.md5(dname.split('.')[0]).hexdigest()
                    if (hashname in self.__movieList
                            and not hashname in dirList):
                        videopath = self.__PATH + hashname
                        os.makedirs(videopath)
                        self.__convertVideo(videopath + os.sep, self.__PATH +
                                            dname)  # convert the video
            dirList = os.listdir(self.__PATH)
            for dname in dirList:
                if os.path.isdir(self.__PATH + dname):
                    videopath = self.__PATH + dname + os.sep
                    if dname in self.__movieList:
                        self.__videoDict[dname] = videopath  # vhash: vpath
                        f = open(videopath + 'length', 'rb')
                        dt = f.readlines()
                        self.__videoStat[dname] = dt[0].split(',')
                        # vhash: [NumofChunks, NumofLeftoverPieces]
                        self.__mediaReaders[dname] = []
                    else:
                        print videopath  # not in list, to be deleted
                        shutil.rmtree(videopath)
        else:
            self.__MaxNumConn = MAX_PEER_CONNECTION
            # need to implement NAT traversal
            ##########start here############
            self.__Addr = (([
                ip for ip in gethostbyname_ex(gethostname())[2]
                if not ip.startswith("127.")
            ][0]), choice(range(50000, 60000)))
            ##########end   here############
            dirList = os.listdir(self.__PATH)
            for dname in dirList:
                if os.path.isdir(self.__PATH + dname):
                    videopath = self.__PATH + dname + os.sep
                    self.__videoDict[dname] = videopath
                    self.__mediaReaders[dname] = []
                    self.__mediaUpdaters[dname] = MediaFileWrapper(
                        videopath, False)  # write access
                    self.__storeAlloc[dname] = 0
                    self.__storePrices[dname] = 0

        self.__ClientNeighborhood = []
        self.__NumofConnections = 0
        self.__ClientConnectionIPs = []
        self.__ClientConnectionSocks = []
        self.__choketimer = 30

        self.__uploadBW = 0  # KB/sec
        self.__uploadedBytes = 0  # uploaded bytes in a second

        self.__UploadThreads = [
        ]  # upload threads. used to control UploadBWControl

        self.__neighborLock = thread.allocate_lock()
        self.__connectionLock = thread.allocate_lock()
        self.__timerLock = thread.allocate_lock()
        self.__rateAllocLock = thread.allocate_lock()
        self.__mediaReaderLock = thread.allocate_lock()
        self.__uploadStatLock = thread.allocate_lock()
        self.__UploadThreadsLock = thread.allocate_lock()
        self.__BWControlBoot = threading.Event()
        self.__BWControlBoot.clear()
        # we don't need BW control all the time
        self.__uploadBWExceed = threading.Event()
        self.__uploadBWExceed.clear()
        self.__RateAllocBoot = threading.Event()
        self.__RateAllocBoot.clear()