Created
September 4, 2016 08:34
-
-
Save iyer-arvind/cfead281f6eeabb6521ab1276da54beb to your computer and use it in GitHub Desktop.
This is a very simple class for server client persistent data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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