diff options
-rw-r--r-- | server/client.py | 65 | ||||
-rw-r--r-- | server/piztor_server.py | 107 | ||||
-rw-r--r-- | server/ptp.rst | 39 | ||||
-rw-r--r-- | server/rush.py | 12 |
4 files changed, 151 insertions, 72 deletions
diff --git a/server/client.py b/server/client.py index 5b3fde6..40754a9 100644 --- a/server/client.py +++ b/server/client.py @@ -1,31 +1,46 @@ import socket import sys from struct import * +from random import random +from time import sleep -HOST, PORT = "localhost", 9999 -data = "" - -sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - -#data = pack("!B", 0) -#data += "hello" -#data += "\0" -#data += "world" - -data = pack("!BLL", 1, 1234, 5678) -data += "hello, world!" +def get_hex(data): + return "".join([hex(ord(c))[2:].zfill(2) for c in data]) -#data = pack("!BLdd", 2, 1234, 123.123, 12323.23222) -print data - -try: - - sock.connect((HOST, PORT)) - sock.sendall(data) - sock.shutdown(socket.SHUT_WR) - received = sock.recv(1024) -finally: - sock.close() +HOST, PORT = "localhost", 9999 -print "Sent: {}".format(data) -print "Received: {}".format(received[0]) +def gen_auth(username, password): + data = pack("!B", 0) + data += username + data += "\0" + data += password + return data + +def gen_update_location(token, lat, lont): + return pack("!BLdd", 2, token, lat, lont) + +def send(data): + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.connect((HOST, PORT)) + print "sent." + sock.sendall(data) + sock.shutdown(socket.SHUT_WR) + received = sock.recv(1024) + finally: + print "adf" + sock.close() + + print "Sent".format(get_hex(data)) + print "Received: {}".format(get_hex(data)) + return received + +rec = send(gen_auth("hello", "world")) +opt, token, status = unpack("!BLB", rec) +print "status:" + str(status) + +for i in range(10): + rec = send(gen_update_location(token, random(), random())) + opc, status = unpack("!BB", rec) + print "status:" + str(status) + sleep(10) diff --git a/server/piztor_server.py b/server/piztor_server.py index a19989a..f0107b6 100644 --- a/server/piztor_server.py +++ b/server/piztor_server.py @@ -2,14 +2,19 @@ import sqlalchemy import SocketServer, socket, select import struct -from sqlalchemy import create_engine, Column, Integer, String +from sqlalchemy import create_engine +from sqlalchemy import Column, Integer, String, Float from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker +from random import randint engine = create_engine('sqlite:///t.sqlite', echo = True) Base = declarative_base() Session = sessionmaker(bind=engine) +def get_hex(data): + return "".join([hex(ord(c))[2:].zfill(2) for c in data]) + class PiztorError(Exception): def __init__(self, msg): self.err_msg = msg @@ -29,29 +34,30 @@ class ReqInvalidError(ConnectionError): class TokenInvalidError(ConnectionError): def __init__(self): - super(ReqInvalidError, self).__init__("Invalid token") + super(TokenInvalidError, self).__init__("Invalid token") class DataManager(object): - pass + def __init__(self, piz_srv): + self.piz_srv = piz_srv class UserManager(DataManager): + class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key = True) username = Column(String) password = Column(String) + token = Column(Integer) - def get_uid_by_token(self, token): - try: - return self.active_sessions[token] - except: + def get_user_by_token(self, token): + session = Session() + User = UserManager.User + entries = session.query(User).filter(User.token == token).all() + if len(entries) == 0: raise TokenInvalidError() + return entries[0] - def __init__(self): - Base.metadata.create_all(engine) - self.active_sessions = dict() - - def authentication_handle(self, opt_type, data, srv): + def authentication_handle(self, opt_type, data): print "Parsing User Data" pos = -1 for i in xrange(0, len(data)): @@ -70,16 +76,23 @@ class UserManager(DataManager): print (username, password) session = Session() - q = session.query(User).filter(User.username == username) - entry = q.first() + entries = session.query(UserManager.User). \ + filter(UserManager.User.username == username).all() + if len(entries) == 0: + return struct.pack("!BLB", 0, 0, 1) + entry = entries[0] if entry.password != password: # Auth failed - return struct.pack("!BL" - - return struct.pack("!BL", 0, 1234) + print "Login failed!" + return struct.pack("!BLB", 0, 0, 1) + else: # Succeeded + print "Logged in sucessfully!" + entry.token = randint(0, 2147483647) + session.commit() + return struct.pack("!BLB", 0, entry.token, 0) class MesgManager(DataManager): - def mesg_sending_handle(self, opt_type, data, srv): + def mesg_sending_handle(self, opt_type, data): print "Parsing Mesg Data" try: if len(data) < 8: @@ -92,28 +105,42 @@ class MesgManager(DataManager): raise ReqInvalidError() class LocationManager(DataManager): - def location_update_handle(self, opt_type, data, srv): + + class LocationInfo(Base): + __tablename__ = "location_info" + uid = Column(Integer, primary_key = True) + lat = Column(Float(precesion = 64)) + lng = Column(Float(precesion = 64)) + # More: last_update + + def location_update_handle(self, opt_type, data): print "Parsing Loc Data" try: if len(data) < 8: raise ReqInvalidError() - sender_token, lat, lont = struct.unpack("!Ldd", data) - print (sender_token, lat, lont) - return struct.pack("!B", 2) + sender_token, lat, lng = struct.unpack("!Ldd", data) + print "Updateing location data with following info:" + print (sender_token, lat, lng) + + user = self.piz_srv. \ + user_mgr.get_user_by_token(sender_token) + session = Session() + LInfo = LocationManager.LocationInfo + q = session.query(LInfo).filter(LInfo.uid == user.id) + entry = q.first() + entry.lat = lat + entry.lng = lng + session.commit() + print "Location update succeeded!" + return struct.pack("!BB", 2, 0) + except TokenInvalidError: + print "Location update failed!" + return struct.pack("!BB", 2, 1) except struct.error: raise ReqInvalidError() - - class PiztorServer(): - user_mgr = UserManager() - mesg_mgr = MesgManager() - location_mgr = LocationManager() - - mgr_map = [ user_mgr.authentication_handle, - mesg_mgr.mesg_sending_handle, - location_mgr.location_update_handle ] class GenericHandler(SocketServer.StreamRequestHandler): @@ -122,7 +149,7 @@ class PiztorServer(): sock.setblocking(0) data = "" while True: - ready = select.select([sock], [], [], 1) + ready = select.select([sock], [], [], 10) if not ready[0]: raise ReqReadError() buff = sock.recv(4096) @@ -132,23 +159,33 @@ class PiztorServer(): data += buff sock.shutdown(socket.SHUT_RD) - print "Got the data:" - print data + print "Got the data:" + get_hex(data) print "====" if len(data) < 1: raise ReqInvalidError() opt_id = struct.unpack("!B", data[0])[0] - reply = PiztorServer.mgr_map[opt_id](opt_id, data[1:], self) + reply = self.piz_srv.mgr_map[opt_id](opt_id, data[1:]) sock.sendall(reply) sock.close() def __init__(self, host, port): + PiztorServer.GenericHandler.piz_srv = self srv = SocketServer.TCPServer((host, port), PiztorServer.GenericHandler) srv.timeout = 2 self.server = srv + self.user_mgr = UserManager(self) + self.mesg_mgr = MesgManager(self) + self.location_mgr = LocationManager(self) + + self.mgr_map = [ self.user_mgr.authentication_handle, + self.mesg_mgr.mesg_sending_handle, + self.location_mgr.location_update_handle ] + + Base.metadata.create_all(engine) + def run(self): try: diff --git a/server/ptp.rst b/server/ptp.rst index 741e41e..02a862f 100644 --- a/server/ptp.rst +++ b/server/ptp.rst @@ -33,9 +33,14 @@ Piztor Transmission Protocol v0.1 :: - +--1b---+-----4b-----+---1b---+ - | 0x00 | USER_TOKEN | STATUS | - +-uchar-+-----int----+--uchar-+ + +--1b---+-----4b-----+---1b----+ + | 0x00 | USER_TOKEN | STATUS | + +-uchar-+-----int----+--uchar--+ + + STATUS: + + - 0x00 for success + - 0x01 for failure - Message Sending @@ -43,17 +48,22 @@ Piztor Transmission Protocol v0.1 :: - +--1b---+------4b------+------4b-----+ - | 0x01 | SENDER_TOKEN | RECEIVER_ID | - +-uchar-+------int-----+-----int-----+ + +--1b---+------4b------+------4b-----+-----?b-----+ + | 0x01 | SENDER_TOKEN | RECEIVER_ID | MSG_BODY | + +-uchar-+------int-----+-----int-----+------------+ - Response :: - +--1b---+----?b----+ - | 0x01 | RESERVED | - +-uchar-+----------+ + +--1b---+---1b---+ + | 0x01 | STATUS | + +-uchar-+--uchar-+ + + STATUS: + + - 0x00 for success + - 0x01 for invalid token - Location Update @@ -69,9 +79,14 @@ Piztor Transmission Protocol v0.1 :: - +--1b---+----?b----+ - | 0x02 | RESERVED | - +-uchar-+----------+ + +--1b---+---1b---+ + | 0x01 | STATUS | + +-uchar-+--uchar-+ + + STATUS: + + - 0x00 for success + - 0x01 for invalid token - Location Information diff --git a/server/rush.py b/server/rush.py new file mode 100644 index 0000000..e86bb63 --- /dev/null +++ b/server/rush.py @@ -0,0 +1,12 @@ +from subprocess import Popen +procs = [] + +try: + for i in xrange(100): + procs.append(Popen(["python", "client.py"])) + while True: pass + +except KeyboardInterrupt: + print "killing" + for p in procs: + p.kill() |