Advertisement
rfmonk

epoll_web_serv.py

Jul 15th, 2014
256
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.21 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. """
  4. Simple web server using select.epoll
  5. Using Python 2.7
  6. code from python network programming cookbook
  7. slightly modified
  8. """
  9.  
  10. import socket
  11. import select
  12. import argparse
  13. SERVER_HOST = 'localhost'
  14. EOL1 = b'\n\n'
  15. EOL2 = b'\n\r\n'
  16. SERVER_RESPONSE = b"""HTTP/1.1 200 OK\r\nDate: Mon, Jul 2014 21:37:01 \
  17.        GMT\r\nContent-Type: text/plain\r\nContent-Length: 25\r\n\r\n \
  18.        Hello from Epoll Server!"""
  19.  
  20. class EpollServer(object):
  21.     """ a socket server using epoll """
  22.     def __init__(self, host=SERVER_HOST, port=0):
  23.         self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  24.         self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  25.         self.sock.bind((host, port))
  26.         self.sock.listen(1)
  27.         self.sock.setblocking(0)
  28.         self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
  29.         print "Started Epoll Server"
  30.         self.epoll = select.epoll()
  31.         self.epoll.register(self.sock.fileno(), select.EPOLLIN)
  32.  
  33.     def run(self):
  34.         """ executes epoll server with an ak47 """
  35.         try:
  36.             connections = {}; requests = {}; responses= {}
  37.             while True:
  38.                 events = self.epoll.poll(1)
  39.                 for fileno, event in events:
  40.                     if fileno == self.sock.fileno():
  41.                         connection, address = self.sock.accept()
  42.                         connection.setblocking(0)
  43.                         self.epoll.register(connection.fileno(), \
  44.                                 select.EPOLLIN)
  45.                         connections[connection.fileno()] = connection
  46.                         requests[connection.fileno()] = b''
  47.                         responses[connection.fileno()] = SERVER_RESPONSE
  48.                     elif event & select.EPOLLIN:
  49.                         requests[fileno] += connections[fileno].recv(1024)
  50.                         if EOL1 in requests[fileno] or EOL2 in requests [fileno]:
  51.                             self.epoll.modify(fileno, select.EPOLLOUT)
  52.                             print ('-' * 40 + '\n' + requests[fileno].decode() [:-2])
  53.                         elif event & select.EPOLLOUT:
  54.                             byteswritten = connections[fileno].send(responses[fileno])
  55.                             responses[fileno] = responses[fileno] [byteswritten:]
  56.                             if len(responses[fileno]) == 0:
  57.                                 self.epoll.modify(fileno, 0)
  58.                                 connections[fileno].shutdown(socket.SHUT_RDWR)
  59.                             elif event & select.EPOLLHUP:
  60.                                 self.epoll.unregister(fileno)
  61.                                 connections[fileno].close()
  62.                                 del connections[fileno]
  63.  
  64.         finally:
  65.             self.epoll.unregister(self.sock.fileno())
  66.             self.epoll.close()
  67.             self.sock.close()
  68.  
  69. if __name__ == '__main__':
  70.     parser = argparse.ArgumentParser(description='Socket Server Example with Epoll')
  71.     parser.add_argument('--port', action="store", dest="port", type=int, required=True)
  72.     given_args = parser.parse_args()
  73.     port = given_args.port
  74.     server = EpollServer(host=SERVER_HOST, port=port)
  75.     server.run()
  76.  
  77. # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement