Sometimes you need to write a large custom networking application that wants to avoid repeated server initialization code that creates a socket, binds to an address, listens, and handles basic errors. There are numerous Python networking libraries out there to help you to remove boiler-plate code. Here, we can examine such a library called Diesel.
Diesel uses a non-blocking technique with co-routines to write networking severs efficiently. As stated on the website, Diesel's core is a tight event loop that uses epoll to deliver nearly flat performance out to 10,000 connections and beyond. Here, we introduce Diesel with a simple echo server. You also need diesel library 3.0 or any later version. You can do that with pip command: $ pip install diesel >= 3.0
.
In the Python Diesel framework, applications are initialized with an instance of the Application()
class and an event handler is registered with this instance. Let's see how simple it is to write an echo server.
Listing 2.5 shows the code on the echo server example using Diesel as follows:
#!/usr/bin/env python # Python Network Programming Cookbook -- Chapter - 2 # This program is optimized for Python 2.7. # It may run on any other version with/without modifications. # You also need diesel library 3.0 or any later version import diesel import argparse class EchoServer(object): """ An echo server using diesel""" def handler(self, remote_addr): """Runs the echo server""" host, port = remote_addr[0], remote_addr[1] print "Echo client connected from: %s:%d" %(host, port) while True: try: message = diesel.until_eol() your_message = ': '.join(['You said', message]) diesel.send(your_message) except Exception, e: print "Exception:",e def main(server_port): app = diesel.Application() server = EchoServer() app.add_service(diesel.Service(server.handler, server_port)) app.run() if __name__ == '__main__': parser = argparse.ArgumentParser(description='Echo server example with Diesel') parser.add_argument('--port', action="store", dest="port", type=int, required=True) given_args = parser.parse_args() port = given_args.port main(port)
If you run this script, the server will show the following output:
$ python 2_5_echo_server_with_diesel.py --port=8800 [2013/04/08 11:48:32] {diesel} WARNING:Starting diesel <hand-rolled select.epoll> Echo client connected from: 127.0.0.1:56603
On another console window, another Telnet client can be launched and the echoing message to our server can be tested as follows:
$ telnet localhost 8800 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Hello Diesel server ? You said: Hello Diesel server ?
The following screenshot illustrates the interaction of the Diesel chat server:
Our script has taken a command-line argument for --port
and passed this to the main()
function where our Diesel application has been initialized and run.
Diesel has a notion of service where an application can be built with many services. EchoServer
has a handler()
method. This enables the server to deal with individual client connections. The Service()
method takes the handler
method and a port number to run that service.
Inside the handler()
method, we determine the behavior of the server. In this case, the server is simply returning the message text.
If we compare this code with Chapter 1, Sockets, IPv4, and Simple Client/Server Programming, in the Writing a simple echo client/server application recipe (listing 1.13a), it is very clear that we do not need to write any boiler-plate code and hence it's very easy to concentrate on high-level application logic.
18.220.124.177