def listen_to_nls_sync(q: Queue): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # addr = ("10.250.42.142", 7677) addr = ("192.168.1.161", 7677) sock.connect(addr) bufsock = BufferedSocket(sock, maxsize=READ_LIMIT, timeout=None) sock.send(json.dumps(CONN_PARAMS).encode()) while True: message = bufsock.recv_until(b"\r\n") message_json = json.loads(message.decode("utf-8")) message_type = message_json["type"] if message_type in ["teams", "boxscore"]: store[message_type] = message_json if message_type == "teams": determine_sides(message_json) process_teams(message_json, q) q.sync_q.put(message_json) q.sync_q.put({"homeKey": HOME}) q.sync_q.put({"awayKey": AWAY}) logger.info(f"Home is {HOME} and away is {AWAY}") else: q.sync_q.put({"boxscore": message_json}) elif message_type == "playbyplay": plays = message_json["actions"] compute_stats(q) elif message_type == "action": plays.append(message_json) process_action(message_json, q) updated_computed(message_json, q) if message_type != "boxscore": pprint(message_json) pass
def get_bs_pair(): x, y = socket.socketpair() bx, by = BufferedSocket(x), BufferedSocket(y) # sanity check by.sendall(b'123') bx.recv_size(3) == b'123' return bx, by
def call(self, *commands): ''' Helper function that implements a (subset of) the RESP protocol used by Redis >= 1.2 ''' cm = context.get_context().connection_mgr sock = BufferedSocket(cm.get_connection(self.address)) # ARRAY: first byte *, decimal length, \r\n, contents out = ['*' + str(len(commands))] + \ ["${0}\r\n{1}".format(len(e), e) for e in commands] out = "\r\n".join(out) + "\r\n" sock.send(out) fbyte = sock.peek(1) if fbyte == "-": # error string raise RedisError(sock.recv_until('\r\n')) elif fbyte == '+': # simple string resp = sock.recv_until('\r\n')[1:] elif fbyte == '$': # bulk string length = int(sock.recv_until('\r\n')[1:]) if length == -1: resp = None else: resp = sock.recv_size(length) cm.release_connection(sock) return resp
def test_buffers(): x, y = socket.socketpair() bx, by = BufferedSocket(x), BufferedSocket(y) assert by.getrecvbuffer() == b'' assert by.getsendbuffer() == b'' assert bx.getrecvbuffer() == b'' by.buffer(b'12') by.sendall(b'3') assert bx.recv_size(1) == b'1' assert bx.getrecvbuffer() == b'23' return
def handle_client(self, sock, addr): 'Make sockets available to next process.' bsock = BufferedSocket(sock) secret = bsock.recv_size(len(self.secret)) if secret != self.secret: bsock.send('BAD SECRET.') sock.close() return send_socks = [] for server_sock in self.sockets.values(): if sock.getsockname() == server_sock.getsockname(): continue # exclude the socket-passing-socket send_socks.append(server_sock) sock.send(str(len(send_socks)) + '.') for server_sock in send_socks: sendfileobj.sendfileobj(sock, server_sock) sock.close()
def test_props(): x, y = socket.socketpair() bs = BufferedSocket(x) assert bs.type == x.type assert bs.proto == x.proto assert bs.family == x.family return
def test_split_delim(): delim = b'\r\n' first = b'1234\r' second = b'\n5' x, y = socket.socketpair() bs = BufferedSocket(x) y.sendall(first) try: bs.recv_until(delim, timeout=0.0001) except Timeout: pass y.sendall(second) assert bs.recv_until(delim, with_delimiter=True) == b'1234\r\n' assert bs.recv_size(1) == b'5' return
def test_timeout_setters_getters(): x, y = socket.socketpair() bs = BufferedSocket(x) assert bs.settimeout(1.0) is None assert bs.gettimeout() == 1.0 assert bs.setblocking(False) is None assert bs.gettimeout() == 0.0 assert bs.setblocking(True) is None assert bs.gettimeout() is None
def test_multibyte_delim(): """Primarily tests recv_until with various maxsizes and True/False for with_delimiter. """ delim = b'\r\n' for with_delim in (True, False): if with_delim: cond_delim = b'\r\n' else: cond_delim = b'' empty = b'' small_one = b'1' big_two = b'2' * 2048 for ms in (3, 5, 1024, None): x, y = socket.socketpair() bs = BufferedSocket(x) y.sendall(empty + delim) y.sendall(small_one + delim) y.sendall(big_two + delim) kwargs = {'maxsize': ms, 'with_delimiter': with_delim} assert bs.recv_until(delim, **kwargs) == empty + cond_delim assert bs.recv_until(delim, **kwargs) == small_one + cond_delim try: assert bs.recv_until(delim, **kwargs) == big_two + cond_delim except MessageTooLong: if ms is None: assert False, 'unexpected MessageTooLong' else: if ms is not None: assert False, 'expected MessageTooLong' return
def update_platform(): client = docker.DockerClient(base_url='tcp://172.17.0.1:2375') for container in client.containers.list(): if "ingram" in container.image.tags[0]: socket = container.exec_run("bash", socket=True, stdin=True) socket.output._sock.send(b"cd /root/IdeaProjects/osa\n") socket.output._sock.send(b"git pull origin unstable\n") bf = BufferedSocket(socket.output._sock) pass while True: try: socket.output._sock.settimeout(10) unknown_byte = socket.output._sock.recv(1024) if not unknown_byte: break print(unknown_byte, end='') except: break socket.output._sock.send( b"/usr/local/apache-maven-3.6.1/bin/mvn clean install -f poa\n" ) while True: try: socket.output._sock.settimeout(10) unknown_byte = socket.output._sock.recv(1024) if not unknown_byte: break print(unknown_byte.decode()) except: break # while 1: # # note that os.read does not work # # because it does not TLS-decrypt # # but returns the low-level encrypted data # # one must use "socket.recv" instead # data = socket.output._sock.recv(16384) # if not data: break # print(data) socket.output._sock.send(b"exit\n") print(client.containers.list())
def test_short_lines(): for ms in (2, 4, 6, 1024, None): x, y = socket.socketpair() bs = BufferedSocket(x) y.sendall(b'1\n2\n3\n') assert bs.recv_until(b'\n', maxsize=ms) == b'1' assert bs.recv_until(b'\n', maxsize=ms) == b'2' y.close() assert bs.recv_close(maxsize=ms) == b'3\n' try: bs.recv_size(1) except ConnectionClosed: pass else: assert False, 'expected ConnectionClosed' bs.close() return
def test_basic_nonblocking(): delim = b'\n' # test with per-call timeout x, y = socket.socketpair() bs = BufferedSocket(x) try: bs.recv_until(delim, timeout=0) except socket.error as se: assert se.errno == errno.EWOULDBLOCK y.sendall(delim) # sending an empty message, effectively assert bs.recv_until(delim) == b'' # test with instance-level default timeout x, y = socket.socketpair() bs = BufferedSocket(x, timeout=0) try: bs.recv_until(delim) except socket.error as se: assert se.errno == errno.EWOULDBLOCK y.sendall(delim) assert bs.recv_until(delim) == b'' # test with setblocking(0) on the underlying socket x, y = socket.socketpair() x.setblocking(0) bs = BufferedSocket(x) try: bs.recv_until(delim) except socket.error as se: assert se.errno == errno.EWOULDBLOCK y.sendall(delim) assert bs.recv_until(delim) == b'' return
def __init__(self, back_plane_ip_address=None, subscriber_port='43125', publisher_port='43124', process_name=None, loop_time=.001, gateway_type=BTG_SERVER, publish_topic=None, uuid='e35d6386-1802-414f-b2b9-375c92fa23e0', server_bt_address=None, subscriber_list=None, json_data=False): """ This method initialize the class for operation """ # save input parameters as instance variables self.back_plane_ip_address = back_plane_ip_address self.subscriber_port = subscriber_port self.publisher_port = publisher_port self.loop_time = loop_time self.gateway_type = gateway_type # set the name for the banner depending upon client or server if process_name is None: if self.gateway_type == self.BTG_CLIENT: self.process_name = 'BanyanBluetoothClient' else: self.process_name = 'BanyanBluetoothServer' else: self.process_name = process_name self.publish_topic = publish_topic self.uuid = uuid self.server_bt_address = server_bt_address self.json_data = json_data # initialize the parent super(BlueToothGateway, self).__init__(back_plane_ip_address=self.back_plane_ip_address, subscriber_port=self.subscriber_port, publisher_port=self.publisher_port, process_name=self.process_name, loop_time=self.loop_time) self.subscriber_list = subscriber_list for topic in self.subscriber_list: self.set_subscriber_topic(topic) print('Subscribed to: ', topic) print('Publish to : ', self.publish_topic) mac = self.find_local_mac_address() if mac: print('Local Bluetooth MAC Address: ', mac) else: print('No Bluetooth Interface Found - Exiting') sys.exit(0) if self.gateway_type == self.BTG_SERVER: self.server_sock = BluetoothSocket(RFCOMM) self.server_sock.bind(("", PORT_ANY)) self.server_sock.listen(1) port = self.server_sock.getsockname()[1] advertise_service( self.server_sock, "BanyanBlueToothServer", service_id=uuid, service_classes=[uuid, SERIAL_PORT_CLASS], profiles=[SERIAL_PORT_PROFILE], ) print("Waiting for connection on RFCOMM channel %d" % port) try: self.client_sock, self.client_info = self.server_sock.accept() except KeyboardInterrupt: self.clean_up() sys.exit(0) print("Accepted connection from ", self.client_info) else: service_matches = find_service(uuid=self.uuid, address=self.server_bt_address) if len(service_matches) == 0: print("Could not find the remote Bluetooth server - exiting") self.clean_up() sys.exit(0) first_match = service_matches[0] port = first_match["port"] name = first_match["name"] host = first_match["host"] print("connecting to \"%s\" on %s" % (name, host)) # Create the client socket self.client_sock = BluetoothSocket(RFCOMM) self.client_sock.connect((host, port)) # wrap the socket for both client and server self.bsock = BufferedSocket(self.client_sock) # create a thread to handle receipt of bluetooth data threading.Thread.__init__(self) self.daemon = True # start the thread self.start() # this will keep the program running forever try: self.receive_loop() except KeyboardInterrupt: self.clean_up() sys.exit(0)
class BlueToothGateway(BanyanBase, threading.Thread): """ This class implements Bluetooth an RFCOMM server or client, configurable from command line options. usage: bluetooth_gateway.py [-h] [-a SERVER_BT_ADDRESS] [-b BACK_PLANE_IP_ADDRESS] [-g GATEWAY_TYPE] [-j JSON_DATA] [-l PUBLISH_TOPIC] [-m SUBSCRIBER_LIST [SUBSCRIBER_LIST ...]] [-n PROCESS_NAME] [-p PUBLISHER_PORT] [-s SUBSCRIBER_PORT] [-t LOOP_TIME] [-u UUID] optional arguments: -h, --help show this help message and exit -a SERVER_BT_ADDRESS Bluetooth MAC Address of Bluetooth Gateway -b BACK_PLANE_IP_ADDRESS None or IP address used by Back Plane -g GATEWAY_TYPE Type of Gateway : server or client -j JSON_DATA Bluetooth packets json encoded True or False -l PUBLISH_TOPIC Banyan publisher topic -m SUBSCRIBER_LIST [SUBSCRIBER_LIST ...] Banyan topics space delimited: topic1 topic2 topic3 -n PROCESS_NAME Set process name in banner -p PUBLISHER_PORT Publisher IP port -s SUBSCRIBER_PORT Subscriber IP port -t LOOP_TIME Event Loop Timer in seconds -u UUID Bluetooth UUID """ # gateway types BTG_SERVER = 0 BTG_CLIENT = 1 def __init__(self, back_plane_ip_address=None, subscriber_port='43125', publisher_port='43124', process_name=None, loop_time=.001, gateway_type=BTG_SERVER, publish_topic=None, uuid='e35d6386-1802-414f-b2b9-375c92fa23e0', server_bt_address=None, subscriber_list=None, json_data=False): """ This method initialize the class for operation """ # save input parameters as instance variables self.back_plane_ip_address = back_plane_ip_address self.subscriber_port = subscriber_port self.publisher_port = publisher_port self.loop_time = loop_time self.gateway_type = gateway_type # set the name for the banner depending upon client or server if process_name is None: if self.gateway_type == self.BTG_CLIENT: self.process_name = 'BanyanBluetoothClient' else: self.process_name = 'BanyanBluetoothServer' else: self.process_name = process_name self.publish_topic = publish_topic self.uuid = uuid self.server_bt_address = server_bt_address self.json_data = json_data # initialize the parent super(BlueToothGateway, self).__init__(back_plane_ip_address=self.back_plane_ip_address, subscriber_port=self.subscriber_port, publisher_port=self.publisher_port, process_name=self.process_name, loop_time=self.loop_time) self.subscriber_list = subscriber_list for topic in self.subscriber_list: self.set_subscriber_topic(topic) print('Subscribed to: ', topic) print('Publish to : ', self.publish_topic) mac = self.find_local_mac_address() if mac: print('Local Bluetooth MAC Address: ', mac) else: print('No Bluetooth Interface Found - Exiting') sys.exit(0) if self.gateway_type == self.BTG_SERVER: self.server_sock = BluetoothSocket(RFCOMM) self.server_sock.bind(("", PORT_ANY)) self.server_sock.listen(1) port = self.server_sock.getsockname()[1] advertise_service( self.server_sock, "BanyanBlueToothServer", service_id=uuid, service_classes=[uuid, SERIAL_PORT_CLASS], profiles=[SERIAL_PORT_PROFILE], ) print("Waiting for connection on RFCOMM channel %d" % port) try: self.client_sock, self.client_info = self.server_sock.accept() except KeyboardInterrupt: self.clean_up() sys.exit(0) print("Accepted connection from ", self.client_info) else: service_matches = find_service(uuid=self.uuid, address=self.server_bt_address) if len(service_matches) == 0: print("Could not find the remote Bluetooth server - exiting") self.clean_up() sys.exit(0) first_match = service_matches[0] port = first_match["port"] name = first_match["name"] host = first_match["host"] print("connecting to \"%s\" on %s" % (name, host)) # Create the client socket self.client_sock = BluetoothSocket(RFCOMM) self.client_sock.connect((host, port)) # wrap the socket for both client and server self.bsock = BufferedSocket(self.client_sock) # create a thread to handle receipt of bluetooth data threading.Thread.__init__(self) self.daemon = True # start the thread self.start() # this will keep the program running forever try: self.receive_loop() except KeyboardInterrupt: self.clean_up() sys.exit(0) def incoming_message_processing(self, topic, payload): """ Process the incoming Banyan message to be sent to the Bluetooth network :param topic: topic string :param payload: payload data """ # if the bluetooth device requires json encoding if self.json_data: data_out = json.dumps(payload) data_out = data_out.encode('utf-8') try: self.bsock.send(data_out) except Exception as e: self.clean_up() raise RuntimeError('Write Error') else: # convert the payload to a string data_out = str(payload['report']) data_out = data_out.encode('utf-8') self.client_sock.send(data_out) def find_local_mac_address(self): """ Get the local bluetooth mac address :return: mac address string or None """ proc = subprocess.Popen(['hcitool', 'dev'], stdin=subprocess.PIPE, stdout=subprocess.PIPE) data = proc.communicate() data = data[0].decode() data = data.split('\t') if len(data) < 2: return None else: return data[2].strip() def run(self): """ This is thread that receives packets from the bluetooth interface :return: """ while True: # if json encoding look for termination character # used for a dictionary if self.json_data: try: data = self.bsock.recv_until(b'}', timeout=0, with_delimiter=True) except KeyboardInterrupt: self.clean_up() sys.exit(0) except Exception as e: continue data = data.decode() data = json.loads(data) self.publish_payload(data, self.publish_topic) # data is not json encoded else: try: data = (self.client_sock.recv(1)).decode() except KeyboardInterrupt: self.clean_up() sys.exit(0) payload = {'command': data} self.publish_payload(payload, self.publish_topic)
def millis(): return round(time.time() * 1000) udp_thread = threading.Thread(target=udp_listener_thread, args=()) udp_thread.daemon = True udp_thread.start() print('Waiting for TCP connection...') socket, addr = serversocket.accept() print('Recieved TCP connection from {}!'.format(addr)) serversocket.close() socket = BufferedSocket(socket) class SimpleNamespace(): pass last_frame = SimpleNamespace() lock = threading.Lock() def overwrite(message): global last_message try: print('\r' + ''.join([' '] * len(last_message)), end='') except:
def test_simple_buffered_socket_passthroughs(): x, y = socket.socketpair() bs = BufferedSocket(x) assert bs.getsockname() == x.getsockname() assert bs.getpeername() == x.getpeername()