<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>select – Wait for I/O Efficiently — Python Module of the Week</title> <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" /> <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: '../', VERSION: '1.132', COLLAPSE_INDEX: false, FILE_SUFFIX: '.html', HAS_SOURCE: true }; </script> <script type="text/javascript" src="../_static/jquery.js"></script> <script type="text/javascript" src="../_static/underscore.js"></script> <script type="text/javascript" src="../_static/doctools.js"></script> <link rel="author" title="About these documents" href="../about.html" /> <link rel="top" title="Python Module of the Week" href="../index.html" /> <link rel="up" title="Internet Protocols and Support" href="../internet_protocols.html" /> <link rel="next" title="SocketServer – Creating network servers." href="../SocketServer/index.html" /> <link rel="prev" title="Non-blocking Communication and Timeouts" href="../socket/nonblocking.html" /> </head> <body> <div class="related"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="../genindex.html" title="General Index" accesskey="I">index</a></li> <li class="right" > <a href="../py-modindex.html" title="Python Module Index" >modules</a> |</li> <li class="right" > <a href="../SocketServer/index.html" title="SocketServer – Creating network servers." accesskey="N">next</a> |</li> <li class="right" > <a href="../socket/nonblocking.html" title="Non-blocking Communication and Timeouts" accesskey="P">previous</a> |</li> <li><a href="../contents.html">PyMOTW</a> »</li> <li><a href="../internet_protocols.html" accesskey="U">Internet Protocols and Support</a> »</li> </ul> </div> <div class="sphinxsidebar"> <div class="sphinxsidebarwrapper"> <h3><a href="../contents.html">Table Of Contents</a></h3> <ul> <li><a class="reference internal" href="#">select – Wait for I/O Efficiently</a><ul> <li><a class="reference internal" href="#select">select()</a><ul> <li><a class="reference internal" href="#timeouts">Timeouts</a></li> </ul> </li> <li><a class="reference internal" href="#poll">poll()</a></li> <li><a class="reference internal" href="#platform-specific-options">Platform-specific Options</a></li> </ul> </li> </ul> <h4>Previous topic</h4> <p class="topless"><a href="../socket/nonblocking.html" title="previous chapter">Non-blocking Communication and Timeouts</a></p> <h4>Next topic</h4> <p class="topless"><a href="../SocketServer/index.html" title="next chapter">SocketServer – Creating network servers.</a></p> <h3>This Page</h3> <ul class="this-page-menu"> <li><a href="../_sources/select/index.txt" rel="nofollow">Show Source</a></li> </ul> <div id="searchbox" style="display: none"> <h3>Quick search</h3> <form class="search" action="../search.html" method="get"> <input type="text" name="q" size="18" /> <input type="submit" value="Go" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> <p class="searchtip" style="font-size: 90%"> Enter search terms or a module, class or function name. </p> </div> <script type="text/javascript">$('#searchbox').show(0);</script> </div> </div> <div class="document"> <div class="documentwrapper"> <div class="bodywrapper"> <div class="body"> <div class="section" id="module-select"> <span id="select-wait-for-i-o-efficiently"></span><h1>select – Wait for I/O Efficiently<a class="headerlink" href="#module-select" title="Permalink to this headline">¶</a></h1> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">Purpose:</th><td class="field-body">Wait for notification that an input or output channel is ready.</td> </tr> <tr class="field"><th class="field-name">Python Version:</th><td class="field-body">1.4 and later</td> </tr> </tbody> </table> <p>The <a class="reference internal" href="#module-select" title="select: Wait for I/O Efficiently"><tt class="xref py py-mod docutils literal"><span class="pre">select</span></tt></a> module provides access to platform-specific I/O monitoring functions. The most portable interface is the POSIX function <a class="reference internal" href="#module-select" title="select: Wait for I/O Efficiently"><tt class="xref py py-func docutils literal"><span class="pre">select()</span></tt></a>, which is available on Unix and Windows. The module also includes <tt class="xref py py-func docutils literal"><span class="pre">poll()</span></tt>, a Unix-only API, and several options that only work with specific variants of Unix.</p> <div class="section" id="select"> <h2>select()<a class="headerlink" href="#select" title="Permalink to this headline">¶</a></h2> <p>Python’s <a class="reference internal" href="#module-select" title="select: Wait for I/O Efficiently"><tt class="xref py py-func docutils literal"><span class="pre">select()</span></tt></a> function is a direct interface to the underlying operating system implementation. It monitors sockets, open files, and pipes (anything with a <tt class="xref py py-func docutils literal"><span class="pre">fileno()</span></tt> method that returns a valid file descriptor) until they become readable or writable, or a communication error occurs. <a class="reference internal" href="#module-select" title="select: Wait for I/O Efficiently"><tt class="xref py py-func docutils literal"><span class="pre">select()</span></tt></a> makes it easier to monitor multiple connections at the same time, and is more efficient than writing a polling loop in Python using socket timeouts, because the monitoring happens in the operating system network layer, instead of the interpreter.</p> <div class="admonition note"> <p class="first admonition-title">Note</p> <p class="last">Using Python’s file objects with <a class="reference internal" href="#module-select" title="select: Wait for I/O Efficiently"><tt class="xref py py-func docutils literal"><span class="pre">select()</span></tt></a> works for Unix, but is not supported under Windows.</p> </div> <p>The echo server example from the <a class="reference internal" href="../socket/index.html#module-socket" title="socket: Network communication"><tt class="xref py py-mod docutils literal"><span class="pre">socket</span></tt></a> section can be extended to watch for more than one connection at a time by using <a class="reference internal" href="#module-select" title="select: Wait for I/O Efficiently"><tt class="xref py py-func docutils literal"><span class="pre">select()</span></tt></a>. The new version starts out by creating a non-blocking TCP/IP socket and configuring it to listen on an address.</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">select</span> <span class="kn">import</span> <span class="nn">socket</span> <span class="kn">import</span> <span class="nn">sys</span> <span class="kn">import</span> <span class="nn">Queue</span> <span class="c"># Create a TCP/IP socket</span> <span class="n">server</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">)</span> <span class="n">server</span><span class="o">.</span><span class="n">setblocking</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="c"># Bind the socket to the port</span> <span class="n">server_address</span> <span class="o">=</span> <span class="p">(</span><span class="s">'localhost'</span><span class="p">,</span> <span class="mi">10000</span><span class="p">)</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'starting up on </span><span class="si">%s</span><span class="s"> port </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="n">server_address</span> <span class="n">server</span><span class="o">.</span><span class="n">bind</span><span class="p">(</span><span class="n">server_address</span><span class="p">)</span> <span class="c"># Listen for incoming connections</span> <span class="n">server</span><span class="o">.</span><span class="n">listen</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span> </pre></div> </div> <p>The arguments to <a class="reference internal" href="#module-select" title="select: Wait for I/O Efficiently"><tt class="xref py py-func docutils literal"><span class="pre">select()</span></tt></a> are three lists containing communication channels to monitor. The first is a list of the objects to be checked for incoming data to be read, the second contains objects that will receive outgoing data when there is room in their buffer, and the third those that may have an error (usually a combination of the input and output channel objects). The next step in the server is to set up the lists containing input sources and output destinations to be passed to <a class="reference internal" href="#module-select" title="select: Wait for I/O Efficiently"><tt class="xref py py-func docutils literal"><span class="pre">select()</span></tt></a>.</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># Sockets from which we expect to read</span> <span class="n">inputs</span> <span class="o">=</span> <span class="p">[</span> <span class="n">server</span> <span class="p">]</span> <span class="c"># Sockets to which we expect to write</span> <span class="n">outputs</span> <span class="o">=</span> <span class="p">[</span> <span class="p">]</span> </pre></div> </div> <p>Connections are added to and removed from these lists by the server main loop. Since this version of the server is going to wait for a socket to become writable before sending any data (instead of immediately sending the reply), each output connection needs a queue to act as a buffer for the data to be sent through it.</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># Outgoing message queues (socket:Queue)</span> <span class="n">message_queues</span> <span class="o">=</span> <span class="p">{}</span> </pre></div> </div> <p>The main portion of the server program loops, calling <a class="reference internal" href="#module-select" title="select: Wait for I/O Efficiently"><tt class="xref py py-func docutils literal"><span class="pre">select()</span></tt></a> to block and wait for network activity.</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">while</span> <span class="n">inputs</span><span class="p">:</span> <span class="c"># Wait for at least one of the sockets to be ready for processing</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'</span><span class="se">\n</span><span class="s">waiting for the next event'</span> <span class="n">readable</span><span class="p">,</span> <span class="n">writable</span><span class="p">,</span> <span class="n">exceptional</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span><span class="p">,</span> <span class="n">inputs</span><span class="p">)</span> </pre></div> </div> <p><a class="reference internal" href="#module-select" title="select: Wait for I/O Efficiently"><tt class="xref py py-func docutils literal"><span class="pre">select()</span></tt></a> returns three new lists, containing subsets of the contents of the lists passed in. All of the sockets in the <tt class="xref py py-data docutils literal"><span class="pre">readable</span></tt> list have incoming data buffered and available to be read. All of the sockets in the <tt class="xref py py-data docutils literal"><span class="pre">writable</span></tt> list have free space in their buffer and can be written to. The sockets returned in <tt class="xref py py-data docutils literal"><span class="pre">exceptional</span></tt> have had an error (the actual definition of “exceptional condition” depends on the platform).</p> <p>The “readable” sockets represent three possible cases. If the socket is the main “server” socket, the one being used to listen for connections, then the “readable” condition means it is ready to accept another incoming connection. In addition to adding the new connection to the list of inputs to monitor, this section sets the client socket to not block.</p> <div class="highlight-python"><div class="highlight"><pre> <span class="c"># Handle inputs</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">readable</span><span class="p">:</span> <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="n">server</span><span class="p">:</span> <span class="c"># A "readable" server socket is ready to accept a connection</span> <span class="n">connection</span><span class="p">,</span> <span class="n">client_address</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">accept</span><span class="p">()</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'new connection from'</span><span class="p">,</span> <span class="n">client_address</span> <span class="n">connection</span><span class="o">.</span><span class="n">setblocking</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="n">inputs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">connection</span><span class="p">)</span> <span class="c"># Give the connection a queue for data we want to send</span> <span class="n">message_queues</span><span class="p">[</span><span class="n">connection</span><span class="p">]</span> <span class="o">=</span> <span class="n">Queue</span><span class="o">.</span><span class="n">Queue</span><span class="p">()</span> </pre></div> </div> <p>The next case is an established connection with a client that has sent data. The data is read with <tt class="xref py py-func docutils literal"><span class="pre">recv()</span></tt>, then placed on the queue so it can be sent through the socket and back to the client.</p> <div class="highlight-python"><pre> else: data = s.recv(1024) if data: # A readable client socket has data print >>sys.stderr, 'received "%s" from %s' % (data, s.getpeername()) message_queues[s].put(data) # Add output channel for response if s not in outputs: outputs.append(s) </pre> </div> <p>A readable socket <em>without</em> data available is from a client that has disconnected, and the stream is ready to be closed.</p> <div class="highlight-python"><pre> else: # Interpret empty result as closed connection print >>sys.stderr, 'closing', client_address, 'after reading no data' # Stop listening for input on the connection if s in outputs: outputs.remove(s) inputs.remove(s) s.close() </pre> </div> <p>There are fewer cases for the writable connections. If there is data in the queue for a connection, the next message is sent. Otherwise, the connection is removed from the list of output connections so that the next time through the loop <a class="reference internal" href="#module-select" title="select: Wait for I/O Efficiently"><tt class="xref py py-func docutils literal"><span class="pre">select()</span></tt></a> does not indicate that the socket is ready to send data.</p> <div class="highlight-python"><div class="highlight"><pre> <span class="c"># Handle outputs</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">writable</span><span class="p">:</span> <span class="k">try</span><span class="p">:</span> <span class="n">next_msg</span> <span class="o">=</span> <span class="n">message_queues</span><span class="p">[</span><span class="n">s</span><span class="p">]</span><span class="o">.</span><span class="n">get_nowait</span><span class="p">()</span> <span class="k">except</span> <span class="n">Queue</span><span class="o">.</span><span class="n">Empty</span><span class="p">:</span> <span class="c"># No messages waiting so stop checking for writability.</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'output queue for'</span><span class="p">,</span> <span class="n">s</span><span class="o">.</span><span class="n">getpeername</span><span class="p">(),</span> <span class="s">'is empty'</span> <span class="n">outputs</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'sending "</span><span class="si">%s</span><span class="s">" to </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">next_msg</span><span class="p">,</span> <span class="n">s</span><span class="o">.</span><span class="n">getpeername</span><span class="p">())</span> <span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">next_msg</span><span class="p">)</span> </pre></div> </div> <p>Finally, if there is an error with a socket, it is closed.</p> <div class="highlight-python"><div class="highlight"><pre> <span class="c"># Handle "exceptional conditions"</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">exceptional</span><span class="p">:</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'handling exceptional condition for'</span><span class="p">,</span> <span class="n">s</span><span class="o">.</span><span class="n">getpeername</span><span class="p">()</span> <span class="c"># Stop listening for input on the connection</span> <span class="n">inputs</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="k">if</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">outputs</span><span class="p">:</span> <span class="n">outputs</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="n">s</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> </pre></div> </div> <p>The example client program uses two sockets to demonstrate how the server with <a class="reference internal" href="#module-select" title="select: Wait for I/O Efficiently"><tt class="xref py py-func docutils literal"><span class="pre">select()</span></tt></a> manages multiple connections at the same time. The client starts by connecting each TCP/IP socket to the server.</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">socket</span> <span class="kn">import</span> <span class="nn">sys</span> <span class="n">messages</span> <span class="o">=</span> <span class="p">[</span> <span class="s">'This is the message. '</span><span class="p">,</span> <span class="s">'It will be sent '</span><span class="p">,</span> <span class="s">'in parts.'</span><span class="p">,</span> <span class="p">]</span> <span class="n">server_address</span> <span class="o">=</span> <span class="p">(</span><span class="s">'localhost'</span><span class="p">,</span> <span class="mi">10000</span><span class="p">)</span> <span class="c"># Create a TCP/IP socket</span> <span class="n">socks</span> <span class="o">=</span> <span class="p">[</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">),</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">),</span> <span class="p">]</span> <span class="c"># Connect the socket to the port where the server is listening</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'connecting to </span><span class="si">%s</span><span class="s"> port </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="n">server_address</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">socks</span><span class="p">:</span> <span class="n">s</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">server_address</span><span class="p">)</span> </pre></div> </div> <p>Then it sends one pieces of the message at a time via each socket, and reads all responses available after writing new data.</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">for</span> <span class="n">message</span> <span class="ow">in</span> <span class="n">messages</span><span class="p">:</span> <span class="c"># Send messages on both sockets</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">socks</span><span class="p">:</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'</span><span class="si">%s</span><span class="s">: sending "</span><span class="si">%s</span><span class="s">"'</span> <span class="o">%</span> <span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">getsockname</span><span class="p">(),</span> <span class="n">message</span><span class="p">)</span> <span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">message</span><span class="p">)</span> <span class="c"># Read responses on both sockets</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">socks</span><span class="p">:</span> <span class="n">data</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1024</span><span class="p">)</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'</span><span class="si">%s</span><span class="s">: received "</span><span class="si">%s</span><span class="s">"'</span> <span class="o">%</span> <span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">getsockname</span><span class="p">(),</span> <span class="n">data</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">data</span><span class="p">:</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'closing socket'</span><span class="p">,</span> <span class="n">s</span><span class="o">.</span><span class="n">getsockname</span><span class="p">()</span> <span class="n">s</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> </pre></div> </div> <p>Run the server in one window and the client in another. The output will look like this, with different port numbers.</p> <div class="highlight-python"><pre>$ python ./select_echo_server.py starting up on localhost port 10000 waiting for the next event new connection from ('127.0.0.1', 55821) waiting for the next event new connection from ('127.0.0.1', 55822) received "This is the message. " from ('127.0.0.1', 55821) waiting for the next event sending "This is the message. " to ('127.0.0.1', 55821) waiting for the next event output queue for ('127.0.0.1', 55821) is empty waiting for the next event received "This is the message. " from ('127.0.0.1', 55822) waiting for the next event sending "This is the message. " to ('127.0.0.1', 55822) waiting for the next event output queue for ('127.0.0.1', 55822) is empty waiting for the next event received "It will be sent " from ('127.0.0.1', 55821) received "It will be sent " from ('127.0.0.1', 55822) waiting for the next event sending "It will be sent " to ('127.0.0.1', 55821) sending "It will be sent " to ('127.0.0.1', 55822) waiting for the next event output queue for ('127.0.0.1', 55821) is empty output queue for ('127.0.0.1', 55822) is empty waiting for the next event received "in parts." from ('127.0.0.1', 55821) received "in parts." from ('127.0.0.1', 55822) waiting for the next event sending "in parts." to ('127.0.0.1', 55821) sending "in parts." to ('127.0.0.1', 55822) waiting for the next event output queue for ('127.0.0.1', 55821) is empty output queue for ('127.0.0.1', 55822) is empty waiting for the next event closing ('127.0.0.1', 55822) after reading no data closing ('127.0.0.1', 55822) after reading no data waiting for the next event</pre> </div> <p>The client output shows the data being sent and received using both sockets.</p> <div class="highlight-python"><pre>$ python ./select_echo_multiclient.py connecting to localhost port 10000 ('127.0.0.1', 55821): sending "This is the message. " ('127.0.0.1', 55822): sending "This is the message. " ('127.0.0.1', 55821): received "This is the message. " ('127.0.0.1', 55822): received "This is the message. " ('127.0.0.1', 55821): sending "It will be sent " ('127.0.0.1', 55822): sending "It will be sent " ('127.0.0.1', 55821): received "It will be sent " ('127.0.0.1', 55822): received "It will be sent " ('127.0.0.1', 55821): sending "in parts." ('127.0.0.1', 55822): sending "in parts." ('127.0.0.1', 55821): received "in parts." ('127.0.0.1', 55822): received "in parts."</pre> </div> <div class="section" id="timeouts"> <h3>Timeouts<a class="headerlink" href="#timeouts" title="Permalink to this headline">¶</a></h3> <p><a class="reference internal" href="#module-select" title="select: Wait for I/O Efficiently"><tt class="xref py py-func docutils literal"><span class="pre">select()</span></tt></a> also takes an optional fourth parameter which is the number of seconds to wait before breaking off monitoring if no channels have become active. Using a timeout value lets a main program call <a class="reference internal" href="#module-select" title="select: Wait for I/O Efficiently"><tt class="xref py py-func docutils literal"><span class="pre">select()</span></tt></a> as part of a larger processing loop, taking other actions in between checking for network input.</p> <p>When the timeout expires, <a class="reference internal" href="#module-select" title="select: Wait for I/O Efficiently"><tt class="xref py py-func docutils literal"><span class="pre">select()</span></tt></a> returns three empty lists. Updating the server example to use a timeout requires adding the extra argument to the <a class="reference internal" href="#module-select" title="select: Wait for I/O Efficiently"><tt class="xref py py-func docutils literal"><span class="pre">select()</span></tt></a> call and handling the empty lists after <a class="reference internal" href="#module-select" title="select: Wait for I/O Efficiently"><tt class="xref py py-func docutils literal"><span class="pre">select()</span></tt></a> returns.</p> <div class="highlight-python"><div class="highlight"><pre> <span class="c"># Wait for at least one of the sockets to be ready for processing</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'</span><span class="se">\n</span><span class="s">waiting for the next event'</span> <span class="n">timeout</span> <span class="o">=</span> <span class="mi">1</span> <span class="n">readable</span><span class="p">,</span> <span class="n">writable</span><span class="p">,</span> <span class="n">exceptional</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span><span class="p">,</span> <span class="n">inputs</span><span class="p">,</span> <span class="n">timeout</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">readable</span> <span class="ow">or</span> <span class="n">writable</span> <span class="ow">or</span> <span class="n">exceptional</span><span class="p">):</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">' timed out, do some other work here'</span> <span class="k">continue</span> </pre></div> </div> <p>This “slow” version of the client program pauses after sending each message, to simulate latency or other delay in transmission.</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">socket</span> <span class="kn">import</span> <span class="nn">sys</span> <span class="kn">import</span> <span class="nn">time</span> <span class="c"># Create a TCP/IP socket</span> <span class="n">sock</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">)</span> <span class="c"># Connect the socket to the port where the server is listening</span> <span class="n">server_address</span> <span class="o">=</span> <span class="p">(</span><span class="s">'localhost'</span><span class="p">,</span> <span class="mi">10000</span><span class="p">)</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'connecting to </span><span class="si">%s</span><span class="s"> port </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="n">server_address</span> <span class="n">sock</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">server_address</span><span class="p">)</span> <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="n">messages</span> <span class="o">=</span> <span class="p">[</span> <span class="s">'Part one of the message.'</span><span class="p">,</span> <span class="s">'Part two of the message.'</span><span class="p">,</span> <span class="p">]</span> <span class="n">amount_expected</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="s">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">messages</span><span class="p">))</span> <span class="k">try</span><span class="p">:</span> <span class="c"># Send data</span> <span class="k">for</span> <span class="n">message</span> <span class="ow">in</span> <span class="n">messages</span><span class="p">:</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'sending "</span><span class="si">%s</span><span class="s">"'</span> <span class="o">%</span> <span class="n">message</span> <span class="n">sock</span><span class="o">.</span><span class="n">sendall</span><span class="p">(</span><span class="n">message</span><span class="p">)</span> <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">1.5</span><span class="p">)</span> <span class="c"># Look for the response</span> <span class="n">amount_received</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">while</span> <span class="n">amount_received</span> <span class="o"><</span> <span class="n">amount_expected</span><span class="p">:</span> <span class="n">data</span> <span class="o">=</span> <span class="n">sock</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">16</span><span class="p">)</span> <span class="n">amount_received</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'received "</span><span class="si">%s</span><span class="s">"'</span> <span class="o">%</span> <span class="n">data</span> <span class="k">finally</span><span class="p">:</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'closing socket'</span> <span class="n">sock</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> </pre></div> </div> <p>Running the new server with the slow client produces:</p> <div class="highlight-python"><pre>$ python ./select_echo_server_timeout.py starting up on localhost port 10000 waiting for the next event timed out waiting for the next event timed out waiting for the next event new connection from ('127.0.0.1', 57776) waiting for the next event received "Part one of the message." from ('127.0.0.1', 57776) waiting for the next event sending "Part one of the message." to ('127.0.0.1', 57776) waiting for the next event output queue for ('127.0.0.1', 57776) is empty waiting for the next event timed out waiting for the next event received "Part two of the message." from ('127.0.0.1', 57776) waiting for the next event sending "Part two of the message." to ('127.0.0.1', 57776) waiting for the next event output queue for ('127.0.0.1', 57776) is empty waiting for the next event timed out waiting for the next event closing ('127.0.0.1', 57776) after reading no data waiting for the next event timed out waiting for the next event</pre> </div> <p>And the client output is:</p> <div class="highlight-python"><pre>$ python ./select_echo_slow_client.py connecting to localhost port 10000 sending "Part one of the message." sending "Part two of the message." received "Part one of the " received "message.Part two" received " of the message." closing socket</pre> </div> </div> </div> <div class="section" id="poll"> <h2>poll()<a class="headerlink" href="#poll" title="Permalink to this headline">¶</a></h2> <p>The <tt class="xref py py-func docutils literal"><span class="pre">poll()</span></tt> function provides similar features to <a class="reference internal" href="#module-select" title="select: Wait for I/O Efficiently"><tt class="xref py py-func docutils literal"><span class="pre">select()</span></tt></a>, but the underlying implementation is more efficient. The trade-off is that <tt class="xref py py-func docutils literal"><span class="pre">poll()</span></tt> is not supported under Windows, so programs using <tt class="xref py py-func docutils literal"><span class="pre">poll()</span></tt> are less portable.</p> <p>An echo server built on <tt class="xref py py-func docutils literal"><span class="pre">poll()</span></tt> starts with the same socket configuration code used in the other examples.</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">select</span> <span class="kn">import</span> <span class="nn">socket</span> <span class="kn">import</span> <span class="nn">sys</span> <span class="kn">import</span> <span class="nn">Queue</span> <span class="c"># Create a TCP/IP socket</span> <span class="n">server</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">)</span> <span class="n">server</span><span class="o">.</span><span class="n">setblocking</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="c"># Bind the socket to the port</span> <span class="n">server_address</span> <span class="o">=</span> <span class="p">(</span><span class="s">'localhost'</span><span class="p">,</span> <span class="mi">10000</span><span class="p">)</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'starting up on </span><span class="si">%s</span><span class="s"> port </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="n">server_address</span> <span class="n">server</span><span class="o">.</span><span class="n">bind</span><span class="p">(</span><span class="n">server_address</span><span class="p">)</span> <span class="c"># Listen for incoming connections</span> <span class="n">server</span><span class="o">.</span><span class="n">listen</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span> <span class="c"># Keep up with the queues of outgoing messages</span> <span class="n">message_queues</span> <span class="o">=</span> <span class="p">{}</span> </pre></div> </div> <p>The timeout value passed to <tt class="xref py py-func docutils literal"><span class="pre">poll()</span></tt> is represented in milliseconds, instead of seconds, so in order to pause for a full second the timeout must be set to <tt class="docutils literal"><span class="pre">1000</span></tt>.</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># Do not block forever (milliseconds)</span> <span class="n">TIMEOUT</span> <span class="o">=</span> <span class="mi">1000</span> </pre></div> </div> <p>Python implements <tt class="xref py py-func docutils literal"><span class="pre">poll()</span></tt> with a class that manages the registered data channels being monitored. Channels are added by calling <tt class="xref py py-func docutils literal"><span class="pre">register()</span></tt> with flags indicating which events are interesting for that channel. The full set of flags is:</p> <table border="1" class="docutils"> <colgroup> <col width="44%" /> <col width="56%" /> </colgroup> <thead valign="bottom"> <tr><th class="head">Event</th> <th class="head">Description</th> </tr> </thead> <tbody valign="top"> <tr><td><tt class="xref py py-const docutils literal"><span class="pre">POLLIN</span></tt></td> <td>Input ready</td> </tr> <tr><td><tt class="xref py py-const docutils literal"><span class="pre">POLLPRI</span></tt></td> <td>Priority input ready</td> </tr> <tr><td><tt class="xref py py-const docutils literal"><span class="pre">POLLOUT</span></tt></td> <td>Able to receive output</td> </tr> <tr><td><tt class="xref py py-const docutils literal"><span class="pre">POLLERR</span></tt></td> <td>Error</td> </tr> <tr><td><tt class="xref py py-const docutils literal"><span class="pre">POLLHUP</span></tt></td> <td>Channel closed</td> </tr> <tr><td><tt class="xref py py-const docutils literal"><span class="pre">POLLNVAL</span></tt></td> <td>Channel not open</td> </tr> </tbody> </table> <p>The echo server will be setting up some sockets just for reading, and others to be read from or written to. The appropriate combinations of flags are saved to the local variables <tt class="xref py py-data docutils literal"><span class="pre">READ_ONLY</span></tt> and <tt class="xref py py-data docutils literal"><span class="pre">READ_WRITE</span></tt>.</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># Commonly used flag setes</span> <span class="n">READ_ONLY</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">POLLIN</span> <span class="o">|</span> <span class="n">select</span><span class="o">.</span><span class="n">POLLPRI</span> <span class="o">|</span> <span class="n">select</span><span class="o">.</span><span class="n">POLLHUP</span> <span class="o">|</span> <span class="n">select</span><span class="o">.</span><span class="n">POLLERR</span> <span class="n">READ_WRITE</span> <span class="o">=</span> <span class="n">READ_ONLY</span> <span class="o">|</span> <span class="n">select</span><span class="o">.</span><span class="n">POLLOUT</span> </pre></div> </div> <p>The <tt class="xref py py-data docutils literal"><span class="pre">server</span></tt> socket is registered so that any incoming connections or data triggers an event.</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># Set up the poller</span> <span class="n">poller</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">poll</span><span class="p">()</span> <span class="n">poller</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">server</span><span class="p">,</span> <span class="n">READ_ONLY</span><span class="p">)</span> </pre></div> </div> <p>Since <tt class="xref py py-func docutils literal"><span class="pre">poll()</span></tt> returns a list of tuples containing the file descriptor for the socket and the event flag, a mapping from file descriptor numbers to objects is needed to retrieve the <a class="reference internal" href="../socket/index.html#module-socket" title="socket: Network communication"><tt class="xref py py-class docutils literal"><span class="pre">socket</span></tt></a> to read or write from it.</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># Map file descriptors to socket objects</span> <span class="n">fd_to_socket</span> <span class="o">=</span> <span class="p">{</span> <span class="n">server</span><span class="o">.</span><span class="n">fileno</span><span class="p">():</span> <span class="n">server</span><span class="p">,</span> <span class="p">}</span> </pre></div> </div> <p>The server’s loop calls <tt class="xref py py-func docutils literal"><span class="pre">poll()</span></tt>, then processes the “events” returned by looking up the socket and taking action based on the flag in the event.</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">while</span> <span class="bp">True</span><span class="p">:</span> <span class="c"># Wait for at least one of the sockets to be ready for processing</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'</span><span class="se">\n</span><span class="s">waiting for the next event'</span> <span class="n">events</span> <span class="o">=</span> <span class="n">poller</span><span class="o">.</span><span class="n">poll</span><span class="p">(</span><span class="n">TIMEOUT</span><span class="p">)</span> <span class="k">for</span> <span class="n">fd</span><span class="p">,</span> <span class="n">flag</span> <span class="ow">in</span> <span class="n">events</span><span class="p">:</span> <span class="c"># Retrieve the actual socket from its file descriptor</span> <span class="n">s</span> <span class="o">=</span> <span class="n">fd_to_socket</span><span class="p">[</span><span class="n">fd</span><span class="p">]</span> </pre></div> </div> <p>As with <a class="reference internal" href="#module-select" title="select: Wait for I/O Efficiently"><tt class="xref py py-func docutils literal"><span class="pre">select()</span></tt></a>, when the main server socket is “readable,” that really means there is a pending connection from a client. The new connection is registered with the <tt class="xref py py-data docutils literal"><span class="pre">READ_ONLY</span></tt> flags to watch for new data to come through it.</p> <div class="highlight-python"><div class="highlight"><pre> <span class="c"># Handle inputs</span> <span class="k">if</span> <span class="n">flag</span> <span class="o">&</span> <span class="p">(</span><span class="n">select</span><span class="o">.</span><span class="n">POLLIN</span> <span class="o">|</span> <span class="n">select</span><span class="o">.</span><span class="n">POLLPRI</span><span class="p">):</span> <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="n">server</span><span class="p">:</span> <span class="c"># A "readable" server socket is ready to accept a connection</span> <span class="n">connection</span><span class="p">,</span> <span class="n">client_address</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">accept</span><span class="p">()</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'new connection from'</span><span class="p">,</span> <span class="n">client_address</span> <span class="n">connection</span><span class="o">.</span><span class="n">setblocking</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="n">fd_to_socket</span><span class="p">[</span> <span class="n">connection</span><span class="o">.</span><span class="n">fileno</span><span class="p">()</span> <span class="p">]</span> <span class="o">=</span> <span class="n">connection</span> <span class="n">poller</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">connection</span><span class="p">,</span> <span class="n">READ_ONLY</span><span class="p">)</span> <span class="c"># Give the connection a queue for data we want to send</span> <span class="n">message_queues</span><span class="p">[</span><span class="n">connection</span><span class="p">]</span> <span class="o">=</span> <span class="n">Queue</span><span class="o">.</span><span class="n">Queue</span><span class="p">()</span> </pre></div> </div> <p>Sockets other than the server are existing clients, and <tt class="xref py py-func docutils literal"><span class="pre">recv()</span></tt> is used to access the data waiting to be read.</p> <div class="highlight-python"><pre> else: data = s.recv(1024) </pre> </div> <p>If <tt class="xref py py-func docutils literal"><span class="pre">recv()</span></tt> returns any data, it is placed into the outgoing queue for the socket and the flags for that socket are changed using <tt class="xref py py-func docutils literal"><span class="pre">modify()</span></tt> so <tt class="xref py py-func docutils literal"><span class="pre">poll()</span></tt> will watch for the socket to be ready to receive data.</p> <div class="highlight-python"><div class="highlight"><pre> <span class="k">if</span> <span class="n">data</span><span class="p">:</span> <span class="c"># A readable client socket has data</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'received "</span><span class="si">%s</span><span class="s">" from </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">s</span><span class="o">.</span><span class="n">getpeername</span><span class="p">())</span> <span class="n">message_queues</span><span class="p">[</span><span class="n">s</span><span class="p">]</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="c"># Add output channel for response</span> <span class="n">poller</span><span class="o">.</span><span class="n">modify</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">READ_WRITE</span><span class="p">)</span> </pre></div> </div> <p>An empty string returned by <tt class="xref py py-func docutils literal"><span class="pre">recv()</span></tt> means the client disconnected, so <tt class="xref py py-func docutils literal"><span class="pre">unregister()</span></tt> is used to tell the <tt class="xref py py-class docutils literal"><span class="pre">poll</span></tt> object to ignore the socket.</p> <div class="highlight-python"><pre> else: # Interpret empty result as closed connection print >>sys.stderr, 'closing', client_address, 'after reading no data' # Stop listening for input on the connection poller.unregister(s) s.close() </pre> </div> <p>The <tt class="xref py py-const docutils literal"><span class="pre">POLLHUP</span></tt> flag indicates a client that “hung up” the connection without closing it cleanly. The server stops polling clients that disappear.</p> <div class="highlight-python"><pre> elif flag & select.POLLHUP: # Client hung up print >>sys.stderr, 'closing', client_address, 'after receiving HUP' # Stop listening for input on the connection poller.unregister(s) s.close() </pre> </div> <p>The handling for writable sockets looks like the version used in the example for <a class="reference internal" href="#module-select" title="select: Wait for I/O Efficiently"><tt class="xref py py-func docutils literal"><span class="pre">select()</span></tt></a>, except that <tt class="xref py py-func docutils literal"><span class="pre">modify()</span></tt> is used to change the flags for the socket in the poller, instead of removing it from the output list.</p> <div class="highlight-python"><pre> elif flag & select.POLLOUT: # Socket is ready to send data, if there is any to send. try: next_msg = message_queues[s].get_nowait() except Queue.Empty: # No messages waiting so stop checking for writability. print >>sys.stderr, 'output queue for', s.getpeername(), 'is empty' poller.modify(s, READ_ONLY) else: print >>sys.stderr, 'sending "%s" to %s' % (next_msg, s.getpeername()) s.send(next_msg) </pre> </div> <p>And finally, any events with <tt class="xref py py-const docutils literal"><span class="pre">POLLERR</span></tt> cause the server to close the socket.</p> <div class="highlight-python"><pre> elif flag & select.POLLERR: print >>sys.stderr, 'handling exceptional condition for', s.getpeername() # Stop listening for input on the connection poller.unregister(s) s.close() </pre> </div> <p>When the poll-based server is run together with <tt class="docutils literal"><span class="pre">select_echo_multiclient.py</span></tt> (the client program that uses multiple sockets), the output is:</p> <div class="highlight-python"><pre>$ python ./select_poll_echo_server.py starting up on localhost port 10000 waiting for the next event waiting for the next event waiting for the next event new connection from ('127.0.0.1', 58447) waiting for the next event new connection from ('127.0.0.1', 58448) received "This is the message. " from ('127.0.0.1', 58447) waiting for the next event sending "This is the message. " to ('127.0.0.1', 58447) received "This is the message. " from ('127.0.0.1', 58448) waiting for the next event output queue for ('127.0.0.1', 58447) is empty sending "This is the message. " to ('127.0.0.1', 58448) waiting for the next event output queue for ('127.0.0.1', 58448) is empty waiting for the next event received "It will be sent " from ('127.0.0.1', 58447) received "It will be sent " from ('127.0.0.1', 58448) waiting for the next event sending "It will be sent " to ('127.0.0.1', 58447) sending "It will be sent " to ('127.0.0.1', 58448) waiting for the next event output queue for ('127.0.0.1', 58447) is empty output queue for ('127.0.0.1', 58448) is empty waiting for the next event received "in parts." from ('127.0.0.1', 58447) received "in parts." from ('127.0.0.1', 58448) waiting for the next event sending "in parts." to ('127.0.0.1', 58447) sending "in parts." to ('127.0.0.1', 58448) waiting for the next event output queue for ('127.0.0.1', 58447) is empty output queue for ('127.0.0.1', 58448) is empty waiting for the next event closing ('127.0.0.1', 58448) after reading no data closing ('127.0.0.1', 58448) after reading no data waiting for the next event</pre> </div> </div> <div class="section" id="platform-specific-options"> <h2>Platform-specific Options<a class="headerlink" href="#platform-specific-options" title="Permalink to this headline">¶</a></h2> <p>Less portable options provided by <a class="reference internal" href="#module-select" title="select: Wait for I/O Efficiently"><tt class="xref py py-mod docutils literal"><span class="pre">select</span></tt></a> are <tt class="xref py py-class docutils literal"><span class="pre">epoll</span></tt>, the <em>edge polling</em> API supported by Linux; <tt class="xref py py-class docutils literal"><span class="pre">kqueue</span></tt>, which uses BSD’s <em>kernel queue</em>; and <tt class="xref py py-class docutils literal"><span class="pre">kevent</span></tt>, BSD’s <em>kernel event</em> interface. Refer to the operating system library documentation for more detail about how they work.</p> <div class="admonition-see-also admonition seealso"> <p class="first admonition-title">See also</p> <dl class="last docutils"> <dt><a class="reference external" href="http://docs.python.org/library/select.html">select</a></dt> <dd>The standard library documentation for this module.</dd> <dt><a class="reference external" href="http://docs.python.org/howto/sockets.html">Socket Programming HOWOTO</a></dt> <dd>An instructional guide by Gordon McMillan, included in the standard library documentation.</dd> <dt><a class="reference internal" href="../socket/index.html#module-socket" title="socket: Network communication"><tt class="xref py py-mod docutils literal"><span class="pre">socket</span></tt></a></dt> <dd>Low-level network communication.</dd> <dt><a class="reference internal" href="../SocketServer/index.html#module-SocketServer" title="SocketServer: Creating network servers."><tt class="xref py py-mod docutils literal"><span class="pre">SocketServer</span></tt></a></dt> <dd>Framework for creating network server applications.</dd> <dt><a class="reference internal" href="../asyncore/index.html#module-asyncore" title="asyncore: Asynchronous I/O handler"><tt class="xref py py-mod docutils literal"><span class="pre">asyncore</span></tt></a> and <a class="reference internal" href="../asynchat/index.html#module-asynchat" title="asynchat: Asynchronous protocol handler"><tt class="xref py py-mod docutils literal"><span class="pre">asynchat</span></tt></a></dt> <dd>Asynchronous I/O framework.</dd> <dt><em>Unix Network Programming, Volume 1: The Sockets Networking API, 3/E</em></dt> <dd>By W. Richard Stevens, Bill Fenner, and Andrew M. Rudoff. Published by Addison-Wesley Professional, 2004. ISBN-10: 0131411551</dd> </dl> </div> </div> </div> </div> </div> </div> <div class="clearer"></div> </div> <div class="related"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="../genindex.html" title="General Index" >index</a></li> <li class="right" > <a href="../py-modindex.html" title="Python Module Index" >modules</a> |</li> <li class="right" > <a href="../SocketServer/index.html" title="SocketServer – Creating network servers." >next</a> |</li> <li class="right" > <a href="../socket/nonblocking.html" title="Non-blocking Communication and Timeouts" >previous</a> |</li> <li><a href="../contents.html">PyMOTW</a> »</li> <li><a href="../internet_protocols.html" >Internet Protocols and Support</a> »</li> </ul> </div> <div class="footer"> © Copyright Doug Hellmann. Last updated on Oct 24, 2010. Created using <a href="http://sphinx.pocoo.org/">Sphinx</a>. <br/><a href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/" rel="license"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/88x31.png"/></a> </div> </body> </html>