예제 #1
0
    def NewMap(self,
               target_addr,
               host_addr,
               remote_listen_addr=None,
               host_reuse_addr=False):

        host_s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        if host_reuse_addr:
            host_s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        host_s.bind(host_addr)
        new_id = self.id_set.Gen()

        def RemoteMapConnectHandler(_s,
                                    ID=new_id,
                                    host_s=host_s,
                                    target_addr=target_addr):
            if _s is not None:
                map_h = MapHandler(_socket=_s,
                                   host_socket=host_s,
                                   target_addr=target_addr,
                                   logger=self.logger,
                                   socket_data_sender=self.data_sender)
                self._ConnectingConfirm(ID, map_h)
                map_h.AddDisconnectCallback(self._MapHandleDisconnCallB)
                map_h.Start()
            else:
                #self._DelConnectingInfo(ID)
                #self.id_set.Del(ID)
                # Still waiting for connection
                pass

        if remote_listen_addr is None:
            #bind a random port
            remote_listen_addr = ('', 0)
        remote_s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        remote_s.bind(remote_listen_addr)
        remote_listen_addr = remote_s.getsockname()
        self._Log(logging.INFO, 'Remote listen addr: [%s:%d]',
                  remote_listen_addr[0], remote_listen_addr[1])
        # listen this socket
        remote_s.listen(BACK_LOG)
        self._AddConnecting(remote_s, new_id)
        self.id_remote_sock[new_id] = remote_s

        self.sl.AddSocket(remote_s,
                          ThreadingServerShakeHand(RemoteMapConnectHandler))
        # this remote_s will be closed when map connection confirm in _ConnectingConfirm
        # Send new map message
        msg = Protocol.PackMainCtrlMsg(opt='new_map',
                                       ID=new_id,
                                       port_msg=target_addr,
                                       server_msg=remote_listen_addr)
        self._SelfSendData(msg)
        return new_id