83 lines
2.0 KiB
Python
83 lines
2.0 KiB
Python
|
import socket
|
||
|
import json
|
||
|
import base64
|
||
|
|
||
|
|
||
|
#
|
||
|
# Universal function to send a given amount of data to a TCP socket.
|
||
|
# It returns True or False, depending on the success of
|
||
|
# sending all the data to the socket.
|
||
|
#
|
||
|
def exact_send(dst, data):
|
||
|
try:
|
||
|
while len(data) != 0:
|
||
|
bytes_sent = dst.send(data)
|
||
|
data = data[bytes_sent:]
|
||
|
return True
|
||
|
except OSError:
|
||
|
return False
|
||
|
|
||
|
|
||
|
#
|
||
|
# Universal function to receive a given amount of data from a TCP socket.
|
||
|
# It returns None or data, depending on the success of
|
||
|
# receiving all the required data from the socket.
|
||
|
#
|
||
|
def exact_recv(src, count):
|
||
|
data = bytearray(0)
|
||
|
while count != 0:
|
||
|
new_data = src.recv(count)
|
||
|
|
||
|
if len(new_data) == 0: return None
|
||
|
|
||
|
data += new_data
|
||
|
count -= len(new_data)
|
||
|
|
||
|
return data
|
||
|
|
||
|
|
||
|
#
|
||
|
# Universal function to send a dictionary message to a TCP socket.
|
||
|
# It actually transmits a JSON object, prefixed by its length (in network byte order).
|
||
|
#
|
||
|
# The JSON object is created from the dictionary.
|
||
|
# It returns True or False, depending on the success of sending the
|
||
|
# message to the socket.
|
||
|
#
|
||
|
def send_dict(dst, msg):
|
||
|
# DEBUG print ("Send: %s" % (msg))
|
||
|
data = bytes(json.dumps(msg), "utf8")
|
||
|
prefixed_data = len(data).to_bytes(4, "big") + data
|
||
|
return exact_send(dst, prefixed_data)
|
||
|
|
||
|
|
||
|
#
|
||
|
# Universal function to receive a dictionary message from a TCP socket.
|
||
|
# It actually receives a JSON object, prefixed by its length (in network byte order).
|
||
|
# The dictionary is created from that JSON object.
|
||
|
#
|
||
|
def recv_dict(src):
|
||
|
prefix = exact_recv(src, 4)
|
||
|
|
||
|
if prefix == None: return None
|
||
|
|
||
|
length = int.from_bytes(prefix, "big")
|
||
|
data = exact_recv(src, length)
|
||
|
|
||
|
if data == None: return None
|
||
|
|
||
|
msg = json.loads(str(data, "utf8"))
|
||
|
# DEBUG print ("Recv: %s" % (msg))
|
||
|
return msg
|
||
|
|
||
|
|
||
|
#
|
||
|
# Universal function to send and receive a dictionary to/from a TCP socket peer.
|
||
|
# It returns None upon an error.
|
||
|
#
|
||
|
def sendrecv_dict(peer, msg):
|
||
|
if send_dict(peer, msg):
|
||
|
return recv_dict(peer)
|
||
|
else:
|
||
|
return None
|