2023-10-01 22:41:21 +03:00
|
|
|
|
import socket
|
|
|
|
|
|
|
|
|
|
from transport.base import TransportBase
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Transport(TransportBase):
|
|
|
|
|
def __init__(self, config):
|
|
|
|
|
super().__init__(config)
|
|
|
|
|
|
2023-10-09 03:49:29 +03:00
|
|
|
|
if not self.config['host']:
|
|
|
|
|
self.config['host'] = '127.0.0.1'
|
|
|
|
|
|
|
|
|
|
if not self.config['port']:
|
|
|
|
|
self.config['port'] = '12345'
|
|
|
|
|
|
|
|
|
|
self.__connect()
|
2023-10-01 22:41:21 +03:00
|
|
|
|
self.buffer = bytearray()
|
|
|
|
|
|
2023-10-09 03:49:29 +03:00
|
|
|
|
def write_line(self, cmd_str):
|
2023-10-01 22:41:21 +03:00
|
|
|
|
response_string = cmd_str + "\n"
|
2023-10-09 03:49:29 +03:00
|
|
|
|
try:
|
|
|
|
|
self.conn.sendall(bytes(response_string, 'utf-8'))
|
|
|
|
|
except Exception as err:
|
|
|
|
|
print('Can not write line: ', err)
|
|
|
|
|
self.__connect()
|
2023-10-01 22:41:21 +03:00
|
|
|
|
|
2023-10-09 03:49:29 +03:00
|
|
|
|
def read_line(self):
|
|
|
|
|
data = self.__read_buffer()
|
2023-10-01 22:41:21 +03:00
|
|
|
|
|
|
|
|
|
line = self.__findLine(data)
|
|
|
|
|
|
|
|
|
|
return line
|
|
|
|
|
|
|
|
|
|
def close(self):
|
2023-10-09 03:49:29 +03:00
|
|
|
|
self.conn.close()
|
2023-10-01 22:41:21 +03:00
|
|
|
|
self.listener.close()
|
|
|
|
|
|
2023-10-09 03:49:29 +03:00
|
|
|
|
def __connect(self):
|
2023-10-01 22:41:21 +03:00
|
|
|
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as socket_listener:
|
2023-10-09 03:49:29 +03:00
|
|
|
|
socket_listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
|
|
|
socket_listener.bind((self.config['host'], self.config['port']))
|
2023-10-01 22:41:21 +03:00
|
|
|
|
socket_listener.listen()
|
2023-10-09 03:49:29 +03:00
|
|
|
|
socket_listener.setblocking(True)
|
2023-10-01 22:41:21 +03:00
|
|
|
|
|
|
|
|
|
conn, addr = socket_listener.accept()
|
|
|
|
|
self.conn = conn
|
2023-10-09 03:49:29 +03:00
|
|
|
|
|
|
|
|
|
self.listener = socket_listener
|
|
|
|
|
|
|
|
|
|
return 1
|
2023-10-01 22:41:21 +03:00
|
|
|
|
|
|
|
|
|
def __findLine(self, data):
|
|
|
|
|
data_chunk = bytearray(self.buffer)
|
|
|
|
|
data_chunk.extend(data)
|
|
|
|
|
|
|
|
|
|
line_separator_index = data_chunk.find(b"\n")
|
|
|
|
|
|
|
|
|
|
if line_separator_index > 0:
|
|
|
|
|
line = data_chunk[0: line_separator_index]
|
|
|
|
|
self.buffer = data_chunk[line_separator_index+1:]
|
|
|
|
|
|
|
|
|
|
return line.decode('utf-8')
|
2023-10-09 03:49:29 +03:00
|
|
|
|
|
|
|
|
|
def __read_buffer(self):
|
|
|
|
|
data = self.conn.recv(1024) # команды все короткие, нет смысла много читать из буфера
|
|
|
|
|
if not data:
|
|
|
|
|
self.__connect()
|
|
|
|
|
# Если данных нет, то клиент отвалился. Т.к. сокет у нас блокирующийся и recv будет
|
|
|
|
|
# висеть пока туда не придут хоть какие-то данные. В теории, тут можно словить бесконечную рекурсию,
|
|
|
|
|
# но сейчас и так сойдет
|
|
|
|
|
data = self.__read_buffer()
|
|
|
|
|
|
|
|
|
|
return data
|