def recv_data(cls, net_info, recv_para={}): """ 从指定的网络连接中读取数据 @param {object} net_info - 要读取数据的网络信息对象(例如socket对象) @param {dict} recv_para - 读取数据的参数, 包括: recv_len {int} - 要获取的数据长度, 必要参数 overtime {int} - 获取超时时间,单位为毫秒,非必要参数 @returns {CResult} - 数据获取结果: result.code :'00000'-成功,'20403'-获取数据超时,其他为获取失败 result.data :获取到的数据对象(具体类型和定义,由实现类自定义) result.recv_time : datetime 实际开始接受数据时间 result.overtime : int 超时时间(毫秒),当返回结果为超时,可获取超时时间信息 """ # 子类必须定义该功能 if type(recv_para) != dict: recv_para = {} _result = CResult('00000') _result.data = b'' _result.recv_time = datetime.datetime.now() _overtime = 10000 if 'overtime' in recv_para.keys(): # 外部有传入,优先使用该超时时间 _overtime = recv_para['overtime'] elif hasattr(net_info, 'recv_timeout'): # 如果net_info有超时的设置 _overtime = net_info.recv_timeout _result.overtime = _overtime with ExceptionTool.ignored_cresult( _result ): _rest_bytes = recv_para['recv_len'] while _rest_bytes > 0: # 检查是否超时 if (datetime.datetime.now() - _result.recv_time).total_seconds() * 1000 > _overtime: # 已超时 _result.change_code(code='20403') break _buffer = b'' with ExceptionTool.ignored(expect=(BlockingIOError)): # 获取数据 _buffer = net_info.csocket.recv(_rest_bytes) if len(_buffer) > 0: _result.data = _result.data + _buffer _rest_bytes = _rest_bytes - len(_buffer) else: # 休眠一下 RunTool.sleep(0.001) return _result
def send_data(cls, net_info, data, send_para={}): """ 向指定的网络连接发送数据 @param {object} net_info - 要写入数据的网络信息对象(例如socket对象) @param {object} data - 要写入的数据对象(具体类型和定义,由实现类自定义) @param {dict} send_para - 写入数据的参数: overtime {int} - 发送超时时间,单位为毫秒, 非必须参数 @returns {CResult} - 发送结果: result.code :'00000'-成功,'20404'-写入数据超时,其他为写入失败 result.send_time : datetime 实际发送完成时间 result.overtime : int 超时时间(毫秒),当返回结果为超时,可获取超时时间信息 """ # 子类必须定义该功能 if type(send_para) != dict: send_para = {} _result = CResult('00000') _result.send_time = None _overtime = 10000 if 'overtime' in send_para.keys(): _overtime = send_para['overtime'] elif hasattr(net_info, 'send_timeout'): # 如果net_info有超时的设置 _overtime = net_info.send_timeout _result.overtime = _overtime _begin_time = datetime.datetime.now() with ExceptionTool.ignored_cresult( _result ): _rest_bytes = len(data) _total_bytes = _rest_bytes while _rest_bytes > 0: # 检查是否超时 if (datetime.datetime.now() - _begin_time).total_seconds() * 1000 > _overtime: # 已超时 _result.change_code(code='20404') break with ExceptionTool.ignored(expect=(BlockingIOError)): # 发送数据 _len = net_info.csocket.send(data[_total_bytes - _rest_bytes:]) if _len > 0: _rest_bytes = _rest_bytes - _len _result.send_time = datetime.datetime.now() return _result
def recv_http_head(cls, net_info, recv_para={}): """ 获取http报文头对象 @param {object} net_info - 要读取数据的网络信息对象 @param {dict} recv_para - 获取参数,暂未使用 @returns {CResult} - 数据获取结果: result.code :'00000'-成功,'20403'-获取数据超时,其他为获取失败 result.data :获取到的数据对象,类型为MsgHTTP result.recv_time : datetime 实际开始接受数据时间 """ if type(recv_para) != dict: recv_para = {} _result = CResult('00000') _result.data = None _result.recv_time = datetime.datetime.now() _overtime = 10000 if 'overtime' in recv_para.keys(): # 外部有传入,优先使用该超时时间 _overtime = recv_para['overtime'] elif hasattr(net_info, 'recv_timeout'): # 如果net_info有超时的设置 _overtime = net_info.recv_timeout _result.overtime = _overtime _recv_para = copy.deepcopy(recv_para) _recv_para['recv_len'] = 1 with ExceptionTool.ignored_cresult( _result ): # 循环获取所有报文头内容 _get_line_bytes = b'' _last_is_ln = False # 标记上一个字符是否回车换行 while True: # 检查是否超时 if (datetime.datetime.now() - _result.recv_time).total_seconds() * 1000 > _overtime: # 已超时 _result.change_code(code='20403') break _read_result = TcpIpService.recv_data(net_info, _recv_para) if not _read_result.is_success(): # 出现异常,直接返回失败 _read_result.data = None _read_result.recv_time = _result.recv_time return _read_result # 获取成功,判断是否回车换行 _get_line_bytes = _get_line_bytes + _read_result.data if str(_read_result.data, "ascii") == "\n" and _last_is_ln: # 已经连续遇到两次回车换行,说明报文头已收齐退出循环 break elif str(_read_result.data, "ascii") == "\n": _last_is_ln = True continue elif str(_read_result.data, "ascii") == "\r": continue else: # 其他字符,不是连续换行 _last_is_ln = False continue # 取完报文头数据,转换为结构对象 _result.data = MsgHTTP(_get_line_bytes, msg_id=None, obj_type=EnumMsgObjType.Bytes) return _result