Skip to content

Instantly share code, notes, and snippets.

@iyer-arvind
Created September 4, 2016 08:34
Show Gist options
  • Save iyer-arvind/cfead281f6eeabb6521ab1276da54beb to your computer and use it in GitHub Desktop.
Save iyer-arvind/cfead281f6eeabb6521ab1276da54beb to your computer and use it in GitHub Desktop.
This is a very simple class for server client persistent data
#!/usr/bin/env python
import pickle
import socket
import struct
class BaseSocket(object):
BUFSIZE = 2048
@staticmethod
def _write_ba(socket, bytea):
n = len(bytea)
print('to write: {} bytes'.format(n))
n_bytes = struct.pack('=i', n)
socket.send(n_bytes)
sent = 0
while sent < n:
s = socket.send(bytea[sent:])
if not s:
raise RuntimeError('connection broken')
sent += s
@staticmethod
def _read_ba(socket):
n_bytes = socket.recv(4)
n = struct.unpack('=i', n_bytes)[0]
print('to read: {} bytes'.format(n))
rcv = bytearray()
while len(rcv) < n:
r = min(n-len(rcv), BaseSocket.BUFSIZE)
rcv += socket.recv(r)
return rcv
def write(self, data):
d = pickle.dumps(data)
self.write_ba(d)
def read(self):
d = self.read_ba()
return pickle.loads(d)
class Server(BaseSocket):
def __init__(self, addr, port):
self._socket = socket.socket(
socket.AF_INET, socket.SOCK_STREAM)
if addr is None:
addr = socket.gethostname()
self._socket.bind((addr, port))
self._socket.listen(5)
self.clientsocket = None
self.clientaddress = None
def _connect_loop(self):
print('waiting for connect... ')
self.clientsocket, self.clientaddress = self._socket.accept()
def write_ba(self, bytea):
self._write_ba(self.clientsocket, bytea)
def read_ba(self):
return self._read_ba(self.clientsocket)
def __enter__(self):
self._connect_loop()
return self
def __exit__(self, type, value, traceback):
self.clientsocket.close()
class Client(BaseSocket):
def __init__(self, addr, port):
self.addr, self.port = addr, port
self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def write_ba(self, bytea):
self._write_ba(self._socket, bytea)
def read_ba(self):
return self._read_ba(self._socket)
def __enter__(self):
self._socket.connect((self.addr, self.port))
return self
def __exit__(self, type, value, traceback):
self._socket.close()
if __name__ == '__main__':
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument('mode', choices=['client', 'server'])
parser.add_argument('-i', '--ip-addr', dest='addr', type=str,
required=True)
parser.add_argument('-p', '--port', dest='port', type=int,
required=True)
args = parser.parse_args()
if args.mode == 'server':
cls = Server
else:
cls = Client
with cls(args.addr, args.port) as trns:
while True:
msg = input('(:r to read) >>')
if msg.strip() == ':r':
print(trns.read())
else:
trns.write(msg)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment