client_channel_socket.py
6.52 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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#!/usr/bin/env python3
"""Socket Client implementation (TCP or UDP)
"""
# Standard library imports
import socket
# Third party imports
# None
# Local application imports
from devices_controller.channels.client_channel import *
##class SocketClientAbstract():
class ClientChannelSocket(ClientChannel):
# Select protocol here (udp or tcp)
buf = 1024
mysock = None
# STAMP :
# 00 00 00 00 00 00 00' (8 bytes from '00' to 'FF', 1st one is LOW BYTE)
# ex: 01 + STAMP = 01 00 00 00 00 00 00 00' (8 bytes from '00' to 'FF', 1st one is LOW BYTE)
#STAMP_FILLER = '00000000000000'
'''
STAMP_FILLER = '000000'
MYSTAMP = '01'
MY_FULL_STAMP = MYSTAMP + STAMP_FILLER
'''
def __init__(self, server_host:str="localhost", server_port:int=11110, PROTOCOL:str="SOCKET-TCP", buffer_size=1024, DEBUG=False):
'''
:param server_host: server IP or hostname
:param server_port: server port
:param PROTOCOL: "SOCKET-UDP" or "SOCKET-TCP"
'''
myprotocol = socket.SOCK_DGRAM if PROTOCOL=="SOCKET-UDP" else socket.SOCK_STREAM
self.mysock = socket.socket(socket.AF_INET, myprotocol)
super().__init__(server_host, server_port, PROTOCOL, buffer_size, DEBUG)
# Logger configuration
#self.set_logger()
'''
log_d("\n**************************")
log_d("Logger configured")
log_d("Client instanciated")
'''
'''
def _send_data(self, data_to_send:str):
#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")
#print("before sending", data_to_send)
data_to_send_bytes = data_to_send.encode("utf-8")
#data_to_send_bytes = data_to_send.encode()
#print("before sending", data_to_send_bytes)
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:
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")
'''
'''
def _receive_data(self)->bytes:
data_received = self.mysock.recv(self.buf)
#log_d("data type is "+str(type(data_received)))
log_i(f"RECEIVED (ALL BYTES): {data_received}")
#return str(data_received, "utf-8")
return data_received
'''
# Only for TCP ; does nothing for UDP
#@override
def _connect_to_server(self):
if self.PROTOCOL=="SOCKET-TCP": self.mysock.connect((self.HOST, self.PORT))
print(f"Ready to send commands to HOST {self.HOST} on PORT {self.PORT} \n")
# Close socket
def close(self):
self.mysock.close()
#@override
def _send_data(self, data_to_send:str):
#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")
#@override
def _receive_data(self)->str:
data_received_bytes = self.mysock.recv(self.buf)
#TODO: resoudre ce pb plus proprement (utiliser unicode au lieu de utf-8 codec ???
# BUGFIX: b'\xdf' (should correspond to "°" symbol) generates a UnicodeDecodeError,
# so, replace it by ':' (b'\x3A')
if b'\xdf' in data_received_bytes:
data_received_bytes = data_received_bytes.replace(b'\xdf', b'\x3A')
log_i(f"RECEIVED (ALL BYTES): {data_received_bytes}")
data_received = data_received_bytes.decode()
#log_d("data type is "+str(type(data_received)))
#return str(data_received, "utf-8")
return data_received
'''
# Encapsulate useful data to be ready for sending
#@override
def encapsulate_data_to_send(self, data:str):
#return bytes(data, "utf-8")
return data.encode("utf-8")
# Extract data from received raw data
#@override
def uncap_received_data(self, data_received_bytes:bytes):
#return data_received.decode("utf-8)
return data_received_bytes.decode()
'''
# TODO: empecher de creer une instance de cette classe abstraite
# Avec ABC ?
'''
if __name__ == "__main__":
#HOST, PORT = "localhost", 9999
#HOST, PORT = "localhost", 20001
HOST, PORT = "localhost", 11110
# Classic usage:
#tsock = SocketClient_UDP_TCP(HOST, PORT, "UDP")
# More elegant usage, using "with":
with SocketClient_ABSTRACT(HOST, PORT, "UDP") as tsock:
# 0) CONNECT to server (only for TCP, does nothing for UDP)
tsock._connect_to_server()
while True:
# 1) SEND REQUEST data to server
# saisie de la requête au clavier et suppression des espaces des 2 côtés
data = input("REQUEST TO SERVER [ex: ':GD#' (Get Dec), ':GR#' (Get RA)']: ").strip()
# test d'arrêt
if data=="": break
#data_to_send = bytes(data + "\n", "utf-8")
tsock.send_data(data)
#mysock.sendto("%s" % data, (HOST, PORT))
#print("Sent: {}".format(data))
# 2) RECEIVE REPLY data from server
data_received = tsock.receive_data()
#reponse, adr = mysock.recvfrom(buf)
#print("Received: {}".format(data_received))
#print("Useful data received: {}".format(data_useful))
print('\n')
#tsock.close()
'''