def __init__(self, workers): self.client_fd = None self.recv_buf = '' self.send_buf = '' self.conn_id = None self.msg = Message() self.logger = Log() self.workers = workers
def test_pack(): fd = socket.socket(socket.AF_INET, socket.SOCK_STREAM) fd.connect(("localhost", 7736)) msg = Message() msg.pack_buffer(1001, "hello world") str = msg.get_stream() fd.sendall(str)
class Connection: err_d = (errno.EINPROGRESS, errno.EALREADY, errno.EWOULDBLOCK) err_conn = (errno.EISCONN, 10057, 10035) # client 10053 def __init__(self, workers): self.client_fd = None self.recv_buf = '' self.send_buf = '' self.conn_id = None self.msg = Message() self.logger = Log() self.workers = workers def close_fd(self): try: self.logger.debug( "client exit. fd = " + str(self.client_fd) + "port = " + str(self.client_fd.getpeername()[1])) self.client_fd.shutdown(socket.SHUT_RDWR) self.client_fd.close() except IOError as err: self.logger.error("conn socket close fail err:" + str(err.errno)) def assign(self, fd, conn_id): self.client_fd = fd self.client_fd.setblocking(False) self.client_fd.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) self.conn_id = conn_id self.logger.debug("new client. fd = " + str(self.client_fd) + "port = " + str(self.client_fd.getpeername()[1])) def _package_message(self): while len(self.recv_buf) != 0: size = self.msg.recv(self.recv_buf) self.recv_buf = self.recv_buf[size:] if self.msg.finish(): # self.logger.debug("recv msg:" + self.msg.__str__()) # print "recv msg:" + self.msg.__str__() self.workers.message_handler(self.conn_id, self.msg) self.msg.assign() def recv_event(self): text = '' # 客户端退出 not text为 True,这里text上空字符串。 # 如果是客户端暂时没有数据,并不会导致text为空传,导致10035异常,非阻塞模式中 try: text = self.client_fd.recv(1024) if not text: err_code = 10000 self.close_fd() return True except socket.error, (code, strerror): if code not in Connection.err_d: err_code = code self.close_fd() return True self.recv_buf += text self._package_message() return False
def __init__(self, conn_id=0, msg=None): if msg is None: self.msg = Message() else: self.msg = copy.copy(msg) self.conn_id = conn_id self.content = None self.logger = Log() self.parse_success = False self.parse_err = None
def send(handler, content): fd = socket.socket(socket.AF_INET, socket.SOCK_STREAM) fd.connect(("127.0.0.1", 7736)) fd.setblocking(False) err_d = (errno.EINPROGRESS, errno.EALREADY, errno.EWOULDBLOCK) recv_buf = '' msg = Message() req = Request() req.pack_buffer(handler, content) fd.sendall(req.msg.get_stream()) msg.assign() ok = False while True: text = '' try: text = fd.recv(1024) if not text: err_code = 10000 fd.close() break except socket.error, (code, strerror): if code not in err_d: err_code = code fd.close() continue recv_buf += text # message while len(recv_buf) != 0: size = msg.recv(recv_buf) recv_buf = recv_buf[size:] if msg.finish(): print msg.__str__() msg.assign() ok = True if ok: break
print type(big_ending), len(big_ending) # str, 4 print binascii.hexlify(big_ending) # 字符串的十六进制表示 def test_pack(): fd = socket.socket(socket.AF_INET, socket.SOCK_STREAM) fd.connect(("localhost", 7736)) msg = Message() msg.pack_buffer(1001, "hello world") str = msg.get_stream() fd.sendall(str) if __name__ == '__main__': msg1 = Message() msg1.pack_buffer(1001, 'hello world') stream1 = msg1.get_stream() msg2 = Message() msg2.pack_buffer(1002, 'bye world') stream2 = msg2.get_stream() print stream1, stream2 fd = socket.socket(socket.AF_INET, socket.SOCK_STREAM) fd.connect(("localhost", 7736)) # 测试粘包 stream = stream1 + stream2 fd.sendall(stream)
class Request: def __init__(self, conn_id=0, msg=None): if msg is None: self.msg = Message() else: self.msg = copy.copy(msg) self.conn_id = conn_id self.content = None self.logger = Log() self.parse_success = False self.parse_err = None def get_handler(self): return self.msg.get_handler() def get_msg_content(self): return self.msg.get_msg_content() def pack_buffer(self, handler, content=None): if content and isinstance(content, dict): self.content = content if not isinstance(self.content, dict): raise ValueError("request / response content must be dict. " + str(type(self.content))) self.content = unicode_convert(self.content) self.msg.pack_buffer(handler, json.dumps(self.content)) def deserialization(self): try: self.content = json.loads(self.msg.get_msg_content()) except ValueError as err: self.logger.debug("json parse err. " + str(err)) return self.content = unicode_convert(self.content) self.parse_success = True def contain_key(self, key): if key not in self.content.keys(): self.parse_success = False self.parse_err = "key not exist. " + key return False return True def check_contain_string(self, key): if not self.contain_key(key): return False if not isinstance(self.content[key], str): self.parse_success = False self.parse_err = "key: " + key + " is not str" return False return True def check_contain_float(self, key): if not self.contain_key(key): return False val = self.content[key] try: val = float(val) except Exception as e: self.parse_success = False self.parse_err = "val: " + str(val) + "is not float. " + str(e) return False else: return True def check_contain_int(self, key, min_val=None, max_val=None): if not self.contain_key(key): return False val = self.content[key] if not isinstance(val, int): try: val = int(val) except Exception as e: self.parse_success = False self.parse_err = "val: " + str(val) + "is not int. " + str(e) return False else: return True if (min_val is not None and val < min_val) or (max_val is not None and val > max_val): self.parse_success = False self.parse_err = "key: " + key + " value range error" return False return True