예제 #1
0
    def add_client(self, client_socket, address):
        """新的客户端连入时调用此函数

        建立新的 SenderThread 并加入分发列表。

        Args:
            client_socket: 与客户端通信的 socket
            address: 客户端地址
        """
        sender = SenderThread(client_socket, address, DispatcherThread.new_client_id)
        self.clients[DispatcherThread.new_client_id] = sender
        DispatcherThread.new_client_id += 1
        sender.start()
예제 #2
0
 def connect(self):
     self.newPeerListener_ = NewPeerListener(self.newPeerConnected, self.dfs_)
     self.newPeerListener_.start()
     self.sender_ = SenderThread(self.dfs_, self.fileSystem_)
     self.sender_.connectToMultiple(self.knownPeers_)
     self.sender_.start()
     self.log_.v('connected done')
예제 #3
0
class Network(Base):
    def __init__(self, dfs, fileSystem):
        Base.__init__(self, dfs)
        self.fileSystem_ = fileSystem
        self.knownPeers_ = []
        self.sender_ = None

    ##
    # Public API
    ##
    def loadFromState(self, peers):
        self.knownPeers_ = peers

    def connect(self):
        self.newPeerListener_ = NewPeerListener(self.newPeerConnected, self.dfs_)
        self.newPeerListener_.start()
        self.sender_ = SenderThread(self.dfs_, self.fileSystem_)
        self.sender_.connectToMultiple(self.knownPeers_)
        self.sender_.start()
        self.log_.v('connected done')

    def connectTo(self, dfs):
        if not self.dfs_.online:
            self.log_.w('tried to connectTo while offline')
            return

        self.log_.v('connectTo ' + str(dfs.id))
        self.sender_.connectTo(dfs)

    def disconnect(self):
        self.knownPeers_ = self.sender_.getPeers()
        self.newPeerListener_.close()
        self.sender_.close()
        self.sender_.join()
        self.newPeerListener_.join()
        self.log_.v('disonnected done')

    # ask each peer for a random file chunk until the file is fully retrieved
    def getFile(self, fileName, timeout=30):
        if not self.dfs_.online:
            return err.CannotFullyUpdateFile

        self.log_.v('attempting to get ' + fileName)
        self.fileSystem_.beginLocalUpdate(fileName)
        self.sender_.beginFileFetch(fileName)
        count = 0
        while not self.sender_.isDoneFileFetch():
            time.sleep(.1)
            count += 1
            if count == 5:
                self.log_.i('Downloading ' + fileName + '...')
            if count > timeout:
                self.log_.w('getting ' + fileName + ' timed out')
                break

        status = self.fileSystem_.finishLocalUpdate(fileName)
        self.log_.v('finished getting ' + fileName + ': ' + str(status))
        return status

    def fileEdited(self):
        if not self.dfs_.online:
            return
        self.sender_.updateAll()

    def waitForPropagation(self):
        while not self.sender_.editPropagated():
            time.sleep(.1)

    def getState(self):
        if not self.sender_:
            return self.knownPeers_
        return self.sender_.getPeers()

    ##
    # Private methods
    ##
    def newPeerConnected(self, socket):
        self.log_.v('new peer connected')
        lt = ListenerThread(self.dfs_, self.sender_.addWork)
        lt.setConnection(socket)
        lt.start()
        self.sender_.addListener(lt)