Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import asyncio, socket, hashlib, datetime, struct, json
- LISTEN_PORT = 1111
- COUNT_MAX_PEER = 5
- class Peer(object):
- def __init__(self, server, sock, name):
- self.loop = server.loop
- self.name = name
- self._sock = sock
- self._server = server
- self.loop.create_task(self._peer_handler())
- def send(self, data):
- return self.loop.sock_sendall(self._sock, data)
- async def sendFile(self, filename):
- with open(filename, 'rb') as f:
- return await self.loop.sock_sendfile(self._sock, f)
- async def _peer_handler(self):
- try:
- await self._peer_loop()
- except IOError:
- pass
- finally:
- await self._server.remove(self)
- async def _peer_loop(self):
- while True:
- request = await self.loop.sock_recv(self._sock, 1024)
- print (request)
- indexEndHead = request.find(b'\r\n\r\n')
- if indexEndHead != -1:
- head = request[:indexEndHead].splitlines()
- heads = {title[0]: title[1] for title in [line.split(b':', 1) for line in head[1:]]}
- data = request[indexEndHead+4:]
- date = datetime.datetime.today().timestamp()
- if head[0] == b'MESSANGE':
- await self._server.sendAllPeers({'data': {'type': 'mess', 'text': data.decode('utf-8'), 'name': self.name, "date": date}, 'peer': self})
- elif head[0] == b'NICKNAME':
- newname = data.decode('utf-8')
- await self._server.sendAllPeers({'data': {'type': 'system', 'text': f"user '{self.name}' changed name to '{newname}'", "date": date}, 'peer': self})
- self.name = newname
- elif head[0] == b'FILE':
- tempFileName = hashlib.sha1(struct.pack('f', datetime.datetime.today().timestamp())).hexdigest()
- with open(tempFileName, 'wb') as f:
- numBytes = len(data)
- f.write(data)
- while numBytes < int(heads[b'Content-Length']):
- data = await self.loop.sock_recv(self._sock, 1024)
- numBytes += len(data)
- f.write(data)
- await self._server.sendAllPeers({'data': {'type': 'file', 'name': self.name, 'date': date, 'len': numBytes, 'filename': heads[b'File-name'].decode('utf-8')}, 'temppath': tempFileName, 'peer': self})
- class ChatServer(object):
- def __init__(self, loop, port, max_peer):
- self.loop = loop
- self._serv_sock = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
- self._serv_sock.setblocking(0)
- self._serv_sock.bind(('', port))
- self._serv_sock.listen(max_peer)
- self._peers = []
- self.loop.create_task(self._server())
- async def remove(self, peer):
- self._peers.remove(peer)
- await self.sendAllPeers({'data': {'type': 'system', 'text': 'user %s quit!' % (peer.name,), 'date': datetime.datetime.today().timestamp()}})
- async def sendAllPeers(self, data):
- message = json.dumps(data['data']).encode('utf8')
- for peer in self._peers:
- await peer.send(f"OK\r\nContent-Length:{len(message)}\r\n\r\n".encode('utf-8') + message)
- if data['data']['type'] == 'file':
- await peer.sendFile(data['temppath'])
- async def _server(self):
- while True:
- peer_sock, peer_name = await self.loop.sock_accept(self._serv_sock)
- peer_sock.setblocking(0)
- peer = Peer(self, peer_sock, str(peer_name))
- self._peers.append(peer)
- await self.sendAllPeers({'data': {'type': 'system', 'text': 'user %s connected!' % (peer.name,), 'date': datetime.datetime.today().timestamp()}})
- def main():
- loop = asyncio.get_event_loop()
- ChatServer(loop, LISTEN_PORT, COUNT_MAX_PEER)
- loop.run_forever()
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement