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