예제 #1
0
    def _accept_one(self, server_opts, net_info):
        """
        监听接受一个请求并返回
        提供监听并获取到请求连接返回的方法;注意该该函数必须捕获并处理异常

        @param {objcet} server_opts - 网络服务启动参数
        @param {objcet} net_info - 网络连接信息对象,_start_server_without_accept中获取到的结果

        @returns {CResult} - 获取网络连接结果:
            result.code :'00000'-成功,'20407'-获取客户端连接请求超时
            result.net_info :客户端连接信息对象,该对象将传给后续单个连接处理的线程

        """
        # 子类必须定义该功能
        _result = CResult('00000')
        _result.net_info = None
        with ExceptionTool.ignored_cresult(
            _result,
            logger=self._logger,
            expect=(BlockingIOError),
            expect_no_log=True,  # 超时不记录日志
            error_map={BlockingIOError: ('20407', None)},
            self_log_msg='[LIS][NAME:%s]%s error: ' % (
                self._server_name, _('accept client connect')),
            force_log_level=None
        ):
            # _sys_str = platform.system()
            _csocket, _addr = net_info.csocket.accept()  # 接收客户端连接,返回客户端和地址
            _csocket.setblocking(False)   # 将socket设置为非阻塞. 在创建socket对象后就进行该操作.
            _result.net_info = NullObj()
            _result.net_info.csocket = _csocket
            _result.net_info.raddr = _addr
            _result.net_info.laddr = _csocket.getsockname()
            _result.net_info.send_timeout = server_opts.send_timeout
            _result.net_info.recv_timeout = server_opts.recv_timeout

            # 采用非阻塞模式处理数据,超时自行实现
            """
            if (_sys_str == 'Windows'):
                _csocket.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, server_opts.recv_timeout)
                _csocket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDTIMEO, server_opts.send_timeout)
            else:
                # linux 设置超时时间不同,需重新测试
                _csocket.settimeout(server_opts.recv_timeout / 1000)
            """
            self._logger.log(
                self._log_level,
                '[LIS][NAME:%s]%s: %s - %s' % (
                    self._server_name, _('accept one client connection'), str(_addr), str(_csocket)
                )
            )
        if not _result.is_success():
            # 出现异常,睡眠一段时间
            RunTool.sleep(0.01)
        return _result
예제 #2
0
    def _start_server_without_accept(self, server_opts):
        """
        启动服务但不接受请求服务,该方法只做到启动端口层面,轮询监听不在该方法中实现:

        @param {object} server_opts - 服务参数

        @returns {CResult} - 启动结果:
            result.code :'00000'-成功,其他值为失败
            result.net_info :启动后的服务端网络连接信息对象,该对象将传给后续的监听线程(_AcceptOne),定义为:
                result.net_info.csocket - socket对象
                result.net_info.laddr 本地地址,地址对象,("IP地址",打开端口)
                result.net_info.raddr 远端地址,地址对象,("IP地址",打开端口)
                result.net_info.send_timeout 发送超时时间,单位为毫秒
                result.net_info.recv_timeout 收取超时时间,单位为毫秒

        """
        # 子类必须定义该功能
        _result = CResult('00000')
        _result.net_info = None
        with ExceptionTool.ignored_cresult(
            _result,
            logger=self._logger,
            self_log_msg='[LIS-STARTING][NAME:%s]%s - %s error: ' % (
                self._server_name, _('net service starting'), _('listen without accept')),
            force_log_level=logging.ERROR
        ):
            # _sys_str = platform.system()
            _server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            _server_socket.setblocking(False)   # 将socket设置为非阻塞. 在创建socket对象后就进行该操作.
            _server_socket.bind((server_opts.ip, server_opts.port))
            _server_socket.listen(server_opts.max_connect)
            # 改为用非阻塞模式支持,因此超时自行实现
            """
            if (_sys_str == 'Windows'):
                _server_socket.setsockopt(
                    socket.SOL_SOCKET, socket.SO_RCVTIMEO, server_opts.recv_timeout)
                _server_socket.setsockopt(
                    socket.SOL_SOCKET, socket.SO_SNDTIMEO, server_opts.send_timeout)
            else:
                # linux 设置超时时间不同,需重新测试
                _server_socket.settimeout(server_opts.recv_timeout/1000)
            """
            _result.net_info = NullObj()
            _result.net_info.laddr = _server_socket.getsockname()
            # _result.net_info.raddr = _server_socket.getpeername()
            _result.net_info.raddr = ('', 0)
            _result.net_info.csocket = _server_socket
            _result.net_info.send_timeout = server_opts.send_timeout
            _result.net_info.recv_timeout = server_opts.recv_timeout

        return _result
예제 #3
0
    def connect_server(cls, connect_para):
        """
        客户端通过该函数连接服务器端

        @param {object} connect_para - 需要连接服务器的参数,与server_opts一致

        @returns {CResult} - 连接结果:
            result.code :'00000'-成功,其他值为失败
            result.net_info : 连接后的网络信息对象

        """
        # 子类必须定义该功能
        _result = CResult('00000')
        _result.net_info = None
        with ExceptionTool.ignored_cresult(
            _result,
            logger=None
        ):
            # _sys_str = platform.system()
            _tcp_cli_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 分配 TCP 客户端套接字
            _tcp_cli_sock.connect((connect_para.ip, connect_para.port))  # 主动连接
            _tcp_cli_sock.setblocking(False)   # 将socket设置为非阻塞. 在创建socket对象后就进行该操作.

            # 转换为非阻塞模式,自行控制超时
            """
            if (_sys_str == 'Windows'):
                _tcp_cli_sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO,
                                         connect_para.recv_timeout)
                _tcp_cli_sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDTIMEO,
                                         connect_para.send_timeout)
            else:
                # linux 设置超时时间不同,需重新测试
                _tcp_cli_sock.settimeout(connect_para.recv_timeout / 1000)
            """
            _result.net_info = NullObj()
            _result.net_info.csocket = _tcp_cli_sock
            _result.net_info.laddr = _tcp_cli_sock.getsockname()
            _result.net_info.raddr = _tcp_cli_sock.getpeername()
            _result.net_info.send_timeout = connect_para.send_timeout
            _result.net_info.recv_timeout = connect_para.recv_timeout
        return _result
예제 #4
0
    def test_methon(self):
        """
        测试静态方法
        """
        _logger = Logger()
        _result = CResult('00000')
        _result.net_info = None
        with ExceptionTool.ignored_cresult(_result,
                                           logger=_logger,
                                           expect=(),
                                           error_map={
                                               ImportError: ('20401', None),
                                               BlockingIOError: ('20407', None)
                                           },
                                           self_log_msg='test:',
                                           force_log_level=None):
            _result.test = 'test'

        self.assertTrue(_result.code == '00000' and _result.test == 'test',
                        'ok result error')

        _result = CResult('00000')
        with ExceptionTool.ignored_cresult(_result,
                                           logger=_logger,
                                           expect=(),
                                           error_map={
                                               ImportError: ('20401', None),
                                               BlockingIOError: ('20407', None)
                                           },
                                           self_log_msg='test:',
                                           force_log_level=None):
            raise ImportError

        self.assertTrue(_result.code == '20401',
                        '20401 result error, code:' + _result.code)

        _result = CResult('00000')
        with ExceptionTool.ignored_cresult(_result,
                                           logger=_logger,
                                           expect=(),
                                           error_map={
                                               ImportError: ('20401', None),
                                               BlockingIOError: ('20407', None)
                                           },
                                           self_log_msg='test:',
                                           force_log_level=None):
            raise BlockingIOError

        self.assertTrue(_result.code == '20407',
                        '20407 result error, code:' + _result.code)
예제 #5
0
    def connect(self, **kwargs):
        """
        连接远端服务器
        (对于长连接或有需要实现先连接再处理的场景使用,其他场景无需重构该函数)

        @param {**kwargs} kwargs - 连接参数(具体由实现类定义)

        @returns {HiveNetLib.generic.CResult} - 处理结果(符合HiveNet 错误码规范)
            当处理结果为成功时,通过CResult返回结果对象:
            CResult.proto_obj {object}  - 协议通讯对象
            CResult.net_info {object}  - 网络连接信息

        """
        _ret = CResult(code='00000')
        _ret.proto_obj = self.__proto_obj
        _ret.net_info = self.__net_info
        return _ret