示例#1
0
    def run(self):
        """线程主函数

        循环运行,接受新的客户端的连接。
        """
        log.info('server thread: start, port: %d' % self.port)
        try:
            server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            if os.name != 'nt':
                server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            server.bind(('0.0.0.0', self.port))
            server.listen(100)      # 并发
            server.settimeout(1)    # timeout: 1s
            while self.running:
                # 接受连接
                try:
                    conn, address = server.accept()
                    conn.settimeout(3)
                    self.dispatcher.add_client(conn, address)
                    log.debug('new client from: %s' % str(address))
                except socket.timeout:
                    pass
                # 分发数据
                self.dispatcher.dispatch()
            server.close()
            self.dispatcher.close_all_clients()
            log.info('server thread: bye')
        except Exception as e:
            log.error('server thread error: %s' % e)
            self.running = False
示例#2
0
    def run(self):
        """线程主函数

        循环运行,接受到控制端口的 socket 连接(唯一),接收命令。
        """
        if self.port is None:
            return

        log.info('control thread: start, port: %d' % self.port)
        try:
            # 开始监听
            server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            server.bind(('0.0.0.0', self.port))
            server.listen(1)
            server.settimeout(3)    # timeout: 3s
            # 循环运行,监听端口,接收命令
            while self.running:
                self.accept_client(server)
                self.receive_command()
                self.resolve_command()
                self.send_message()
            server.close()
            self.disconnect_client()
            log.info('control thread: bye')
        except Exception as e:
            log.error('control thread error: %s' % e)
            self.running = False
示例#3
0
    def load_config(self):
        """载入配置文件

        先读入 conf/config.json 中的配置,再读入 conf/ 中其他 json 文件里的 entry
        """
        config_dir = os.path.join(sys.path[0], 'conf')
        configs = {}
        # main config
        config_file_name = os.path.join(config_dir, 'config.json')
        try:
            with open(config_file_name) as config_fp:
                configs = json.load(config_fp)
        except Exception as e:
            log.error('main: failed to load config from conf/config.json: %s' % e)
        if 'entry' not in configs.keys():
            configs['entry'] = {}

        # other entries
        for dir_path, dir_names, file_names in os.walk(config_dir):
            for file_name in file_names:
                if file_name != 'config.json' and file_name.endswith('.json'):
                    # load sub config
                    config_file_name = os.path.join(config_dir, file_name)
                    try:
                        with open(config_file_name) as config_fp:
                            sub_configs = json.load(config_fp)
                        # insert into main config
                        for name, config in sorted(sub_configs['entry'].items()):
                            if name not in configs['entry'].keys():
                                configs['entry'][name] = config
                    except Exception as e:
                        log.error('main: failed to load config from conf/%s: %s' % (file_name, e))

        return configs
示例#4
0
    def run(self):
        """线程主函数

        循环运行,接受新的客户端的连接。
        """
        log.info('station server thread: start, port: %d' % self.port)
        try:
            server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            if os.name != 'nt':
                server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            server.bind(('0.0.0.0', self.port))
            server.listen(1)
            server.settimeout(3)    # timeout: 3s
            while self.running:
                try:
                    conn, address = server.accept()
                    conn.settimeout(3)
                    log.debug('new station connection from: %s' % str(address))
                    self.got_client(conn, str(address))
                except socket.timeout:
                    pass
                self.check_new_connections()
            # clean up
            server.close()
            self.disconnect()
            log.info('station server thread: bye')
        except Exception as e:
            log.error('station server thread error: %s' % e)
            self.running = False
        self.disconnect()
示例#5
0
    def start_rtk_threads(self, entries):
        """停止某 rtk 线程,不等待

        之后需要调用 wait_for_thread

        Args:
            entries (dict[str, dict]): 各组 rtk 转发配置
        """
        if isinstance(entries, dict):
            # start threads from config
            for name, config in entries.items():
                # start one thread
                try:
                    if name in self.rtk_threads.keys():
                        # 如果已有
                        rtk_group = self.rtk_threads[name]
                        # 判断配置是否发生改变,如果不变并且在运行,就跳过
                        if rtk_group.is_alive() and rtk_group.config == config:
                            continue
                        self.stop_and_wait_for_thread(name)
                    rtk_group = RtkGroup(name, self.thread_count, config, self.status_queue)
                    self.thread_count += 1
                    rtk_group.start()
                    self.rtk_threads[name] = rtk_group
                except Exception as e:
                    log.error('main: failed to start thread %s: %s' % (name, e))
            # stop threads not in config
            for name in self.rtk_threads.keys():
                if name not in entries.keys():
                    self.stop_and_wait_for_thread(name)
                    del self.rtk_threads[name]
示例#6
0
 def disconnect(self):
     """断开连接"""
     try:
         self.client_socket.close()
     except socket.error:
         pass
     except Exception as e:
         log.error('sender thread %d exception when close: %s' % (self.sender_id, e))
 def disconnect(self):
     """断开连接"""
     try:
         self.client_socket.close()
     except socket.error:
         pass
     except Exception as e:
         log.error('station connection thread exception when close: %s' % e)
示例#8
0
    def push_back(self, data):
        """加入新收到的数据 (list)

        Args:
            data (list): 新收到的数据
        """
        try:
            self.data.extend(data)
        except Exception as e:
            log.error("checker error when add: %s" % e)
示例#9
0
    def stop_thread(self, name, thread_to_stop):
        """结束指定线程

        Args:
            name (str): 要结束的线程名,名字仅用于 log
            thread_to_stop (threading.Thread): 要结束的线程
        """
        try:
            thread_to_stop.running = False
            thread_to_stop.join()
        except Exception as e:
            log.error('rtk thread: failed to stop thread %s: %s' % (name, e))
示例#10
0
    def receive_command(self):
        """从控制端口接收数据

        并在发生异常时进行处理。
        """
        if self.client is not None:
            try:
                self.receive_data()
            except socket.timeout:      # 允许超时
                pass
            except Exception as e:
                log.error('control client error: %s' % e)
                self.disconnect_client()
    def run(self):
        """线程主函数

        循环运行,接收来自客户端的数据并丢弃,向客户端发送 data_queue 中的数据包。
        当 data_queue 过长时,丢弃旧的数据包。
        """
        log.info('station connection thread: start, %s' % self.address)
        self.update_status_cb(RtkStatus.S_CONNECTED)

        try:
            self.send_and_receive_data()
        except Exception as e:
            log.error('station connection thread error: %s' % e)
        self.update_status_cb(RtkStatus.S_DISCONNECTED)
        log.info('station connection thread: bye')
示例#12
0
    def stop_thread(self, name):
        """停止某 rtk 线程,不等待

        之后需要调用 wait_for_thread

        Args:
            name (str): rtk 线程名
        """
        try:
            if name in self.rtk_threads.keys():
                rtk_thread = self.rtk_threads[name]
                if isinstance(rtk_thread, RtkGroup):
                    rtk_thread.stop()
                    log.info('main: require stop thread %d %s.' % (rtk_thread.thread_id, name))
        except Exception as e:
            log.error('main: failed to stop thread %s: %s' % (name, e))
示例#13
0
    def run(self):
        """线程主函数

        启动定时器,用于检查心跳超时
        循环运行,接受新的客户端的连接。
        """
        log.info("http thread: start, port: %d" % self.port)

        try:
            self.server = ThreadingHTTPServer(("", self.port), RequestHandler)
            self.server.serve_forever()
        except Exception as e:
            log.error("http thread error: %s" % e)

        time.sleep(0.5)
        log.info("http thread: bye")
示例#14
0
    def get_parsed_data(self):
        """解析数据

        Returns:
            return (bytes): 解析了的完整报文
        """

        # 拷贝
        self.rtcm_checker.push_back(self.data)
        self.data.clear()

        try:
            # 解析
            return self.rtcm_checker.get_parsed_data()
        except Exception as e:
            log.error('checker error when parse msg: %s' % e)
        return None
示例#15
0
    def wait_for_thread(self, name):
        """等待某 rtk 线程完全退出

        在 stop_thread 之后调用

        Args:
            name (str): rtk 线程名
        """
        try:
            if name in self.rtk_threads.keys():
                rtk_thread = self.rtk_threads[name]
                if isinstance(rtk_thread, RtkGroup):
                    # wait
                    rtk_thread.join()
                log.info('main: thread %d %s has stopped.' % (rtk_thread.thread_id, name))
                # remove
                del self.rtk_threads[name]
        except Exception as e:
            log.error('main: error when wait for thread %s: %s' % (name, e))
示例#16
0
    def run(self):
        """线程主函数

        循环运行,建立连接、接收数据,并在连接出错时重连。
        """
        log.info('station client thread: start')
        while self.running:
            try:
                # 建立连接
                conn = self.connect()
                log.info('station client thread: connected')
                # 开启数据接收线程
                self.run_receive_data_thread(conn)
            except Exception as e:
                log.error('station client thread error: %s' % e)
                time.sleep(3)
        # disconnect
        self.disconnect()
        log.info('station client thread: bye')
示例#17
0
    def disconnect_client(self):
        """断开连接并清理"""
        if self.client is not None:
            # say goodbye
            try:
                self.client.sendall(b'bye')
            except:
                pass

            # close socket
            try:
                self.client.close()
            except socket.error:
                pass
            except Exception as e:
                log.error('control client exception when close: %s' % e)
        # clean up
        self.client = None
        self.buffer.clear()
        self.is_in_command = False
示例#18
0
    def pop_front(self, len_to_remove):
        """从 data 开头移除数据 (bytes)

        Args:
            len_to_remove (int): 要删除的数据长度

        Returns:
            ret_data (list): 被删除的数据
        """
        ret_data = None
        try:
            if len_to_remove > 0:
                if len_to_remove < len(self.data):
                    ret_data = self.data[:len_to_remove]
                    self.data = self.data[len_to_remove:]
                else:
                    ret_data = self.data[:]
                    self.data.clear()
        except Exception as e:
            log.error("checker error when remove data: %s" % e)
        return ret_data
示例#19
0
    def start_threads_from_config(self):
        """读取配置文件,启动所有 rtk 线程"""
        # config
        configs = self.load_config()
        self.configs = configs

        # web 管理界面
        try:
            port = configs['webInterface']['port']
            if configs['webInterface']['allow'].lower() == 'true':
                self.start_web_interface(port)
        except Exception as e:
            log.error('main: failed to start web interface: %s' % e)
        # rtk 转发服务
        try:
            if 'entry' in configs.keys():
                self.start_rtk_threads(configs['entry'])
        except Exception as e:
            log.error('main: failed to start rtk threads: %s' % e)
        # web 管理界面的配置
        try:
            if configs['webInterface']['allow'].lower() == 'true':
                self.update_web_interface(sorted(configs['entry'].keys()))
        except Exception as e:
            log.error('main: failed to update web interface: %s' % e)
示例#20
0
    def get_parsed_data(self):
        """解析数据

        Returns:
            return (bytes): 解析了的完整报文
        """

        if len(self.data) <= 0:
            return None
        # 拷贝
        data = self.data[:]
        if self.is_acceptable_msg_type is None:
            # 如果不用解析
            self.data.clear()
            return bytes(data)

        try:
            # 解析
            index, len_message, msg_type = try_parse(data)
            if index > 0:
                # 删除无法解析的数据
                log.debug('unknown data size: %d' % index)
                # print unknown data
                # print([hex(x) for x in data[:index]])
                # print(bytes(data[:index]).decode('utf-8', errors='ignore'))
                self.pop_front(index)
            if len_message > 0:
                # 删除解析后的数据
                log.debug('pkg size: %d, msg size: %d, msg type: %d' % (len_message, len_message - 6, msg_type))
                # print([hex(x) for x in data[:index + len_message]])
                # print(bytes(data[:index + len_message]).decode('utf-8', errors='ignore'))
                parsed_data = bytes(self.pop_front(len_message))
                if self.is_acceptable_msg_type(msg_type):
                    return parsed_data
        except Exception as e:
            log.error('checker error when parse msg: %s' % e)
        return None
示例#21
0
    def run(self):
        """线程主函数

        循环运行,接收来自客户端的数据并丢弃,向客户端发送 data_queue 中的数据包。
        当 data_queue 过长时,丢弃旧的数据包。
        """
        log.info('sender thread %d: start, %s' % (self.sender_id, self.address))
        try:
            while self.running:
                # ignore old data
                while self.data_queue.qsize() > 10:
                    self.data_queue.get(block=False)
                # send data
                try:
                    data = self.data_queue.get(timeout=1)
                    self.client_socket.settimeout(5)
                    self.client_socket.sendall(data)
                    self.send_count += 1
                    self.data_queue.task_done()
                except queue.Empty:
                    pass
                # rcv useless data
                try:
                    self.client_socket.settimeout(0.1)
                    rcv_buf = self.client_socket.recv(256)
                    if len(rcv_buf) == 0:
                        log.info('sender thread %d has disconnected.' % self.sender_id)
                        # 退出
                        break
                except socket.timeout:
                    pass
        except Exception as e:
            log.error('sender thread %d error: %s' % (self.sender_id, e))
        self.disconnect()
        self.running = False
        log.info('sender thread %d: bye' % self.sender_id)