client_channel.py
4.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/usr/bin/env python3
"""Socket Client (abstract)
To be used as a base class (interface) for any concrete socket client class
"""
# Standard library imports
import os
# Third party imports
# None
# Local application imports
from src.logpyros import LogPyros
##from device_controller.logs import *
'''
def printd(*args, **kwargs):
if os.environ.get('PYROS_DEBUG', '0')=='1': print(*args, **kwargs)
'''
##class SocketClientAbstract():
class ClientChannel():
my_channel = None
buf = 1024
#def __init__(self, server_host:str="localhost", server_port:int=11110, PROTOCOL:str="SOCKET-TCP", buffer_size=1024, DEBUG=False):
def __init__(self, server_host:str="localhost", server_port:int=11110, PROTOCOL:str="SOCKET-TCP", buffer_size=1024):
'''
:param server_host: server IP or hostname
:param server_port: server port
:param PROTOCOL: "SOCKET-TCP" or "SOCKET-UDP" or "SERIAL" or "USB" (to be continued...)
'''
self.DEBUG_MODE = os.environ.get('PYROS_DEBUG', '0') == '1'
self.HOST = server_host
self.PORT = server_port
self.PROTOCOL = PROTOCOL
self.buf = buffer_size
self.log = LogPyros(self.__class__.__name__)
# Logger configuration
#self.set_logger()
##set_logger(DEBUG)
self.printd("\n**************************")
##log_d("Client CHANNEL instanciated")
self.printd("Client CHANNEL instanciated")
# So that we can use this with the "with" statement (context manager)
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
self.close()
#printd("Client channel killed")
print("Client channel killed")
# LOG methods
def print(self, *args, **kwargs): self.log.print(*args, **kwargs)
def printd(self, *args, **kwargs): self.log.printd(*args, **kwargs)
def send_data(self, data:str):
##data_encapsulated = self.encapsulate_data_to_send(data)
self._send_data(data)
'''
#data_to_send = bytes(data_to_send + "\n", "utf-8")
#data_to_send = bytes(data_to_send + "\x00", "utf-8")
##data_to_send = bytes(data_to_send, "utf-8")
data_to_send_bytes = data_to_send.encode("utf-8")
#data_to_send_bytes = data_to_send.encode()
if self.PROTOCOL=="SOCKET-TCP":
# Unlike send(), this method sendall() continues to send data from bytes until either all data has been sent or an error occurs.
# None is returned on success.
# On error, an exception is raised, and there is no way to determine how much data, if any, was successfully sent
nb_bytes_sent = self.mysock.sendall(data_to_send_bytes)
else:
# SOCKET-UDP
nb_bytes_sent = self.mysock.sendto(data_to_send_bytes, (self.HOST, self.PORT))
log_i(f'Sent: {data_to_send_bytes}')
log_i(f"Sent {nb_bytes_sent} bytes")
'''
#@abstract
def _send_data(self, data_to_send:str):
pass
def receive_data(self)->str:
data_received = self._receive_data()
##data_received_bytes = self.mysock.recv(self.buf)
#printd("Received (all data): {}".format(data_received))
#printd("data in bytes: "+str(bytes(data_received, "utf-8")))
##data_received_uncaped = self.uncap_received_data(data_received)
#log_i("RECEIVED (useful data): {}".format(data_received))
return data_received
#@abstract
def _receive_data(self)->bytes:
pass
'''
data_received = self.mysock.recv(self.buf)
#printd("data type is "+str(type(data_received)))
log_i(f"RECEIVED (ALL BYTES): {data_received}")
#return str(data_received, "utf-8")
return data_received
'''
#@abstract
def _connect_to_server(self):
pass
# Close socket
def close(self):
self.mysock.close()
'''
put(), read(), put_read() commands
'''
def put(self, data:str):
self.send_data(data)
def read(self)->str:
return self.receive_data()
def put_read(self, data:str)->str:
# send command
self.put(data)
# receive answer (or ack)
return self.read()