2016-11-25 11:01:11 -05:00
|
|
|
import socket
|
|
|
|
|
|
|
|
class PacketUtility:
|
|
|
|
"""The base class of QuickStreamServer and QuickStreamClient."""
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def getMyIP():
|
|
|
|
return socket.gethostbyname(socket.getfqdn())
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def getMyDomainName():
|
|
|
|
return socket.getfqdn()
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get_int(socket, int_length = 2):
|
|
|
|
"""Get a tuple of ints from THE OTHER SIDE!"""
|
|
|
|
size = b""
|
|
|
|
message = b""
|
|
|
|
msg_len = int(0)
|
|
|
|
bytes_recd = int(0)
|
|
|
|
ret = []
|
|
|
|
|
|
|
|
while bytes_recd < int_length:
|
|
|
|
size += socket.recv(int_length - bytes_recd)
|
|
|
|
if size == b"":
|
|
|
|
raise RuntimeError("socket connection broken")
|
|
|
|
bytes_recd = len(size)
|
|
|
|
msg_len = int.from_bytes(size, byteorder = "big")
|
|
|
|
bytes_recd = int(0)
|
|
|
|
|
|
|
|
while bytes_recd < msg_len:
|
|
|
|
message += socket.recv(min(msg_len - bytes_recd, 1024))
|
|
|
|
if bytes_recd == len(message): # if the message wasn't added to
|
|
|
|
raise RuntimeError("socket connection broken")
|
|
|
|
bytes_recd = len(message)
|
|
|
|
socket.send(bytes_recd.to_bytes(int_length, byteorder = "big"))
|
|
|
|
|
|
|
|
for i in range(0, int(msg_len), int_length):
|
|
|
|
ret.append(int.from_bytes(message[i:i+int_length], byteorder = "big"))
|
|
|
|
return tuple(ret)
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get_str(socket):
|
|
|
|
"""get a string from THE OTHER SIDE!"""
|
|
|
|
size = b""
|
|
|
|
message = b""
|
|
|
|
msg_len = int(0)
|
|
|
|
bytes_recd = int(0)
|
|
|
|
#ret = []
|
|
|
|
|
|
|
|
while bytes_recd < 2:
|
|
|
|
size += socket.recv(2 - bytes_recd)
|
|
|
|
if size == b"":
|
|
|
|
raise RuntimeError("socket connection broken")
|
|
|
|
bytes_recd = len(size)
|
|
|
|
msg_len = int.from_bytes(size, byteorder = "big")
|
|
|
|
bytes_recd = int(0)
|
|
|
|
|
|
|
|
while bytes_recd < msg_len:
|
|
|
|
message += socket.recv(min(msg_len - bytes_recd, 1024))
|
|
|
|
if bytes_recd == len(message):
|
|
|
|
raise RuntimeError("socket connection broken")
|
|
|
|
bytes_recd = len(message)
|
|
|
|
socket.send(bytes_recd.to_bytes(2, byteorder = "big"))
|
|
|
|
ret = str(message, "utf-8")
|
|
|
|
return ret
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def send_int(socket, stuff, int_length = 2): #tuple stuff
|
|
|
|
"""Send a tuple of ints to THE OTHER SIDE!"""
|
|
|
|
message = b""
|
|
|
|
|
|
|
|
for thing in stuff:
|
|
|
|
message += int(thing).to_bytes(int_length, byteorder = "big")
|
|
|
|
msg_len = len(message)
|
|
|
|
message = msg_len.to_bytes(int_length, byteorder = "big") + message
|
|
|
|
total_sent = 0
|
|
|
|
|
|
|
|
while total_sent < msg_len + int_length:
|
|
|
|
total_sent += socket.send(message[total_sent:])
|
|
|
|
confirm = socket.recv(int_length)
|
|
|
|
|
|
|
|
if int.from_bytes(confirm, byteorder = "big") == msg_len:
|
|
|
|
return
|
|
|
|
else:
|
|
|
|
raise RuntimeError("incomplete packet sent")
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def send_str(socket, stuff):
|
|
|
|
"""Send a string to THE OTHER SIDE!"""
|
|
|
|
msg_len = len(stuff)
|
|
|
|
message = msg_len.to_bytes(2, byteorder = "big") + bytes(stuff, "utf-8")
|
|
|
|
total_sent = 0
|
|
|
|
|
|
|
|
while total_sent < msg_len + 2:
|
|
|
|
total_sent += socket.send(message[total_sent:])
|
|
|
|
confirm = socket.recv(2)
|
|
|
|
|
|
|
|
if int.from_bytes(confirm, byteorder = "big") == msg_len:
|
|
|
|
return
|
|
|
|
else:
|
|
|
|
raise RuntimeError("incomplete packet sent")
|
|
|
|
|
|
|
|
class QuickStreamServer(PacketUtility):
|
|
|
|
"""Get a server set up easily! Note: This kind of server is NOT always ideal."""
|
|
|
|
|
2016-12-27 14:07:13 -05:00
|
|
|
def __init__(self, port = 1028, expectedClients = 1, ipAddress = ''):
|
2016-11-25 11:01:11 -05:00
|
|
|
"""Creates a quick server using the specified port and number of expected clients."""
|
|
|
|
self.clients = [] # Start with an empty list of clients
|
|
|
|
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
2016-12-27 14:07:13 -05:00
|
|
|
if len(ipAddress) >= 6:
|
2016-11-25 11:01:11 -05:00
|
|
|
address = (ipAddress, port)
|
2016-11-25 12:26:07 -05:00
|
|
|
else:
|
2016-11-25 11:01:11 -05:00
|
|
|
address = (socket.gethostname(), port)
|
|
|
|
serverSocket.bind(address)
|
2016-12-27 14:07:13 -05:00
|
|
|
serverSocket.listen(1)
|
2016-11-25 11:01:11 -05:00
|
|
|
for i in range(expectedClients):
|
|
|
|
self.clients.append(serverSocket.accept())
|
|
|
|
serverSocket.close()
|
|
|
|
|
|
|
|
def __del__(self):
|
2016-12-27 14:07:13 -05:00
|
|
|
self.close()
|
|
|
|
|
|
|
|
def close(self):
|
|
|
|
if self.clients:
|
|
|
|
for i in range(len(self.clients)):
|
|
|
|
self.clients[i][0].close()
|
2016-11-25 11:01:11 -05:00
|
|
|
|
|
|
|
def getByte(self):
|
2016-12-27 14:07:13 -05:00
|
|
|
"""Get a list of byte-size ints from each client."""
|
2016-11-25 11:01:11 -05:00
|
|
|
ret = []
|
|
|
|
for i in range(len(self.clients)):
|
2016-11-25 12:26:07 -05:00
|
|
|
ret.append(QuickStreamServer.get_int(self.clients[i][0], 1))
|
|
|
|
return ret
|
2016-11-25 11:01:11 -05:00
|
|
|
|
|
|
|
def getShort(self):
|
2016-12-27 14:07:13 -05:00
|
|
|
"""Get a list of short ints from each client."""
|
2016-11-25 11:01:11 -05:00
|
|
|
ret = []
|
|
|
|
for i in range(len(self.clients)):
|
2016-11-25 12:26:07 -05:00
|
|
|
ret.append(QuickStreamServer.get_int(self.clients[i][0], 2))
|
|
|
|
return ret
|
2016-11-25 11:01:11 -05:00
|
|
|
|
|
|
|
def getInt(self):
|
2016-12-27 14:07:13 -05:00
|
|
|
"""Get a list of ints from each client."""
|
2016-11-25 11:01:11 -05:00
|
|
|
ret = []
|
|
|
|
for i in range(len(self.clients)):
|
2016-11-25 12:26:07 -05:00
|
|
|
ret.append(QuickStreamServer.get_int(self.clients[i][0], 4))
|
|
|
|
return ret
|
2016-11-25 11:01:11 -05:00
|
|
|
|
|
|
|
def getLong(self):
|
2016-12-27 14:07:13 -05:00
|
|
|
"""Get a list of long ints from each client."""
|
2016-11-25 11:01:11 -05:00
|
|
|
ret = []
|
|
|
|
for i in range(len(self.clients)):
|
2016-11-25 12:26:07 -05:00
|
|
|
ret.append(QuickStreamServer.get_int(self.clients[i][0], 8))
|
|
|
|
return ret
|
2016-11-25 11:01:11 -05:00
|
|
|
|
|
|
|
def getString(self):
|
|
|
|
"""Get a string from each client."""
|
|
|
|
ret = []
|
|
|
|
for i in range(len(self.clients)):
|
|
|
|
ret.append(QuickStreamServer.get_str(self.clients[i][0]))
|
2016-11-25 12:26:07 -05:00
|
|
|
return ret
|
2016-11-25 11:01:11 -05:00
|
|
|
|
|
|
|
def sendByte(self, message):
|
|
|
|
"""Send a tuple of byte-size ints to each client."""
|
2016-12-27 14:07:13 -05:00
|
|
|
if not isinstance(message, tuple): message = tuple(message)
|
2016-11-25 11:01:11 -05:00
|
|
|
for i in range(len(self.clients)):
|
|
|
|
QuickStreamServer.send_int(self.clients[i][0], message, 1)
|
|
|
|
|
|
|
|
def sendShort(self, message):
|
|
|
|
"""Send a tuple of short ints to each client."""
|
2016-12-27 14:07:13 -05:00
|
|
|
if not isinstance(message, tuple): message = tuple(message)
|
2016-11-25 11:01:11 -05:00
|
|
|
for i in range(len(self.clients)):
|
|
|
|
QuickStreamServer.send_int(self.clients[i][0], message, 2)
|
|
|
|
|
|
|
|
def sendByte(self, message):
|
|
|
|
"""Send a tuple of ints to each client."""
|
2016-12-27 14:07:13 -05:00
|
|
|
if not isinstance(message, tuple): message = tuple(message)
|
2016-11-25 11:01:11 -05:00
|
|
|
for i in range(len(self.clients)):
|
|
|
|
QuickStreamServer.send_int(self.clients[i][0], message, 4)
|
|
|
|
|
2016-12-27 14:07:13 -05:00
|
|
|
def sendLong(self, message):
|
2016-11-25 11:01:11 -05:00
|
|
|
"""Send a tuple of long ints to each client."""
|
2016-12-27 14:07:13 -05:00
|
|
|
if not isinstance(message, tuple): message = tuple(message)
|
2016-11-25 11:01:11 -05:00
|
|
|
for i in range(len(self.clients)):
|
|
|
|
QuickStreamServer.send_int(self.clients[i][0], message, 8)
|
|
|
|
|
|
|
|
def sendString(self, message):
|
|
|
|
"""Send a string to each client."""
|
|
|
|
for i in range(len(self.clients)):
|
|
|
|
QuickStreamServer.send_str(self.clients[i][0], message)
|
|
|
|
|
|
|
|
class QuickStreamClient(PacketUtility):
|
|
|
|
"""Get a client set up easily! Note: This kind of client is NOT always ideal."""
|
|
|
|
|
2016-12-27 14:07:13 -05:00
|
|
|
def __init__(self, ipAddress, port = 1028):
|
2016-11-25 11:01:11 -05:00
|
|
|
"""Creates a quick client using the specified IP address and port."""
|
2016-12-27 14:07:13 -05:00
|
|
|
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
|
|
self.server.connect((ipAddress, port))
|
2016-11-25 11:01:11 -05:00
|
|
|
|
|
|
|
def __del__(self):
|
2016-12-27 14:07:13 -05:00
|
|
|
if self.server:
|
|
|
|
self.server.close()
|
|
|
|
|
|
|
|
def close(self):
|
|
|
|
if self.server:
|
|
|
|
self.server.close()
|
2016-11-25 11:01:11 -05:00
|
|
|
|
|
|
|
def getByte(self):
|
|
|
|
"""Get a tuple of byte-size ints from the server."""
|
|
|
|
return QuickStreamClient.get_int(self.server, 1)
|
|
|
|
|
|
|
|
def getShort(self):
|
|
|
|
"""Get a tuple of short ints from the server."""
|
|
|
|
return QuickStreamClient.get_int(self.server, 2)
|
|
|
|
|
|
|
|
def getInt(self):
|
|
|
|
"""Get a tuple of ints from the server."""
|
|
|
|
return QuickStreamClient.get_int(self.server, 4)
|
|
|
|
|
|
|
|
def getLong(self):
|
|
|
|
"""Get a tuple of long ints from the server."""
|
|
|
|
return QuickStreamClient.get_int(self.server, 8)
|
|
|
|
|
|
|
|
def getString(self):
|
|
|
|
"""Get a string from the server."""
|
|
|
|
return QuickStreamClient.get_str(self.server)
|
|
|
|
|
|
|
|
def sendByte(self, message):
|
|
|
|
"""Send a tuple of byte-size ints to the server."""
|
2016-12-27 14:07:13 -05:00
|
|
|
if not isinstance(message, tuple): message = tuple(message)
|
2016-11-25 11:01:11 -05:00
|
|
|
QuickStreamClient.send_int(self.server, message, 1)
|
|
|
|
|
|
|
|
def sendShort(self, message):
|
|
|
|
"""Send a tuple of short ints to the server."""
|
2016-12-27 14:07:13 -05:00
|
|
|
if not isinstance(message, tuple): message = tuple(message)
|
2016-11-25 11:01:11 -05:00
|
|
|
QuickStreamClient.send_int(self.server, message, 2)
|
|
|
|
|
|
|
|
def sendInt(self, message):
|
|
|
|
"""Send a tuple of ints to the server."""
|
2016-12-27 14:07:13 -05:00
|
|
|
if not isinstance(message, tuple): message = tuple(message)
|
2016-11-25 11:01:11 -05:00
|
|
|
QuickStreamClient.send_int(self.server, message, 4)
|
|
|
|
|
|
|
|
def sendLong(self, message):
|
|
|
|
"""Send a tuple of long ints to the server."""
|
2016-12-27 14:07:13 -05:00
|
|
|
if not isinstance(message, tuple): message = tuple(message)
|
2016-11-25 11:01:11 -05:00
|
|
|
QuickStreamClient.send_int(self.server, message, 8)
|
|
|
|
|
|
|
|
def sendString(self, message):
|
|
|
|
"""Send a string to the server."""
|
2016-12-27 14:07:13 -05:00
|
|
|
QuickStreamClient.send_str(self.server, message)
|
2016-11-25 11:01:11 -05:00
|
|
|
|
|
|
|
# Legacy support:
|
|
|
|
get_int = PacketUtility.get_int
|
|
|
|
get_str = PacketUtility.get_str
|
|
|
|
send_int = PacketUtility.send_int
|
|
|
|
send_str = PacketUtility.send_str
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
print("""packets.py
|
|
|
|
Contents:
|
|
|
|
Class PacketUtility: The base class of QuickStreamServer and QuickStreamClient.
|
|
|
|
Methods:
|
|
|
|
getMyIP()
|
|
|
|
get_int(socket, int_length = 2)
|
|
|
|
get_str(socket)
|
|
|
|
send_int(socket, stuff, int_length = 2)
|
|
|
|
send_str(socket, stuff)
|
|
|
|
|
|
|
|
Class QuickStreamServer: Get a server set up easily! Note: This kind of server is NOT always ideal.
|
|
|
|
Methods:
|
|
|
|
QuickStreamServer(port, expectedClients = 1, ipAddress = '')
|
|
|
|
getByte()
|
|
|
|
getShort()
|
|
|
|
getInt()
|
|
|
|
getLong()
|
|
|
|
getString()
|
|
|
|
sendByte(message)
|
|
|
|
sendShort(message)
|
|
|
|
sendInt(message)
|
|
|
|
sendLong(message)
|
|
|
|
sendString(message)
|
|
|
|
Fields:
|
|
|
|
clients
|
|
|
|
|
|
|
|
Class QuickStreamClient: Get a client set up easily! Note: This kind of client is NOT always ideal.
|
|
|
|
Methods:
|
|
|
|
QuickStreamClient(ipAddress, port)
|
|
|
|
getByte()
|
|
|
|
getShort()
|
|
|
|
getInt()
|
|
|
|
getLong()
|
|
|
|
getString()
|
|
|
|
sendByte(message)
|
|
|
|
sendShort(message)
|
|
|
|
sendInt(message)
|
|
|
|
sendLong(message)
|
|
|
|
sendString(message)
|
|
|
|
Fields:
|
|
|
|
server
|
|
|
|
|
|
|
|
Legacy:
|
|
|
|
get_int(socket, int_length = 2)
|
|
|
|
get_str(socket)
|
|
|
|
send_int(socket, stuff, int_length = 2)
|
|
|
|
send_str(socket, stuff)
|
|
|
|
|
|
|
|
This module is meant to be imported along with 'socket'.""")
|