Use thread for receiving data

This commit is contained in:
clerie 2022-01-16 22:17:28 +01:00
parent a8d9afe3d1
commit 1365226c00

View File

@ -1,8 +1,10 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import queue
import select
import socket import socket
import ssl import ssl
import threading
class Connection: class Connection:
""" """
@ -22,9 +24,10 @@ class Connection:
self._host = host self._host = host
self._port = port self._port = port
self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self._recv_buffer = b""
self._socket.settimeout(3) self._received_messages = queue.Queue()
self._close = False
def connect(self): def connect(self):
""" """
@ -32,6 +35,9 @@ class Connection:
""" """
self._socket.connect((self._host, self._port)) self._socket.connect((self._host, self._port))
self._socket.setblocking(False)
threading.Thread(target=self._receive_loop, daemon=True).start()
def send(self, message): def send(self, message):
""" """
@ -42,6 +48,34 @@ class Connection:
self._socket.send(message.encode("utf-8") + b"\0") self._socket.send(message.encode("utf-8") + b"\0")
def _receive_loop(self):
recv_buffer = b""
while not self._close:
if select.select([self._socket], [], []) != ([], [], []):
# wait for data availiable
while True:
# fill buffer with one message
data = self._socket.recv(1024)
if not data:
break
recv_buffer += data
if b"\0" in recv_buffer:
break
if b"\0" not in recv_buffer:
# no new messages
break
message, buffer = recv_buffer.split(b"\0", 1)
recv_buffer = buffer
self._received_messages.put(message)
def recv(self): def recv(self):
""" """
Returns one message Returns one message
@ -49,34 +83,17 @@ class Connection:
Use multiple times to receive multiple messages Use multiple times to receive multiple messages
""" """
data = b"" if self._received_messages.empty():
while True:
try:
new_data = self._socket.recv(1024)
except TimeoutError:
break
data += new_data
if b"\0" in new_data:
break
self._recv_buffer += data
if b"\0" not in self._recv_buffer:
# no new messages
return None return None
message, buffer = self._recv_buffer.split(b"\0", 1) return self._received_messages.get().decode("utf-8")
self._recv_buffer = buffer
return message.decode("utf-8")
def close(self): def close(self):
""" """
Shout down connection Shut down connection
""" """
self._close = True
return self._socket.close() return self._socket.close()
def __del__(self): def __del__(self):