Skip to content

Instantly share code, notes, and snippets.

@maxdeliso
Last active December 21, 2015 05:49
Show Gist options
  • Save maxdeliso/6259538 to your computer and use it in GitHub Desktop.
Save maxdeliso/6259538 to your computer and use it in GitHub Desktop.
PyPu
#! /usr/bin/env python3.3
# PyPu: Simple UDP chat.
import logging
import curses
import curses.ascii
from socketserver import UDPServer
from socketserver import BaseRequestHandler
class PuChat(UDPServer):
# module constants
PU_MAJOR_VER = 0
PU_MINOR_VER = 1
PU_HOST = ""
PU_PORT = 1337
PU_POLL = 0.1
def __init__(self):
# chain call UDPServer constructor with nested class for handler
super(PuChat, self).__init__((self.PU_HOST, self.PU_PORT), self.PuHandler)
# configure logger output to file
logging.basicConfig(filename='pupu.log',level=logging.DEBUG)
# print version info
logging.info(sys.version + '\nPU_VER: {}.{}'.format(
self.PU_MAJOR_VER, self.PU_MINOR_VER))
# only wait for this many seconds
self.timeout = self.PU_POLL
# log
logging.info("starting UDP server on port: {}".
format(self.PU_PORT))
# initialize terminal and make it non-blocking
self.win = curses.initscr()
self.win.nodelay(1)
TERM_HEIGHT, TERM_WIDTH = self.win.getmaxyx()
logging.info("initialized terminal with dimensions {} by {}".
format(TERM_WIDTH, TERM_HEIGHT))
assert TERM_HEIGHT > 4
self.netWin = self.win.subwin(TERM_HEIGHT - 3, TERM_WIDTH - 2, 1, 1)
self.netWin.idlok(True)
self.netWin.scrollok(True)
self.localWin = self.win.subwin(1, TERM_WIDTH - 2, TERM_HEIGHT - 2, 1)
curses.noecho()
curses.nonl()
def __loop(self):
""" main i/o loop """
while True:
self.handle_request()
userCh = self.win.getch()
if(userCh != -1 and curses.ascii.isalnum(userCh)):
self.localWin.addch(userCh)
self.localWin.refresh()
# TODO: handle sending and clearing localWin
def start(self):
""" initiate i/o loop and clean-up gracefully afterwards """
logging.info("entering main loop")
try:
self.__loop()
except KeyboardInterrupt:
self.win.addstr('shutting down...')
finally:
curses.endwin()
logging.info("exiting main loop")
class PuHandler(BaseRequestHandler):
""" class to deal with UDP messages. poll driven """
def handle(self):
# alias into locals
msgData = self.request[0]
peerSocket = self.request[1]
peerAddress = self.client_address[0]
win = self.server.netWin
logging.info("received {} bytes from sender: {}".format(
len(msgData), peerAddress))
# print out the received message and its origin
win.addstr("{} >> {}\n".format(peerAddress, msgData))
win.refresh()
# echo received message back to sender over UDP
peerSocket.sendto(msgData, self.client_address)
if __name__ == "__main__":
import sys
chat = PuChat()
chat.start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment