First commit

This commit is contained in:
Yui
2026-05-02 20:54:01 -03:00
commit 1f6b38c894
9 changed files with 244 additions and 0 deletions

29
client/SocketClient.py Normal file
View File

@@ -0,0 +1,29 @@
import socket as s
from logging import Logger
from abc import ABC, abstractmethod
class SocketClient(ABC):
ip: str = ""
port: int = 0
socket: s.socket
logger: Logger
def __init__(self, ip: str, port: int, logger: Logger):
if port <= 0 or port > 65535:
raise ValueError("Port out of range.")
self.ip = ip
self.port = port
self.logger = logger
@abstractmethod
def Connect(self) -> bool:
pass
@abstractmethod
def Reconnect(self) -> bool:
pass
@abstractmethod
def Send(self, data: str):
pass

42
client/TCPClient.py Normal file
View File

@@ -0,0 +1,42 @@
import socket as s
from SocketClient import SocketClient
from select import select
class TCPClient(SocketClient):
def Connect(self) -> bool:
self.socket = s.socket(s.AF_INET, s.SOCK_STREAM)
try:
self.socket.connect((self.ip, self.port))
except ConnectionRefusedError:
self.logger.fatal("TCP_FATAL_CONNECT %s:%d" % (self.ip, self.port))
return False
self.socket.setblocking(False)
return True
def Reconnect(self) -> bool:
self.socket.close()
return self.Connect()
def Send(self, data: str):
try:
self.socket.sendall(data.encode())
self.logger.info("TCP_SENT %s" % data)
self.Receive()
except Exception as ex:
self.logger.fatal("TCP_FATAL_SEND %s" % ex)
def Receive(self):
(incoming, _, _) = select([self.socket], [], [], 0)
if incoming:
try:
data = self.socket.recv(1024)
if not data:
self.socket.close()
self.logger.error("TCP_NO_DATA")
return
self.logger.info("TCP_SUCCESS %s" % data.decode())
except InterruptedError as ex:
self.logger.error("TCP_FAIL %s" % ex)
self.Reconnect()

53
client/UDPClient.py Normal file
View File

@@ -0,0 +1,53 @@
from SocketClient import SocketClient
import time
import socket
import select
class UDPClient(SocketClient):
_timestamps: set[float] = set()
_last_check = time.time()
def Connect(self) -> bool:
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.socket.setblocking(False)
return True
def Send(self, data: str):
now = time.time()
data = "%s/%f" % (data, now)
self.socket.sendto(data.encode(), (self.ip, self.port))
self.logger.info("UDP_SENT %s" % data)
self._timestamps.add(now)
print(self._timestamps)
self.Receive()
self.staleCheck()
def Reconnect(self) -> bool:
return True
def Receive(self):
(incoming, _, _) = select.select([self.socket], [], [], 0)
if incoming:
data, addr = self.socket.recvfrom(1024)
timestamp = data.split(b"/")[1]
print(timestamp.decode())
self.logger.info("UDP_SUCCESS %s (%s)" % (data.decode(), addr))
self._timestamps.discard(float(timestamp.decode()))
print(self._timestamps)
def staleCheck(self):
if (time.time() - self._last_check) < 1:
return
timedout_timestamps = set()
for timestamp in self._timestamps:
if (self._last_check - timestamp) < 10:
continue
self.logger.error("UDP_FAIL %f" % timestamp)
print(self._timestamps)
timedout_timestamps.add(timestamp)
self._last_check = time.time()
for timestamp in timedout_timestamps:
self._timestamps.discard(timestamp)

Binary file not shown.

Binary file not shown.

Binary file not shown.

63
client/main.py Normal file
View File

@@ -0,0 +1,63 @@
import logging as log
import time
import datetime
from TCPClient import TCPClient
from UDPClient import UDPClient
IP = "10.69.0.2"
TCP_PORT = 6069
UDP_PORT = 5069
class SuperGreatFormatter(log.Formatter):
def formatTime(self, record, datefmt=None):
if not datefmt:
return super().formatTime(record, datefmt=datefmt)
return (
datetime.datetime.fromtimestamp(record.created)
.astimezone()
.strftime(datefmt)
)
def setupLogger() -> log.Logger:
logger = log.getLogger("client")
logger.setLevel(log.DEBUG)
filehandler = log.FileHandler(
filename="client-%s.csv" % datetime.datetime.now().isoformat(),
encoding="utf-8",
mode="a+",
)
filehandler.setFormatter(
SuperGreatFormatter(
"{message},{levelname},{asctime}", "%Y-%m-%d %H:%M:%S.%f %z", "{"
)
)
logger.addHandler(filehandler)
streamhandler = log.StreamHandler()
streamhandler.setFormatter(
log.Formatter("[{asctime}]{levelname}: {message}", "%Y-%m-%d %H:%M:%S", "{")
)
logger.addHandler(streamhandler)
return logger
def main():
logger = setupLogger()
tcp = TCPClient(IP, TCP_PORT, logger)
udp = UDPClient(IP, UDP_PORT, logger)
tcp.Connect()
udp.Connect()
while True:
# tcp.Send("meow")
udp.Send("woof")
time.sleep(9)
if __name__ == "__main__":
main()