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 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