Skip to content

Instantly share code, notes, and snippets.

@kollad
Last active December 19, 2015 09:49
Show Gist options
  • Select an option

  • Save kollad/5936073 to your computer and use it in GitHub Desktop.

Select an option

Save kollad/5936073 to your computer and use it in GitHub Desktop.
import collections
import hashlib
import logging
import pickle
import socket
import struct
from threading import Thread
__author__ = 'kollad'
log = logging.getLogger(__name__)
class Command(object):
def __init__(self, action, value):
self.action = action
self.value = value
def execute(self):
print('Executing {action} with params {value}'.format(action=self.action, value=self.value))
class Server(object):
def __init__(self, host='0.0.0.0', port=7777):
self.host = host
self.port = port
self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self._socket.bind((self.host, self.port))
self._socket.listen(10)
def handler(self, connection, address):
while 1:
data = connection.recv(1024)
print('Received data from client {}: {}'.format(address, data))
if not data:
break
self.process(data, address)
msg = b'Echo:' + data
connection.sendall(msg)
connection.close()
def connect(self):
while 1:
print('Waiting for connection...')
connection, address = self._socket.accept()
print('Connected: {}'.format(address))
thread = Thread(target=self.handler, args=(connection, address))
thread.start()
thread.join()
def calculate_checksum(self, obj):
return hashlib.md5(pickle.dumps(obj)).hexdigest()
def unpack(self, data):
(i,), data = struct.unpack('!I', data[:4]), data[4:]
(action,), data = struct.unpack('!{}s'.format(i), data[:i]), data[i:]
(value,), data = struct.unpack('!h', data[:2]), data[2:]
(checksum,) = struct.unpack('!{}s'.format(len(data)), data)
action = str(action, 'utf-8')
checksum = str(checksum, 'utf-8')
command = {
'action': action,
'value': value,
}
return command, checksum
def validate_checksum(self, command, checksum):
assert self.calculate_checksum(command) == checksum, 'Probably a malformed request'
def process(self, packet, address):
print('Processing data. Client: {}'.format(address))
command, checksum = self.unpack(packet)
self.validate_checksum(command, checksum)
Command(*command.values()).execute()
if __name__ == '__main__':
server = Server()
server.connect()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment