[code.view]

[top] / python / PyMOTW / docs / select / index.html


<!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 &mdash; 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> &raquo;</li>
          <li><a href="../internet_protocols.html" accesskey="U">Internet Protocols and Support</a> &raquo;</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 &#8211; 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 &#8211; 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 &#8211; 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&#8217;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&#8217;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">&#39;localhost&#39;</span><span class="p">,</span> <span class="mi">10000</span><span class="p">)</span>
<span class="k">print</span> <span class="o">&gt;&gt;</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&#39;starting up on </span><span class="si">%s</span><span class="s"> port </span><span class="si">%s</span><span class="s">&#39;</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">&gt;&gt;</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&#39;</span><span class="se">\n</span><span class="s">waiting for the next event&#39;</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
&#8220;exceptional condition&#8221; depends on the platform).</p>
<p>The &#8220;readable&#8221; sockets represent three possible cases.  If the socket
is the main &#8220;server&#8221; socket, the one being used to listen for
connections, then the &#8220;readable&#8221; 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 &quot;readable&quot; 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">&gt;&gt;</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&#39;new connection from&#39;</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 &gt;&gt;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 &gt;&gt;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">&gt;&gt;</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&#39;output queue for&#39;</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">&#39;is empty&#39;</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">&gt;&gt;</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&#39;sending &quot;</span><span class="si">%s</span><span class="s">&quot; to </span><span class="si">%s</span><span class="s">&#39;</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 &quot;exceptional conditions&quot;</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">&gt;&gt;</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&#39;handling exceptional condition for&#39;</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">&#39;This is the message. &#39;</span><span class="p">,</span>
             <span class="s">&#39;It will be sent &#39;</span><span class="p">,</span>
             <span class="s">&#39;in parts.&#39;</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">&#39;localhost&#39;</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">&gt;&gt;</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&#39;connecting to </span><span class="si">%s</span><span class="s"> port </span><span class="si">%s</span><span class="s">&#39;</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">&gt;&gt;</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&#39;</span><span class="si">%s</span><span class="s">: sending &quot;</span><span class="si">%s</span><span class="s">&quot;&#39;</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">&gt;&gt;</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&#39;</span><span class="si">%s</span><span class="s">: received &quot;</span><span class="si">%s</span><span class="s">&quot;&#39;</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">&gt;&gt;</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&#39;closing socket&#39;</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">&gt;&gt;</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&#39;</span><span class="se">\n</span><span class="s">waiting for the next event&#39;</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">&gt;&gt;</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&#39;  timed out, do some other work here&#39;</span>
        <span class="k">continue</span>
</pre></div>
</div>
<p>This &#8220;slow&#8221; 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">&#39;localhost&#39;</span><span class="p">,</span> <span class="mi">10000</span><span class="p">)</span>
<span class="k">print</span> <span class="o">&gt;&gt;</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&#39;connecting to </span><span class="si">%s</span><span class="s"> port </span><span class="si">%s</span><span class="s">&#39;</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">&#39;Part one of the message.&#39;</span><span class="p">,</span>
             <span class="s">&#39;Part two of the message.&#39;</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">&#39;&#39;</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">&gt;&gt;</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&#39;sending &quot;</span><span class="si">%s</span><span class="s">&quot;&#39;</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">&lt;</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">&gt;&gt;</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&#39;received &quot;</span><span class="si">%s</span><span class="s">&quot;&#39;</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">&gt;&gt;</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&#39;closing socket&#39;</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">&#39;localhost&#39;</span><span class="p">,</span> <span class="mi">10000</span><span class="p">)</span>
<span class="k">print</span> <span class="o">&gt;&gt;</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&#39;starting up on </span><span class="si">%s</span><span class="s"> port </span><span class="si">%s</span><span class="s">&#39;</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&#8217;s loop calls <tt class="xref py py-func docutils literal"><span class="pre">poll()</span></tt>, then processes the &#8220;events&#8221;
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">&gt;&gt;</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&#39;</span><span class="se">\n</span><span class="s">waiting for the next event&#39;</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 &#8220;readable,&#8221;
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">&amp;</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 &quot;readable&quot; 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">&gt;&gt;</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&#39;new connection from&#39;</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">&gt;&gt;</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">&#39;received &quot;</span><span class="si">%s</span><span class="s">&quot; from </span><span class="si">%s</span><span class="s">&#39;</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 &gt;&gt;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 &#8220;hung up&#8221; the
connection without closing it cleanly.  The server stops polling
clients that disappear.</p>
<div class="highlight-python"><pre>        elif flag &amp; select.POLLHUP:
            # Client hung up
            print &gt;&gt;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 &amp; 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 &gt;&gt;sys.stderr, 'output queue for', s.getpeername(), 'is empty'
                poller.modify(s, READ_ONLY)
            else:
                print &gt;&gt;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 &amp; select.POLLERR:
            print &gt;&gt;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&#8217;s <em>kernel queue</em>; and <tt class="xref py py-class docutils literal"><span class="pre">kevent</span></tt>, BSD&#8217;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> &raquo;</li>
          <li><a href="../internet_protocols.html" >Internet Protocols and Support</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
      &copy; 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>

[top] / python / PyMOTW / docs / select / index.html

contact | logmethods.com