def handle_feedback(socket, address): print 'New FEEDBACK connection from %s:%s' % address feedback_handled.append("") if not feedback_saved: socket.recv(1) socket.sendall("") else: response = feedback_saved.popleft() for x in response: print ">>> FEEDBACK SENT TO DISPATCHER: " + repr(x) socket.sendall(x) socket.recv(1)
def do_request(): siteid = random.choice(siteids) oids = set( int(random.gauss(0, settings.objects_per_site/4)) for i in range(settings.objects_per_request) ) socket = gevent.socket.create_connection(waddr) try: socket.sendall( request_template % dict( data='_'.join(map(str, oids)), host='h%s' % siteid, ) ) response = '' while '\r\n\r\n' not in response: data = socket.recv(9999) if not data: stats.truncated += 1 return response += data headers, body = response.split('\r\n\r\n') headers = headers.split('\r\n') status = headers.pop(0) headers = dict(l.strip().lower().split(':', 1) for l in headers if ':' in l) content_length = int(headers['content-length']) while len(body) < content_length: data = socket.recv(9999) if not data: stats.truncated += 1 return body += data pid, n, nhit, nmiss, nevict = map(int, body.strip().split()) stats.requests += 1 stats.nobs += n stats.nhits += nhit bypid = stats.bypid.get(pid) if bypid is None: bypid = stats.bypid[pid] = dict(nr=0, n=0, nhit=0) bypid['nr'] += 1 bypid['n'] += n bypid['nhit'] += nhit logger.info(' '.join(map(str, ( 100*stats.nhits/stats.nobs, pid, n, nhit, 100*nhit/n, )))) finally: socket.close()
def producerForward(socket, address): fp = socket.makefile() destfp = "" myid = socket.recv(1024) gevent.sleep(0) while True: chunk = socket.recv(1024) if destfp == "": if myid in glo_consumer_socket: destfp = glo_consumer_socket[myid] else: destfp.send(chunk) gevent.sleep(0)
def handle_APN(socket, address): print 'New APN connection from %s:%s' % address received_data = socket.recv() unpack_received_data(received_data) if not responses_saved: socket.settimeout(1) try: socket.recv(64) except: pass else: response = responses_saved.popleft() socket.sendall(response)
def read_line(socket): data = "" while(True): byt = socket.recv(1) data+=byt if(byt=='\n' or not byt): return data
def read_line(socket): data = "" while (True): byt = socket.recv(1) data += byt if (byt == '\n' or not byt): return data
def read_until_bytes_received_or_enter_pressed(self, socket, n_bytes): ''' Read bytes from socket until reaching given number of bytes, cancel if enter was pressed. Parameters ---------- socket: Socket to read from. n_bytes: int Number of bytes to read. ''' enter_pressed = False array = '' while len(array) < n_bytes and not enter_pressed: array += socket.recv(n_bytes - len(array)) # check if enter is pressed i,o,e = gevent.select.select([sys.stdin],[],[],0.0001) for s in i: if s == sys.stdin: _ = sys.stdin.readline() enter_pressed = True if enter_pressed: return None else: assert len(array) == n_bytes return array
def read_until_bytes_received_or_enter_pressed(socket, n_bytes): ''' Read bytes from socket until reaching given number of bytes, cancel if enter was pressed. Parameters ---------- socket: Socket to read from. n_bytes: int Number of bytes to read. ''' enter_pressed = False # http://dabeaz.blogspot.de/2010/01/few-useful-bytearray-tricks.html array_parts = [] n_remaining = n_bytes while (n_remaining > 0) and (not enter_pressed): chunk = socket.recv(n_remaining) array_parts.append(chunk) n_remaining -= len(chunk) # check if enter is pressed i, o, e = gevent.select.select([sys.stdin], [], [], 0.0001) for s in i: if s == sys.stdin: _ = sys.stdin.readline() enter_pressed = True if enter_pressed: return None else: array = b"".join(array_parts) assert len(array) == n_bytes return array
def consumerForward(socket, address): fp = socket.makefile() myid = socket.recv(1024) glo_consumer_socket[myid] = socket gevent.sleep(0) while True: gevent.sleep(100)
def _recv_loop(self, socket): while True: data = socket.recv(2048) if not data: logger.info("Connection from %s:%d disconnected" % self.client_address) self._send_queue.put(self) break self.feed(data)
def tcp_echo_func(socket,address): while True: r,_,_ = select.select([socket],[],[],3.) if r: msg = socket.recv(8192) if not msg: return socket.sendall(msg)
def tcp_echo_func(socket, address): while True: r, _, _ = select.select([socket], [], [], 3.) if r: msg = socket.recv(8192) if not msg: return socket.sendall(msg)
def read_until_bytes_received(socket, n_bytes): array_parts = [] n_remaining = n_bytes while n_remaining > 0: chunk = socket.recv(n_remaining) array_parts.append(chunk) n_remaining -= len(chunk) array = b"".join(array_parts) return array
def main(): """ Spawns greenlets for processing incoming messages, then listens for UDP packets, handing them off to those greenlets. """ # Yes, friends, the log aggregator does some logging of its own. logging.basicConfig(level=setting('LOG_LEVEL'), format=setting('LOG_FORMAT')) logging.info('Starting up') if len(sys.argv) > 1: settings.import_config_file(sys.argv[1]) _validate_settings() # Setup our objects message_queue, message_rate, message_buffer = _create_queue_rate_buffer() # Start the message processor, and the loop that triggers flushing. gevent.spawn(processor, message_queue, message_buffer) gevent.spawn(flush_trigger, message_buffer, message_rate) # Ensure that we flush the buffer on exit no matter what. # Pylint thinks we never use this. # pylint: disable=W0612 @atexit.register def flush_on_exit(): """ Ensures that the flusher runs when exiting. """ flusher_greenlet = gevent.spawn(flusher, message_buffer, message_rate) flusher_greenlet.join() # pylint: enable=W0612 # Create a socket to listen to incoming messages. socket = gevent.socket.socket(family=gevent.socket.AF_INET, type=gevent.socket.SOCK_DGRAM) socket.bind(setting('UDP_BIND')) logging.info('Listening on %r', setting('UDP_BIND')) # As messages arrive, unpack them and put them into the queue. count = 0 while True: try: data = socket.recv(setting('INCOMING_MESSAGE_MAX_SIZE')) obj = json.loads(data) record = logging.makeLogRecord(obj) message_queue.put(vars(record)) # Too general an exception but we want to make sure we recover # cleanly. # pylint: disable=W0703 except Exception, exc: count += 1 logging.exception('Error on incoming packet: %s', exc) message_queue.put(_make_fake_record(count, exc))
def recv_enough(socket, size): buf = io.BytesIO() more = size while more: chunk = socket.recv(more) if not chunk: raise EOFError buf.write(chunk) more -= len(chunk) return buf.getvalue()
def client_service(socket): while True: print("2") data = socket.recv(1024) if not data: socket.close() return else: send_data = "return : ".encode("gb2312") + data socket.send(send_data)
def client_service(): for socket in client_list: print("2") data = socket.recv(1024) if not data: socket.close() return else: send_data = "return : ".encode("gb2312")+ data socket.send(send_data)
def handle(self, socket, addr): self.conn = socket print('Connected by', addr) while True: try: chunk = socket.recv(2048) if chunk == '': raise RuntimeError("socket connection broken") self.received_data(chunk) except: pass
def handle_connection(socket, address): request_line = read_line(socket) try: request_type, request_path, http_version = request_line.split(" ") except: socket.close() print "new request", request_line headers = {} while (True): l = read_line(socket) if (l == '\r\n'): break if (not l): return header_type, data = l.split(": ", 1) headers[header_type] = data post_data = None if (request_type == "POST" and headers.get("Content-Length", None)): n = int(headers.get("Content-Length", "0").strip(" \r\n")) if (n > 0): data = "" while (len(data) < n): bts = socket.recv(n) if (not bts): break data += bts post_data = urlparse.parse_qs(data) ##app specific headers auth_key = headers.get("auth-key", None) user = None if (auth_key): #decode and get user auth_key = urllib.unquote(auth_key).strip() user = User.objects.get( pk=decode_signed_value(config.SERVER_SECRET, "auth_key", auth_key)) for handler in request_handlers: args = handler[0].match(request_path) func = handler[1] kwargs = {"user": user} if (post_data != None): kwargs["post"] = post_data if (args != None): fargs = args.groups() if (fargs): func(socket, *fargs, **kwargs) else: func(socket, **kwargs)
def handle_connection(socket, address): request_line = read_line(socket) try: request_type , request_path , http_version = request_line.split(" ") except: socket.close() print "new request", request_line headers = {} while(True): l = read_line(socket) if(l=='\r\n'): break if( not l): return header_type , data = l.split(": ",1) headers[header_type] = data post_data = None if(request_type == "POST" and headers.get("Content-Length", None)): n = int(headers.get("Content-Length","0").strip(" \r\n")) if(n>0): data = "" while(len(data) < n): bts = socket.recv(n) if(not bts): break data +=bts post_data = urlparse.parse_qs(data) ##app specific headers auth_key = headers.get("auth-key", None) user = None if(auth_key): #decode and get user auth_key = urllib.unquote(auth_key).strip() user = User.objects.get(pk = decode_signed_value(config.SERVER_SECRET , "auth_key", auth_key)) for handler in request_handlers: args = handler[0].match(request_path) func = handler[1] kwargs = {"user":user} if(post_data!=None): kwargs["post"] = post_data if(args!=None): fargs = args.groups() if(fargs): func(socket, *fargs , **kwargs) else: func(socket, **kwargs)
def peek_http_host(socket): host = '' hostheader = re.compile('host: ([^\(\);:,<>]+)', re.I) # Peek up to 512 bytes into data for the Host header for n in [128, 256, 512]: bytes = socket.recv(n, MSG_PEEK) if not bytes: break for line in bytes.split('\r\n'): match = hostheader.match(line) if match: host = match.group(1) if host: break return host
def _recv_nbytes_from_socket(self, socket, n): """Read n bytes from a socket. This function does not use timeouts. You must wrap calls to this function with gevent.Timeout() context managers.""" output = [] bytes_read = 0 while True: chunk = socket.recv(n) if chunk != '': output.append(chunk) bytes_read += len(chunk) if bytes_read >= n: break return ''.join(output)
def handle_connection(self, socket, address): start = datetime.datetime.now() data = socket.recv(104857600) end = datetime.datetime.now() data = data.split('\n') if self.debug: print("New incoming {} connection from {}".format(data[0], address)) if data[0] == 'ECHO': socket.send(data[0]) socket.close() elif data[0] == 'UPDATE': data = json.loads(data[1]) self.handle_update(data) self.propagate_update(data) socket.close() elif data[0] == 'DATA': print start print end delay = (((end - start) / 2).microseconds) / 1000.0 print delay data = json.loads(data[1]) self.handle_data(data) self.propagate_data(data) socket.close(); elif data[0] == 'STATUS': status = 'Node: ' + self.this_node + '\n' status += 'Connected nodes: ' + str(self.g.nodes()) + '\n' for a,b in self.g.edges(): status += str(a) + ' ' + str(b) + ' ' + str(self.g[a][b]['weight']) + '\n' if self.debug: print status socket.send(status) socket.close() else: print 'UNRECOG: ' print data
def dummy_server_loop(socket, address): msg_parser = message_key_types.Message() try: while True: wait_read(socket.fileno()) buf = socket.recv(8192) if len(buf) == 0: break msg_parser.recv(buf) while True: msg = msg_parser.parse() if msg is None: break result_queue.put(msg) except: print("## disconnected")
def unpack_response(self, resp_code, socket): result = struct.unpack('!B', socket.recv(1))[0] if result == 0: result_data = struct.unpack('!HBBHH', socket.recv(8)) name_len = struct.unpack('!H', socket.recv(2))[0] nodename = struct.unpack('!%ds' % name_len, socket.recv(name_len)) extra_len = struct.unpack('!H', socket.recv(2))[0] extra = struct.unpack('!%ds' % extra_len, socket.recv(extra_len)) return tuple(list(result_data) + list(nodename) + list(extra))
def handle_log(self, socket): """ Process a single log record that come from a socket :param socket: """ log = socket.recv(self.MAX_LOG_SIZE) match = self.regexp.match(log) if not match: record = LogRecord('gsyslogd', syslog.LOG_DAEMON, syslog.LOG_ERR, str(datetime.datetime.now()), "%s: Malformed log: '%s'" % ( self.__class__.__name__, log)) record.log() raise MalformedLog(log) # convert priority string into facility and priority priority = int(match.group('facility_priority')) severity = priority % 8 facility = (priority - severity) / 8 return match, severity, facility
def handler(socket, address): host = peek_http_host(socket) hostname = host.split(':')[0] if not hostname: logging.debug("!no hostname, closing") socket.close() return redirect_url = lookup_txt_attribute(hostname, 'location', '_redirect') if redirect_url: # only append path in request if redirect location # is completely pathless. ex: http://example.com # however, we don't pass query params... if redirect_url.count('/') == 2: req_tip = socket.recv(256) method, path, _ = req_tip.split(' ', 2) redirect_url = '{0}{1}'.format(redirect_url, urlparse.urlparse(path).path) resp = """ HTTP/1.1 301 Moved Permanently\r\nLocation: {0}\r\nConnection: close\r\nContent-Length: 0\r\n\r\n """.format(redirect_url).strip() socket.sendall(resp) socket.close() return proxy_to = lookup_txt_attribute(hostname, 'address', '_proxy') if proxy_to: address = proxy_to.split(':') if len(address) == 1: address = (address[0], 80) try: backend = gevent.socket.create_connection(address) # TODO: insert headers: Via, X-Forwarded-For, Host join_sockets(socket, backend) except IOError: socket.close() return
def recv_req(): content = "" while True: try: recv_buf = socket.recv(1024) if len(recv_buf) == 0: break except Exception, e: logging.warning('recv_req error: ' + str(e)) break content += recv_buf mem_content = memoryview(content) cur_index = 0 while cur_index < len(content): if len(mem_content[cur_index:]) < 6: break elif mem_content[cur_index:cur_index + 2] != 'PB': cur_index += 2 # skip the first 2 bytes break (buf_size,) = struct.unpack('!I', mem_content[cur_index + 2: cur_index + 6].tobytes()) if len(mem_content[cur_index + 6:]) < buf_size: break pb_buf = mem_content[cur_index + 6: cur_index + 6 + buf_size].tobytes() cur_index += buf_size + 6 result = self.parse_message(pb_buf) if result is None: logging.warning('pb decode error, skip this message') break self._spawn(call_service, result) if cur_index > 0: content = content[cur_index:]
def read_until_bytes_received_or_enter_pressed(socket, n_bytes): ''' Read bytes from socket until reaching given number of bytes, cancel if enter was pressed. Parameters ---------- socket: Socket to read from. n_bytes: int Number of bytes to read. ''' enter_pressed = False # http://dabeaz.blogspot.de/2010/01/few-useful-bytearray-tricks.html array_parts = [] n_remaining = n_bytes while (n_remaining > 0) and (not enter_pressed): chunk = socket.recv(n_remaining) array_parts.append(chunk) n_remaining -= len(chunk) # check if enter is pressed # throws exception on windows. needed?->yes! when stopped the program saves model and data # i, o, e = gevent.select.select([sys.stdin], [], [], 0.0001) # for s in i: # if s == sys.stdin: # _ = sys.stdin.readline() # enter_pressed = True input_string = my_async_stdin_reader.input_async() if input_string is not None: enter_pressed = True if enter_pressed: return None else: array = b"".join(array_parts) assert len(array) == n_bytes return array
def unpack_response(self, resp_code, socket): return struct.unpack('!BH', socket.recv(3))
def handle(socket, address): """每个协程运行的主函数,每当某个设备发起链接,服务器创建一个新的协程运行该函数 这个函数首先检测是否是有效设备发起的链接,正常设备发起链接,首先需要上报该设备的物理地址,通过这个检测之后,然后使用全局变量`greenlets`以及数据库来确定该设备的具体情况 接下来是这个函数的主要部分: 一个无限循环,在循环过程中转发用户命令,监控设备状态,处理设备上报信息 单次循环具体流程描述如下: 首先检查`redis`是否含有发向当前设备的命令: 如果有,执行相应命令; 如果没有,则尝试接收设备的上报信息(具体流程参见`send_command`); 执行下次循环; :param socket: 设备和程序之间的链接 :param address: 设备具体`IP`地址以及端口 :return: 无返回值 """ logging.info("设备接入: %s" % socket) try: MAC = socket.recv(4096) except: logging.critical(sys.exc_info()[1][1]) logging.critical("接收数据失败") socket.close() return if not re.match("[0-9A-F]{12}", MAC): logging.critical("物理地址无效: %s" % MAC) socket.close() return logging.info("物理地址: %s" % MAC) # time.sleep(2) # # logging.info("发送测试命令: %s" % MAC) # # # test_connection(MAC, socket, connection, cursor) # connection = pymysql.connect(host="", user="", passwd="", db="") connection.autocommit(1) cursor = connection.cursor() if MAC not in greenlets: greenlets[MAC] = gevent.getcurrent() cursor.execute("SELECT id FROM device WHERE mac = %s", MAC) logging.debug(cursor._last_executed) if not cursor.fetchall(): logging.info("新的设备: %s" % MAC) logging.info("发送测试命令: %s" % MAC) # test_connection(MAC, socket, connection, cursor) # current_time = str(datetime.now()).split('.')[0] cursor.execute("INSERT INTO device (mac, online, ctime, utime, ip) VALUES (%s, %s, %s, %s, %s)", (MAC, 1, current_time, current_time, address[0])) logging.debug(cursor._last_executed) else: logging.info("程序重启") cursor.execute("UPDATE device SET online = 1 WHERE mac = %s", MAC) logging.debug(cursor._last_executed) else: greenlets[MAC] = gevent.getcurrent() logging.info("旧的设备: %s" % MAC) cursor.execute("UPDATE device SET online = 1 WHERE mac = %s", MAC) logging.debug(cursor._last_executed) while 1: connection.ping() task = redis_client.rpop(MAC) if not task: cursor.execute("SELECT online FROM device WHERE mac = %s", MAC) logging.debug(cursor._last_executed) online = cursor.fetchone()[0] logging.info("%s 设备当前状态: %s" % (MAC, online)) if online: logging.info("%s 尝试接收数据" % MAC) try: data = socket.recv(4096) except gevent.socket.timeout: continue except gevent.socket.error: cursor.execute("UPDATE device SET online = 0 WHERE mac = %s", MAC) logging.debug(cursor._last_executed) logging.critical(sys.exc_info()[1][1]) cursor.close() connection.close() socket.close() return logging.info("%s 发送 %s" % (MAC, data)) if data: handle_report(MAC, socket, connection, cursor, data) else: cursor.execute("UPDATE device SET online = 0 WHERE mac = %s", MAC) logging.debug(cursor._last_executed) logging.critical("设备返回空值") cursor.close() connection.close() socket.close() return else: logging.critical("设备已经离线") cursor.close() connection.close() socket.close() return else: task = ast.literal_eval(task) logging.info("命令: %s" % str(task)) if task["type"] == -1: delete(MAC, socket, connection, cursor, task) return elif task["type"] == 0: turnof(MAC, socket, connection, cursor, task) continue elif task["type"] == 1: turnon(MAC, socket, connection, cursor, task) continue elif task["type"] == 2: heartbeat(MAC, socket, connection, cursor, task) continue elif task["type"] == 4: read_temperature_humidity(MAC, socket, connection, cursor, task) continue elif task["type"] == 6: check_status(MAC, socket, connection, cursor, task) continue elif task["type"] == 7: read_remaining_potion(MAC, socket, connection, cursor, task) continue
def read_until_bytes_received(self, socket, n_bytes): array = '' while len(array) < n_bytes: array += socket.recv(n_bytes - len(array)) return array
def handler(socket, address): while True: if not socket.recv(1000): break
def recvall(socket, addr): while socket.recv(4096): pass
def handle(socket, address): while True: data = socket.recv(1024) if not data: break log.append(data)
def handle(socket, address): """每个协程运行的主函数,每当某个设备发起链接,服务器创建一个新的协程运行该函数 这个函数首先检测是否是有效设备发起的链接,正常设备发起链接,首先需要上报该设备的物理地址,通过这个检测之后,然后使用全局变量`greenlets`以及数据库来确定该设备的具体情况 接下来是这个函数的主要部分: 一个无限循环,在循环过程中转发用户命令,监控设备状态,处理设备上报信息 单次循环具体流程描述如下: 首先检查`redis`是否含有发向当前设备的命令: 如果有,执行相应命令; 如果没有,则尝试接收设备的上报信息(具体流程参见`send_command`); 执行下次循环; :param socket: 设备和程序之间的链接 :param address: 设备具体`IP`地址以及端口 :return: 无返回值 """ logging.info("设备接入: %s" % socket) try: MAC = socket.recv(4096) except: logging.critical(sys.exc_info()[1][1]) logging.critical("接收数据失败") socket.close() return if not re.match("[0-9A-F]{12}", MAC): logging.critical("物理地址无效: %s" % MAC) socket.close() return logging.info("物理地址: %s" % MAC) # time.sleep(2) # # logging.info("发送测试命令: %s" % MAC) # # # test_connection(MAC, socket, connection, cursor) # connection = pymysql.connect(host="", user="", passwd="", db="") connection.autocommit(1) cursor = connection.cursor() if MAC not in greenlets: greenlets[MAC] = gevent.getcurrent() cursor.execute("SELECT id FROM device WHERE mac = %s", MAC) logging.debug(cursor._last_executed) if not cursor.fetchall(): logging.info("新的设备: %s" % MAC) logging.info("发送测试命令: %s" % MAC) # test_connection(MAC, socket, connection, cursor) # current_time = str(datetime.now()).split('.')[0] cursor.execute( "INSERT INTO device (mac, online, ctime, utime, ip) VALUES (%s, %s, %s, %s, %s)", (MAC, 1, current_time, current_time, address[0])) logging.debug(cursor._last_executed) else: logging.info("程序重启") cursor.execute("UPDATE device SET online = 1 WHERE mac = %s", MAC) logging.debug(cursor._last_executed) else: greenlets[MAC] = gevent.getcurrent() logging.info("旧的设备: %s" % MAC) cursor.execute("UPDATE device SET online = 1 WHERE mac = %s", MAC) logging.debug(cursor._last_executed) while 1: connection.ping() task = redis_client.rpop(MAC) if not task: cursor.execute("SELECT online FROM device WHERE mac = %s", MAC) logging.debug(cursor._last_executed) online = cursor.fetchone()[0] logging.info("%s 设备当前状态: %s" % (MAC, online)) if online: logging.info("%s 尝试接收数据" % MAC) try: data = socket.recv(4096) except gevent.socket.timeout: continue except gevent.socket.error: cursor.execute( "UPDATE device SET online = 0 WHERE mac = %s", MAC) logging.debug(cursor._last_executed) logging.critical(sys.exc_info()[1][1]) cursor.close() connection.close() socket.close() return logging.info("%s 发送 %s" % (MAC, data)) if data: handle_report(MAC, socket, connection, cursor, data) else: cursor.execute( "UPDATE device SET online = 0 WHERE mac = %s", MAC) logging.debug(cursor._last_executed) logging.critical("设备返回空值") cursor.close() connection.close() socket.close() return else: logging.critical("设备已经离线") cursor.close() connection.close() socket.close() return else: task = ast.literal_eval(task) logging.info("命令: %s" % str(task)) if task["type"] == -1: delete(MAC, socket, connection, cursor, task) return elif task["type"] == 0: turnof(MAC, socket, connection, cursor, task) continue elif task["type"] == 1: turnon(MAC, socket, connection, cursor, task) continue elif task["type"] == 2: heartbeat(MAC, socket, connection, cursor, task) continue elif task["type"] == 4: read_temperature_humidity(MAC, socket, connection, cursor, task) continue elif task["type"] == 6: check_status(MAC, socket, connection, cursor, task) continue elif task["type"] == 7: read_remaining_potion(MAC, socket, connection, cursor, task) continue
def listen2( self, socket,address): print "listen2" print self.pool.free_count() while True: name =socket.recv(1010).strip() print name
def readall(socket, address): while socket.recv(1024): pass
def send_command(MAC, socket, connection, cursor, command, response_length=0, response_type=0, times=5): """通过链接发送命令,等待响应,返回有效响应数据 这个函数默认发送五次命令,如果其中有一次发送成功,同时没有其它错误,则返回有效响应数据(删除响应头,命令类型以及校验和),结束循环,函数返回. 下面介绍每次循环的流程: 首先通过链接尝试发送数据,如果出现异常,关闭连接,清理资源; 然后通过链接尝试接收数据,如果出现异常,关闭连接,清理资源,如果等待超时,进入下次循环,重新发送命令; 获得响应数据,如果响应数据为空,关闭连接,清理资源; 然后检验响应数据类型是否与期望相符,如果相符,则验证校验和,如果校验通过,返回有效响应数据,否则进入下次循环,重新发送命令; 如果响应数据类型与期望不符,把设备响应信息当作上报信息处理 *因为处理上报信息过程中发送的命令无需返回,所以发送之后,函数直接返回,不进行后续操作* 如果五次循环过后,仍未获得有效响应数据,关闭链接,清理资源 :param MAC: 设备的物理地址(唯一标志) :param socket: 设备和程序之间的链接 :param connection: 当前协程的数据库链接(每个协程使用独立的数据库链接) :param cursor: 当前协程的数据库游标(每个协程使用独立的数据库游标) :param command: 待发送的命令 :param response_length: 因为设备返回的响应数据不遵循标准,所以需要根据协议手动获取有效响应数据 :param response_type: 期望的响应数据的类型,用来检查响应数据是否是上报信息 :param times: 循环发送命令的次数,默认值`5` :return: 如果一切正常,返回有效响应数据;如果指定循环次数过后,仍未获得有效响应数据,返回`None` """ for _ in xrange(times): try: socket.send(set_checksum(command)) except: cursor.execute("UPDATE device SET online = 0 WHERE mac = %s", MAC) logging.debug(cursor._last_executed) logging.critical(sys.exc_info()[1][1]) cursor.close() connection.close() socket.close() return if response_length == 0 and response_type == 0: return else: while 1: logging.info("%s 尝试接收数据" % MAC) try: response = socket.recv(4096) except gevent.socket.timeout: break except gevent.socket.error: cursor.execute( "UPDATE device SET online = 0 WHERE mac = %s", MAC) logging.debug(cursor._last_executed) logging.critical(sys.exc_info()[1][1]) cursor.close() connection.close() socket.close() return logging.info("%s 发送 %s" % (MAC, str(hexlify(response[:response_length])))) if response: data = translate(response, "client") if data[2] != response_type: handle_report(MAC, socket, connection, cursor, response) break else: if not get_checksum(response[:response_length]): logging.error("%s 响应校验出错" % MAC) break else: return data[3:-1] else: cursor.execute( "UPDATE device SET online = 0 WHERE mac = %s", MAC) logging.debug(cursor._last_executed) logging.critical("%s 设备返回空值" % MAC) cursor.close() connection.close() socket.close() return cursor.execute("UPDATE device SET online = 0 WHERE mac = %s", MAC) logging.debug(cursor._last_executed) logging.critical("%s 等待响应超时" % MAC) cursor.close() connection.close() socket.close() return None
def shandler(socket,address): print address print socket.recv(10) socket.send("good")
def send_command(MAC, socket, connection, cursor, command, response_length=0, response_type=0, times=5): """通过链接发送命令,等待响应,返回有效响应数据 这个函数默认发送五次命令,如果其中有一次发送成功,同时没有其它错误,则返回有效响应数据(删除响应头,命令类型以及校验和),结束循环,函数返回. 下面介绍每次循环的流程: 首先通过链接尝试发送数据,如果出现异常,关闭连接,清理资源; 然后通过链接尝试接收数据,如果出现异常,关闭连接,清理资源,如果等待超时,进入下次循环,重新发送命令; 获得响应数据,如果响应数据为空,关闭连接,清理资源; 然后检验响应数据类型是否与期望相符,如果相符,则验证校验和,如果校验通过,返回有效响应数据,否则进入下次循环,重新发送命令; 如果响应数据类型与期望不符,把设备响应信息当作上报信息处理 *因为处理上报信息过程中发送的命令无需返回,所以发送之后,函数直接返回,不进行后续操作* 如果五次循环过后,仍未获得有效响应数据,关闭链接,清理资源 :param MAC: 设备的物理地址(唯一标志) :param socket: 设备和程序之间的链接 :param connection: 当前协程的数据库链接(每个协程使用独立的数据库链接) :param cursor: 当前协程的数据库游标(每个协程使用独立的数据库游标) :param command: 待发送的命令 :param response_length: 因为设备返回的响应数据不遵循标准,所以需要根据协议手动获取有效响应数据 :param response_type: 期望的响应数据的类型,用来检查响应数据是否是上报信息 :param times: 循环发送命令的次数,默认值`5` :return: 如果一切正常,返回有效响应数据;如果指定循环次数过后,仍未获得有效响应数据,返回`None` """ for _ in xrange(times): try: socket.send(set_checksum(command)) except: cursor.execute("UPDATE device SET online = 0 WHERE mac = %s", MAC) logging.debug(cursor._last_executed) logging.critical(sys.exc_info()[1][1]) cursor.close() connection.close() socket.close() return if response_length == 0 and response_type == 0: return else: while 1: logging.info("%s 尝试接收数据" % MAC) try: response = socket.recv(4096) except gevent.socket.timeout: break except gevent.socket.error: cursor.execute("UPDATE device SET online = 0 WHERE mac = %s", MAC) logging.debug(cursor._last_executed) logging.critical(sys.exc_info()[1][1]) cursor.close() connection.close() socket.close() return logging.info("%s 发送 %s" % (MAC, str(hexlify(response[:response_length])))) if response: data = translate(response, "client") if data[2] != response_type: handle_report(MAC, socket, connection, cursor, response) break else: if not get_checksum(response[:response_length]): logging.error("%s 响应校验出错" % MAC) break else: return data[3:-1] else: cursor.execute("UPDATE device SET online = 0 WHERE mac = %s", MAC) logging.debug(cursor._last_executed) logging.critical("%s 设备返回空值" % MAC) cursor.close() connection.close() socket.close() return cursor.execute("UPDATE device SET online = 0 WHERE mac = %s", MAC) logging.debug(cursor._last_executed) logging.critical("%s 等待响应超时" % MAC) cursor.close() connection.close() socket.close() return None
def handle(socket, address): while True: data = socket.recv(1024) log.append(data) if not data: break
def tcp_handler(socket, address, conn_data, accept_count): need_to_close = False need_to_send_data = False accepted_name = conn_data['name'] + '-%d' % accept_count conn_greenlets[accepted_name] = { 'greenlet': Greenlet.getcurrent(), 'result': None, 'data': None } DBG('new tcp accepted from %s:%s conn_data = %r' % (address[0], address[1], conn_data)) data_pack = dict(name=conn_data['name'], accepted_name=accepted_name, op="accepted", remote_ip=address[0], remote_port=address[1], local_port=conn_data['specific_port'], type='tcpserver') re = guifeeder_socket.sendto(json.dumps(data_pack), GUIFEEDER_ADDRESS) DBG("sent to gui feeder %r" % re) while True: try: if need_to_close: DBG('tcp_handler need_to_close') socket.close() conn_greenlets[accepted_name]['result'].set({'result': 'ok'}) return if need_to_send_data: try: re = socket.send( base64.b64decode( conn_greenlets[accepted_name]['data'])) conn_greenlets[accepted_name]['result'].set('ok') DBG("sent to remote %r" % re) need_to_send_data = False except: DBG_TRACE() conn_greenlets[accepted_name]['result'].set('error') data = socket.recv(8012) if not data: # closed by remote DBG('tcp_handler got nothing') socket.close() data_pack = {"name": accepted_name, "op": "disconnected"} re = guifeeder_socket.sendto(json.dumps(data_pack), GUIFEEDER_ADDRESS) del conn_greenlets[accepted_name] DBG("sent to gui feeder %r" % re) return # die else: DBG(type(data)) DBG('tcp_handler %s got %r' % (time.ctime(), bytearray(data))) data_pack = { "name": accepted_name, "op": "recvdata", "text": base64.b64encode(bytearray(data)) } # socket.send('hi') re = guifeeder_socket.sendto(json.dumps(data_pack), GUIFEEDER_ADDRESS) DBG("sent to gui feeder %r" % re) except CloseSocket: DBG("tcp_handler CloseSocket") need_to_close = True except SendData: DBG("tcp_handler SendData") need_to_send_data = True except: DBG_TRACE() data_pack = { "name": conn_data['name'], 'type': conn_data['type'], "op": "error", 'msg': base64.b64encode(str(sys.exc_info()[1])) } socket.close() del conn_greenlets[conn_data['name']] re = guifeeder_socket.sendto(json.dumps(data_pack), GUIFEEDER_ADDRESS) DBG("sent to gui feeder %r" % re) return
def __call__(self, socket, addr): try: ctx = self._run(socket, addr) except Exception as err: if isinstance(self.bind_addr, str): bind_addr = self.bind_addr else: bind_addr = "%s:%d" % self.bind_addr if slowdown.gvars.logger.level <= slowdown.logging.DEBUG: slowdown.gvars.logger.debug(utils.exc()) elif slowdown.gvars.logger.level <= slowdown.logging.INFO: slowdown.gvars.logger.info( f'{"%s:%d" % addr} - ' f'\033[32m{self.proto}://\033[0m{bind_addr} - ' f'\033[33m{err}\033[0m') return if ctx.via_socket is None: if slowdown.gvars.logger.level <= slowdown.logging.INFO: if isinstance(self.bind_addr, str): bind_addr = self.bind_addr else: bind_addr = "%s:%d" % self.bind_addr if REJECT == ctx.mode: slowdown.gvars.logger.info( f'{"%s:%d" % addr} - ' f'\033[32m{ctx.proto}://\033[0m{bind_addr} - ' '\033[31mADBLK\033[0m - ' f'{"%s:%d" % ctx.target_addr}') else: slowdown.gvars.logger.info( f'{"%s:%d" % addr} - ' f'\033[32m{ctx.proto}://\033[0m{bind_addr} - ' f'\033[35mPERFORMED\033[0m') return if slowdown.gvars.logger.level <= slowdown.logging.INFO: if isinstance(self.bind_addr, str): bind_addr = self.bind_addr else: bind_addr = "%s:%d" % self.bind_addr if DIRECT == ctx.mode: slowdown.gvars.logger.info( f'{"%s:%d" % addr} - ' f'\033[32m{ctx.proto}://\033[0m{bind_addr} - ' f'{"%s:%d" % ctx.target_addr}') elif PROXY == ctx.mode: slowdown.gvars.logger.info( f'{"%s:%d" % addr} - ' f'\033[32m{ctx.proto}://\033[0m{bind_addr} - ' f'\033[32m{self.via.proto}://\033[0m' f'{"%s:%d" % self.via.bind_addr} - ' f'{"%s:%d" % ctx.target_addr}') else: slowdown.gvars.logger.info( f'{"%s:%d" % addr} - ' f'\033[32m{ctx.proto}://\033[0m{bind_addr} - ' f'\033[31mLIMBO-{ctx.mode}\033[0m - ' f'{"%s:%d" % ctx.target_addr}') reverse_relay_task = \ gevent.spawn( reverse_relay, gevent.getcurrent(), socket, ctx.via_socket ) while True: try: data = socket.recv(gvars.PACKET_SIZE) except gevent.GreenletExit: break except: reverse_relay_task.kill(block=False) if slowdown.gvars.logger.level <= slowdown.logging.DEBUG: slowdown.gvars.logger.debug(utils.exc()) break if not data: reverse_relay_task.kill(block=False) break if ctx.via_socket.closed: return try: ctx.via_socket.sendall(data) except gevent.GreenletExit: break except: reverse_relay_task.kill(block=False) if slowdown.gvars.logger.level <= slowdown.logging.DEBUG: slowdown.gvars.logger.debug(utils.exc()) break