838 lines
82 KiB
HTML
838 lines
82 KiB
HTML
|
|
|||
|
<!DOCTYPE html>
|
|||
|
|
|||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|||
|
<head>
|
|||
|
<meta charset="utf-8" />
|
|||
|
<title>socketserver — A framework for network servers — Python 3.7.4 documentation</title>
|
|||
|
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
|
|||
|
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
|||
|
|
|||
|
<script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></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>
|
|||
|
<script type="text/javascript" src="../_static/language_data.js"></script>
|
|||
|
|
|||
|
<script type="text/javascript" src="../_static/sidebar.js"></script>
|
|||
|
|
|||
|
<link rel="search" type="application/opensearchdescription+xml"
|
|||
|
title="Search within Python 3.7.4 documentation"
|
|||
|
href="../_static/opensearch.xml"/>
|
|||
|
<link rel="author" title="About these documents" href="../about.html" />
|
|||
|
<link rel="index" title="Index" href="../genindex.html" />
|
|||
|
<link rel="search" title="Search" href="../search.html" />
|
|||
|
<link rel="copyright" title="Copyright" href="../copyright.html" />
|
|||
|
<link rel="next" title="http.server — HTTP servers" href="http.server.html" />
|
|||
|
<link rel="prev" title="uuid — UUID objects according to RFC 4122" href="uuid.html" />
|
|||
|
<link rel="shortcut icon" type="image/png" href="../_static/py.png" />
|
|||
|
<link rel="canonical" href="https://docs.python.org/3/library/socketserver.html" />
|
|||
|
|
|||
|
<script type="text/javascript" src="../_static/copybutton.js"></script>
|
|||
|
<script type="text/javascript" src="../_static/switchers.js"></script>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<style>
|
|||
|
@media only screen {
|
|||
|
table.full-width-table {
|
|||
|
width: 100%;
|
|||
|
}
|
|||
|
}
|
|||
|
</style>
|
|||
|
|
|||
|
|
|||
|
</head><body>
|
|||
|
|
|||
|
<div class="related" role="navigation" aria-label="related navigation">
|
|||
|
<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="http.server.html" title="http.server — HTTP servers"
|
|||
|
accesskey="N">next</a> |</li>
|
|||
|
<li class="right" >
|
|||
|
<a href="uuid.html" title="uuid — UUID objects according to RFC 4122"
|
|||
|
accesskey="P">previous</a> |</li>
|
|||
|
<li><img src="../_static/py.png" alt=""
|
|||
|
style="vertical-align: middle; margin-top: -1px"/></li>
|
|||
|
<li><a href="https://www.python.org/">Python</a> »</li>
|
|||
|
<li>
|
|||
|
<span class="language_switcher_placeholder">en</span>
|
|||
|
<span class="version_switcher_placeholder">3.7.4</span>
|
|||
|
<a href="../index.html">Documentation </a> »
|
|||
|
</li>
|
|||
|
|
|||
|
<li class="nav-item nav-item-1"><a href="index.html" >The Python Standard Library</a> »</li>
|
|||
|
<li class="nav-item nav-item-2"><a href="internet.html" accesskey="U">Internet Protocols and Support</a> »</li>
|
|||
|
<li class="right">
|
|||
|
|
|||
|
|
|||
|
<div class="inline-search" style="display: none" role="search">
|
|||
|
<form class="inline-search" action="../search.html" method="get">
|
|||
|
<input placeholder="Quick search" type="text" name="q" />
|
|||
|
<input type="submit" value="Go" />
|
|||
|
<input type="hidden" name="check_keywords" value="yes" />
|
|||
|
<input type="hidden" name="area" value="default" />
|
|||
|
</form>
|
|||
|
</div>
|
|||
|
<script type="text/javascript">$('.inline-search').show(0);</script>
|
|||
|
|
|
|||
|
</li>
|
|||
|
|
|||
|
</ul>
|
|||
|
</div>
|
|||
|
|
|||
|
<div class="document">
|
|||
|
<div class="documentwrapper">
|
|||
|
<div class="bodywrapper">
|
|||
|
<div class="body" role="main">
|
|||
|
|
|||
|
<div class="section" id="module-socketserver">
|
|||
|
<span id="socketserver-a-framework-for-network-servers"></span><h1><a class="reference internal" href="#module-socketserver" title="socketserver: A framework for network servers."><code class="xref py py-mod docutils literal notranslate"><span class="pre">socketserver</span></code></a> — A framework for network servers<a class="headerlink" href="#module-socketserver" title="Permalink to this headline">¶</a></h1>
|
|||
|
<p><strong>Source code:</strong> <a class="reference external" href="https://github.com/python/cpython/tree/3.7/Lib/socketserver.py">Lib/socketserver.py</a></p>
|
|||
|
<hr class="docutils" />
|
|||
|
<p>The <a class="reference internal" href="#module-socketserver" title="socketserver: A framework for network servers."><code class="xref py py-mod docutils literal notranslate"><span class="pre">socketserver</span></code></a> module simplifies the task of writing network servers.</p>
|
|||
|
<p>There are four basic concrete server classes:</p>
|
|||
|
<dl class="class">
|
|||
|
<dt id="socketserver.TCPServer">
|
|||
|
<em class="property">class </em><code class="descclassname">socketserver.</code><code class="descname">TCPServer</code><span class="sig-paren">(</span><em>server_address</em>, <em>RequestHandlerClass</em>, <em>bind_and_activate=True</em><span class="sig-paren">)</span><a class="headerlink" href="#socketserver.TCPServer" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>This uses the Internet TCP protocol, which provides for
|
|||
|
continuous streams of data between the client and server.
|
|||
|
If <em>bind_and_activate</em> is true, the constructor automatically attempts to
|
|||
|
invoke <a class="reference internal" href="#socketserver.BaseServer.server_bind" title="socketserver.BaseServer.server_bind"><code class="xref py py-meth docutils literal notranslate"><span class="pre">server_bind()</span></code></a> and
|
|||
|
<a class="reference internal" href="#socketserver.BaseServer.server_activate" title="socketserver.BaseServer.server_activate"><code class="xref py py-meth docutils literal notranslate"><span class="pre">server_activate()</span></code></a>. The other parameters are passed to
|
|||
|
the <a class="reference internal" href="#socketserver.BaseServer" title="socketserver.BaseServer"><code class="xref py py-class docutils literal notranslate"><span class="pre">BaseServer</span></code></a> base class.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="class">
|
|||
|
<dt id="socketserver.UDPServer">
|
|||
|
<em class="property">class </em><code class="descclassname">socketserver.</code><code class="descname">UDPServer</code><span class="sig-paren">(</span><em>server_address</em>, <em>RequestHandlerClass</em>, <em>bind_and_activate=True</em><span class="sig-paren">)</span><a class="headerlink" href="#socketserver.UDPServer" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>This uses datagrams, which are discrete packets of information that may
|
|||
|
arrive out of order or be lost while in transit. The parameters are
|
|||
|
the same as for <a class="reference internal" href="#socketserver.TCPServer" title="socketserver.TCPServer"><code class="xref py py-class docutils literal notranslate"><span class="pre">TCPServer</span></code></a>.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="class">
|
|||
|
<dt id="socketserver.UnixStreamServer">
|
|||
|
<em class="property">class </em><code class="descclassname">socketserver.</code><code class="descname">UnixStreamServer</code><span class="sig-paren">(</span><em>server_address</em>, <em>RequestHandlerClass</em>, <em>bind_and_activate=True</em><span class="sig-paren">)</span><a class="headerlink" href="#socketserver.UnixStreamServer" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dt id="socketserver.UnixDatagramServer">
|
|||
|
<em class="property">class </em><code class="descclassname">socketserver.</code><code class="descname">UnixDatagramServer</code><span class="sig-paren">(</span><em>server_address</em>, <em>RequestHandlerClass</em>, <em>bind_and_activate=True</em><span class="sig-paren">)</span><a class="headerlink" href="#socketserver.UnixDatagramServer" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>These more infrequently used classes are similar to the TCP and
|
|||
|
UDP classes, but use Unix domain sockets; they’re not available on
|
|||
|
non-Unix platforms. The parameters are the same as for
|
|||
|
<a class="reference internal" href="#socketserver.TCPServer" title="socketserver.TCPServer"><code class="xref py py-class docutils literal notranslate"><span class="pre">TCPServer</span></code></a>.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<p>These four classes process requests <em class="dfn">synchronously</em>; each request must be
|
|||
|
completed before the next request can be started. This isn’t suitable if each
|
|||
|
request takes a long time to complete, because it requires a lot of computation,
|
|||
|
or because it returns a lot of data which the client is slow to process. The
|
|||
|
solution is to create a separate process or thread to handle each request; the
|
|||
|
<a class="reference internal" href="#socketserver.ForkingMixIn" title="socketserver.ForkingMixIn"><code class="xref py py-class docutils literal notranslate"><span class="pre">ForkingMixIn</span></code></a> and <a class="reference internal" href="#socketserver.ThreadingMixIn" title="socketserver.ThreadingMixIn"><code class="xref py py-class docutils literal notranslate"><span class="pre">ThreadingMixIn</span></code></a> mix-in classes can be used to
|
|||
|
support asynchronous behaviour.</p>
|
|||
|
<p>Creating a server requires several steps. First, you must create a request
|
|||
|
handler class by subclassing the <a class="reference internal" href="#socketserver.BaseRequestHandler" title="socketserver.BaseRequestHandler"><code class="xref py py-class docutils literal notranslate"><span class="pre">BaseRequestHandler</span></code></a> class and
|
|||
|
overriding its <a class="reference internal" href="#socketserver.BaseRequestHandler.handle" title="socketserver.BaseRequestHandler.handle"><code class="xref py py-meth docutils literal notranslate"><span class="pre">handle()</span></code></a> method;
|
|||
|
this method will process incoming
|
|||
|
requests. Second, you must instantiate one of the server classes, passing it
|
|||
|
the server’s address and the request handler class. It is recommended to use
|
|||
|
the server in a <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> statement. Then call the
|
|||
|
<a class="reference internal" href="#socketserver.BaseServer.handle_request" title="socketserver.BaseServer.handle_request"><code class="xref py py-meth docutils literal notranslate"><span class="pre">handle_request()</span></code></a> or
|
|||
|
<a class="reference internal" href="#socketserver.BaseServer.serve_forever" title="socketserver.BaseServer.serve_forever"><code class="xref py py-meth docutils literal notranslate"><span class="pre">serve_forever()</span></code></a> method of the server object to
|
|||
|
process one or many requests. Finally, call <a class="reference internal" href="#socketserver.BaseServer.server_close" title="socketserver.BaseServer.server_close"><code class="xref py py-meth docutils literal notranslate"><span class="pre">server_close()</span></code></a>
|
|||
|
to close the socket (unless you used a <code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code> statement).</p>
|
|||
|
<p>When inheriting from <a class="reference internal" href="#socketserver.ThreadingMixIn" title="socketserver.ThreadingMixIn"><code class="xref py py-class docutils literal notranslate"><span class="pre">ThreadingMixIn</span></code></a> for threaded connection behavior,
|
|||
|
you should explicitly declare how you want your threads to behave on an abrupt
|
|||
|
shutdown. The <a class="reference internal" href="#socketserver.ThreadingMixIn" title="socketserver.ThreadingMixIn"><code class="xref py py-class docutils literal notranslate"><span class="pre">ThreadingMixIn</span></code></a> class defines an attribute
|
|||
|
<em>daemon_threads</em>, which indicates whether or not the server should wait for
|
|||
|
thread termination. You should set the flag explicitly if you would like
|
|||
|
threads to behave autonomously; the default is <a class="reference internal" href="constants.html#False" title="False"><code class="xref py py-const docutils literal notranslate"><span class="pre">False</span></code></a>, meaning that
|
|||
|
Python will not exit until all threads created by <a class="reference internal" href="#socketserver.ThreadingMixIn" title="socketserver.ThreadingMixIn"><code class="xref py py-class docutils literal notranslate"><span class="pre">ThreadingMixIn</span></code></a> have
|
|||
|
exited.</p>
|
|||
|
<p>Server classes have the same external methods and attributes, no matter what
|
|||
|
network protocol they use.</p>
|
|||
|
<div class="section" id="server-creation-notes">
|
|||
|
<h2>Server Creation Notes<a class="headerlink" href="#server-creation-notes" title="Permalink to this headline">¶</a></h2>
|
|||
|
<p>There are five classes in an inheritance diagram, four of which represent
|
|||
|
synchronous servers of four types:</p>
|
|||
|
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="o">+------------+</span>
|
|||
|
<span class="o">|</span> <span class="n">BaseServer</span> <span class="o">|</span>
|
|||
|
<span class="o">+------------+</span>
|
|||
|
<span class="o">|</span>
|
|||
|
<span class="n">v</span>
|
|||
|
<span class="o">+-----------+</span> <span class="o">+------------------+</span>
|
|||
|
<span class="o">|</span> <span class="n">TCPServer</span> <span class="o">|------->|</span> <span class="n">UnixStreamServer</span> <span class="o">|</span>
|
|||
|
<span class="o">+-----------+</span> <span class="o">+------------------+</span>
|
|||
|
<span class="o">|</span>
|
|||
|
<span class="n">v</span>
|
|||
|
<span class="o">+-----------+</span> <span class="o">+--------------------+</span>
|
|||
|
<span class="o">|</span> <span class="n">UDPServer</span> <span class="o">|------->|</span> <span class="n">UnixDatagramServer</span> <span class="o">|</span>
|
|||
|
<span class="o">+-----------+</span> <span class="o">+--------------------+</span>
|
|||
|
</pre></div>
|
|||
|
</div>
|
|||
|
<p>Note that <a class="reference internal" href="#socketserver.UnixDatagramServer" title="socketserver.UnixDatagramServer"><code class="xref py py-class docutils literal notranslate"><span class="pre">UnixDatagramServer</span></code></a> derives from <a class="reference internal" href="#socketserver.UDPServer" title="socketserver.UDPServer"><code class="xref py py-class docutils literal notranslate"><span class="pre">UDPServer</span></code></a>, not from
|
|||
|
<a class="reference internal" href="#socketserver.UnixStreamServer" title="socketserver.UnixStreamServer"><code class="xref py py-class docutils literal notranslate"><span class="pre">UnixStreamServer</span></code></a> — the only difference between an IP and a Unix
|
|||
|
stream server is the address family, which is simply repeated in both Unix
|
|||
|
server classes.</p>
|
|||
|
<dl class="class">
|
|||
|
<dt id="socketserver.ForkingMixIn">
|
|||
|
<em class="property">class </em><code class="descclassname">socketserver.</code><code class="descname">ForkingMixIn</code><a class="headerlink" href="#socketserver.ForkingMixIn" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dt id="socketserver.ThreadingMixIn">
|
|||
|
<em class="property">class </em><code class="descclassname">socketserver.</code><code class="descname">ThreadingMixIn</code><a class="headerlink" href="#socketserver.ThreadingMixIn" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>Forking and threading versions of each type of server can be created
|
|||
|
using these mix-in classes. For instance, <a class="reference internal" href="#socketserver.ThreadingUDPServer" title="socketserver.ThreadingUDPServer"><code class="xref py py-class docutils literal notranslate"><span class="pre">ThreadingUDPServer</span></code></a>
|
|||
|
is created as follows:</p>
|
|||
|
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">ThreadingUDPServer</span><span class="p">(</span><span class="n">ThreadingMixIn</span><span class="p">,</span> <span class="n">UDPServer</span><span class="p">):</span>
|
|||
|
<span class="k">pass</span>
|
|||
|
</pre></div>
|
|||
|
</div>
|
|||
|
<p>The mix-in class comes first, since it overrides a method defined in
|
|||
|
<a class="reference internal" href="#socketserver.UDPServer" title="socketserver.UDPServer"><code class="xref py py-class docutils literal notranslate"><span class="pre">UDPServer</span></code></a>. Setting the various attributes also changes the
|
|||
|
behavior of the underlying server mechanism.</p>
|
|||
|
<p><a class="reference internal" href="#socketserver.ForkingMixIn" title="socketserver.ForkingMixIn"><code class="xref py py-class docutils literal notranslate"><span class="pre">ForkingMixIn</span></code></a> and the Forking classes mentioned below are
|
|||
|
only available on POSIX platforms that support <a class="reference internal" href="os.html#os.fork" title="os.fork"><code class="xref py py-func docutils literal notranslate"><span class="pre">fork()</span></code></a>.</p>
|
|||
|
<p><code class="xref py py-meth docutils literal notranslate"><span class="pre">socketserver.ForkingMixIn.server_close()</span></code> waits until all child
|
|||
|
processes complete, except if
|
|||
|
<code class="xref py py-attr docutils literal notranslate"><span class="pre">socketserver.ForkingMixIn.block_on_close</span></code> attribute is false.</p>
|
|||
|
<p><code class="xref py py-meth docutils literal notranslate"><span class="pre">socketserver.ThreadingMixIn.server_close()</span></code> waits until all non-daemon
|
|||
|
threads complete, except if
|
|||
|
<code class="xref py py-attr docutils literal notranslate"><span class="pre">socketserver.ThreadingMixIn.block_on_close</span></code> attribute is false. Use
|
|||
|
daemonic threads by setting
|
|||
|
<code class="xref py py-data docutils literal notranslate"><span class="pre">ThreadingMixIn.daemon_threads</span></code> to <code class="docutils literal notranslate"><span class="pre">True</span></code> to not wait until threads
|
|||
|
complete.</p>
|
|||
|
<div class="versionchanged">
|
|||
|
<p><span class="versionmodified changed">Changed in version 3.7: </span><code class="xref py py-meth docutils literal notranslate"><span class="pre">socketserver.ForkingMixIn.server_close()</span></code> and
|
|||
|
<code class="xref py py-meth docutils literal notranslate"><span class="pre">socketserver.ThreadingMixIn.server_close()</span></code> now waits until all
|
|||
|
child processes and non-daemonic threads complete.
|
|||
|
Add a new <code class="xref py py-attr docutils literal notranslate"><span class="pre">socketserver.ForkingMixIn.block_on_close</span></code> class
|
|||
|
attribute to opt-in for the pre-3.7 behaviour.</p>
|
|||
|
</div>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="class">
|
|||
|
<dt id="socketserver.ForkingTCPServer">
|
|||
|
<em class="property">class </em><code class="descclassname">socketserver.</code><code class="descname">ForkingTCPServer</code><a class="headerlink" href="#socketserver.ForkingTCPServer" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dt id="socketserver.ForkingUDPServer">
|
|||
|
<em class="property">class </em><code class="descclassname">socketserver.</code><code class="descname">ForkingUDPServer</code><a class="headerlink" href="#socketserver.ForkingUDPServer" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dt id="socketserver.ThreadingTCPServer">
|
|||
|
<em class="property">class </em><code class="descclassname">socketserver.</code><code class="descname">ThreadingTCPServer</code><a class="headerlink" href="#socketserver.ThreadingTCPServer" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dt id="socketserver.ThreadingUDPServer">
|
|||
|
<em class="property">class </em><code class="descclassname">socketserver.</code><code class="descname">ThreadingUDPServer</code><a class="headerlink" href="#socketserver.ThreadingUDPServer" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>These classes are pre-defined using the mix-in classes.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<p>To implement a service, you must derive a class from <a class="reference internal" href="#socketserver.BaseRequestHandler" title="socketserver.BaseRequestHandler"><code class="xref py py-class docutils literal notranslate"><span class="pre">BaseRequestHandler</span></code></a>
|
|||
|
and redefine its <a class="reference internal" href="#socketserver.BaseRequestHandler.handle" title="socketserver.BaseRequestHandler.handle"><code class="xref py py-meth docutils literal notranslate"><span class="pre">handle()</span></code></a> method.
|
|||
|
You can then run various versions of
|
|||
|
the service by combining one of the server classes with your request handler
|
|||
|
class. The request handler class must be different for datagram or stream
|
|||
|
services. This can be hidden by using the handler subclasses
|
|||
|
<a class="reference internal" href="#socketserver.StreamRequestHandler" title="socketserver.StreamRequestHandler"><code class="xref py py-class docutils literal notranslate"><span class="pre">StreamRequestHandler</span></code></a> or <a class="reference internal" href="#socketserver.DatagramRequestHandler" title="socketserver.DatagramRequestHandler"><code class="xref py py-class docutils literal notranslate"><span class="pre">DatagramRequestHandler</span></code></a>.</p>
|
|||
|
<p>Of course, you still have to use your head! For instance, it makes no sense to
|
|||
|
use a forking server if the service contains state in memory that can be
|
|||
|
modified by different requests, since the modifications in the child process
|
|||
|
would never reach the initial state kept in the parent process and passed to
|
|||
|
each child. In this case, you can use a threading server, but you will probably
|
|||
|
have to use locks to protect the integrity of the shared data.</p>
|
|||
|
<p>On the other hand, if you are building an HTTP server where all data is stored
|
|||
|
externally (for instance, in the file system), a synchronous class will
|
|||
|
essentially render the service “deaf” while one request is being handled –
|
|||
|
which may be for a very long time if a client is slow to receive all the data it
|
|||
|
has requested. Here a threading or forking server is appropriate.</p>
|
|||
|
<p>In some cases, it may be appropriate to process part of a request synchronously,
|
|||
|
but to finish processing in a forked child depending on the request data. This
|
|||
|
can be implemented by using a synchronous server and doing an explicit fork in
|
|||
|
the request handler class <a class="reference internal" href="#socketserver.BaseRequestHandler.handle" title="socketserver.BaseRequestHandler.handle"><code class="xref py py-meth docutils literal notranslate"><span class="pre">handle()</span></code></a> method.</p>
|
|||
|
<p>Another approach to handling multiple simultaneous requests in an environment
|
|||
|
that supports neither threads nor <a class="reference internal" href="os.html#os.fork" title="os.fork"><code class="xref py py-func docutils literal notranslate"><span class="pre">fork()</span></code></a> (or where these are too
|
|||
|
expensive or inappropriate for the service) is to maintain an explicit table of
|
|||
|
partially finished requests and to use <a class="reference internal" href="selectors.html#module-selectors" title="selectors: High-level I/O multiplexing."><code class="xref py py-mod docutils literal notranslate"><span class="pre">selectors</span></code></a> to decide which
|
|||
|
request to work on next (or whether to handle a new incoming request). This is
|
|||
|
particularly important for stream services where each client can potentially be
|
|||
|
connected for a long time (if threads or subprocesses cannot be used). See
|
|||
|
<a class="reference internal" href="asyncore.html#module-asyncore" title="asyncore: A base class for developing asynchronous socket handling services."><code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncore</span></code></a> for another way to manage this.</p>
|
|||
|
</div>
|
|||
|
<div class="section" id="server-objects">
|
|||
|
<h2>Server Objects<a class="headerlink" href="#server-objects" title="Permalink to this headline">¶</a></h2>
|
|||
|
<dl class="class">
|
|||
|
<dt id="socketserver.BaseServer">
|
|||
|
<em class="property">class </em><code class="descclassname">socketserver.</code><code class="descname">BaseServer</code><span class="sig-paren">(</span><em>server_address</em>, <em>RequestHandlerClass</em><span class="sig-paren">)</span><a class="headerlink" href="#socketserver.BaseServer" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>This is the superclass of all Server objects in the module. It defines the
|
|||
|
interface, given below, but does not implement most of the methods, which is
|
|||
|
done in subclasses. The two parameters are stored in the respective
|
|||
|
<a class="reference internal" href="#socketserver.BaseServer.server_address" title="socketserver.BaseServer.server_address"><code class="xref py py-attr docutils literal notranslate"><span class="pre">server_address</span></code></a> and <a class="reference internal" href="#socketserver.BaseServer.RequestHandlerClass" title="socketserver.BaseServer.RequestHandlerClass"><code class="xref py py-attr docutils literal notranslate"><span class="pre">RequestHandlerClass</span></code></a> attributes.</p>
|
|||
|
<dl class="method">
|
|||
|
<dt id="socketserver.BaseServer.fileno">
|
|||
|
<code class="descname">fileno</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#socketserver.BaseServer.fileno" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>Return an integer file descriptor for the socket on which the server is
|
|||
|
listening. This function is most commonly passed to <a class="reference internal" href="selectors.html#module-selectors" title="selectors: High-level I/O multiplexing."><code class="xref py py-mod docutils literal notranslate"><span class="pre">selectors</span></code></a>, to
|
|||
|
allow monitoring multiple servers in the same process.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="method">
|
|||
|
<dt id="socketserver.BaseServer.handle_request">
|
|||
|
<code class="descname">handle_request</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#socketserver.BaseServer.handle_request" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>Process a single request. This function calls the following methods in
|
|||
|
order: <a class="reference internal" href="#socketserver.BaseServer.get_request" title="socketserver.BaseServer.get_request"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get_request()</span></code></a>, <a class="reference internal" href="#socketserver.BaseServer.verify_request" title="socketserver.BaseServer.verify_request"><code class="xref py py-meth docutils literal notranslate"><span class="pre">verify_request()</span></code></a>, and
|
|||
|
<a class="reference internal" href="#socketserver.BaseServer.process_request" title="socketserver.BaseServer.process_request"><code class="xref py py-meth docutils literal notranslate"><span class="pre">process_request()</span></code></a>. If the user-provided
|
|||
|
<a class="reference internal" href="#socketserver.BaseRequestHandler.handle" title="socketserver.BaseRequestHandler.handle"><code class="xref py py-meth docutils literal notranslate"><span class="pre">handle()</span></code></a> method of the
|
|||
|
handler class raises an exception, the server’s <a class="reference internal" href="#socketserver.BaseServer.handle_error" title="socketserver.BaseServer.handle_error"><code class="xref py py-meth docutils literal notranslate"><span class="pre">handle_error()</span></code></a> method
|
|||
|
will be called. If no request is received within <a class="reference internal" href="#socketserver.BaseServer.timeout" title="socketserver.BaseServer.timeout"><code class="xref py py-attr docutils literal notranslate"><span class="pre">timeout</span></code></a>
|
|||
|
seconds, <a class="reference internal" href="#socketserver.BaseServer.handle_timeout" title="socketserver.BaseServer.handle_timeout"><code class="xref py py-meth docutils literal notranslate"><span class="pre">handle_timeout()</span></code></a> will be called and <a class="reference internal" href="#socketserver.BaseServer.handle_request" title="socketserver.BaseServer.handle_request"><code class="xref py py-meth docutils literal notranslate"><span class="pre">handle_request()</span></code></a>
|
|||
|
will return.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="method">
|
|||
|
<dt id="socketserver.BaseServer.serve_forever">
|
|||
|
<code class="descname">serve_forever</code><span class="sig-paren">(</span><em>poll_interval=0.5</em><span class="sig-paren">)</span><a class="headerlink" href="#socketserver.BaseServer.serve_forever" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>Handle requests until an explicit <a class="reference internal" href="#socketserver.BaseServer.shutdown" title="socketserver.BaseServer.shutdown"><code class="xref py py-meth docutils literal notranslate"><span class="pre">shutdown()</span></code></a> request. Poll for
|
|||
|
shutdown every <em>poll_interval</em> seconds.
|
|||
|
Ignores the <a class="reference internal" href="#socketserver.BaseServer.timeout" title="socketserver.BaseServer.timeout"><code class="xref py py-attr docutils literal notranslate"><span class="pre">timeout</span></code></a> attribute. It
|
|||
|
also calls <a class="reference internal" href="#socketserver.BaseServer.service_actions" title="socketserver.BaseServer.service_actions"><code class="xref py py-meth docutils literal notranslate"><span class="pre">service_actions()</span></code></a>, which may be used by a subclass or mixin
|
|||
|
to provide actions specific to a given service. For example, the
|
|||
|
<a class="reference internal" href="#socketserver.ForkingMixIn" title="socketserver.ForkingMixIn"><code class="xref py py-class docutils literal notranslate"><span class="pre">ForkingMixIn</span></code></a> class uses <a class="reference internal" href="#socketserver.BaseServer.service_actions" title="socketserver.BaseServer.service_actions"><code class="xref py py-meth docutils literal notranslate"><span class="pre">service_actions()</span></code></a> to clean up zombie
|
|||
|
child processes.</p>
|
|||
|
<div class="versionchanged">
|
|||
|
<p><span class="versionmodified changed">Changed in version 3.3: </span>Added <code class="docutils literal notranslate"><span class="pre">service_actions</span></code> call to the <code class="docutils literal notranslate"><span class="pre">serve_forever</span></code> method.</p>
|
|||
|
</div>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="method">
|
|||
|
<dt id="socketserver.BaseServer.service_actions">
|
|||
|
<code class="descname">service_actions</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#socketserver.BaseServer.service_actions" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>This is called in the <a class="reference internal" href="#socketserver.BaseServer.serve_forever" title="socketserver.BaseServer.serve_forever"><code class="xref py py-meth docutils literal notranslate"><span class="pre">serve_forever()</span></code></a> loop. This method can be
|
|||
|
overridden by subclasses or mixin classes to perform actions specific to
|
|||
|
a given service, such as cleanup actions.</p>
|
|||
|
<div class="versionadded">
|
|||
|
<p><span class="versionmodified added">New in version 3.3.</span></p>
|
|||
|
</div>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="method">
|
|||
|
<dt id="socketserver.BaseServer.shutdown">
|
|||
|
<code class="descname">shutdown</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#socketserver.BaseServer.shutdown" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>Tell the <a class="reference internal" href="#socketserver.BaseServer.serve_forever" title="socketserver.BaseServer.serve_forever"><code class="xref py py-meth docutils literal notranslate"><span class="pre">serve_forever()</span></code></a> loop to stop and wait until it does.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="method">
|
|||
|
<dt id="socketserver.BaseServer.server_close">
|
|||
|
<code class="descname">server_close</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#socketserver.BaseServer.server_close" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>Clean up the server. May be overridden.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="attribute">
|
|||
|
<dt id="socketserver.BaseServer.address_family">
|
|||
|
<code class="descname">address_family</code><a class="headerlink" href="#socketserver.BaseServer.address_family" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>The family of protocols to which the server’s socket belongs.
|
|||
|
Common examples are <a class="reference internal" href="socket.html#socket.AF_INET" title="socket.AF_INET"><code class="xref py py-const docutils literal notranslate"><span class="pre">socket.AF_INET</span></code></a> and <a class="reference internal" href="socket.html#socket.AF_UNIX" title="socket.AF_UNIX"><code class="xref py py-const docutils literal notranslate"><span class="pre">socket.AF_UNIX</span></code></a>.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="attribute">
|
|||
|
<dt id="socketserver.BaseServer.RequestHandlerClass">
|
|||
|
<code class="descname">RequestHandlerClass</code><a class="headerlink" href="#socketserver.BaseServer.RequestHandlerClass" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>The user-provided request handler class; an instance of this class is created
|
|||
|
for each request.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="attribute">
|
|||
|
<dt id="socketserver.BaseServer.server_address">
|
|||
|
<code class="descname">server_address</code><a class="headerlink" href="#socketserver.BaseServer.server_address" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>The address on which the server is listening. The format of addresses varies
|
|||
|
depending on the protocol family;
|
|||
|
see the documentation for the <a class="reference internal" href="socket.html#module-socket" title="socket: Low-level networking interface."><code class="xref py py-mod docutils literal notranslate"><span class="pre">socket</span></code></a> module
|
|||
|
for details. For Internet protocols, this is a tuple containing a string giving
|
|||
|
the address, and an integer port number: <code class="docutils literal notranslate"><span class="pre">('127.0.0.1',</span> <span class="pre">80)</span></code>, for example.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="attribute">
|
|||
|
<dt id="socketserver.BaseServer.socket">
|
|||
|
<code class="descname">socket</code><a class="headerlink" href="#socketserver.BaseServer.socket" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>The socket object on which the server will listen for incoming requests.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<p>The server classes support the following class variables:</p>
|
|||
|
<dl class="attribute">
|
|||
|
<dt id="socketserver.BaseServer.allow_reuse_address">
|
|||
|
<code class="descname">allow_reuse_address</code><a class="headerlink" href="#socketserver.BaseServer.allow_reuse_address" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>Whether the server will allow the reuse of an address. This defaults to
|
|||
|
<a class="reference internal" href="constants.html#False" title="False"><code class="xref py py-const docutils literal notranslate"><span class="pre">False</span></code></a>, and can be set in subclasses to change the policy.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="attribute">
|
|||
|
<dt id="socketserver.BaseServer.request_queue_size">
|
|||
|
<code class="descname">request_queue_size</code><a class="headerlink" href="#socketserver.BaseServer.request_queue_size" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>The size of the request queue. If it takes a long time to process a single
|
|||
|
request, any requests that arrive while the server is busy are placed into a
|
|||
|
queue, up to <a class="reference internal" href="#socketserver.BaseServer.request_queue_size" title="socketserver.BaseServer.request_queue_size"><code class="xref py py-attr docutils literal notranslate"><span class="pre">request_queue_size</span></code></a> requests. Once the queue is full,
|
|||
|
further requests from clients will get a “Connection denied” error. The default
|
|||
|
value is usually 5, but this can be overridden by subclasses.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="attribute">
|
|||
|
<dt id="socketserver.BaseServer.socket_type">
|
|||
|
<code class="descname">socket_type</code><a class="headerlink" href="#socketserver.BaseServer.socket_type" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>The type of socket used by the server; <a class="reference internal" href="socket.html#socket.SOCK_STREAM" title="socket.SOCK_STREAM"><code class="xref py py-const docutils literal notranslate"><span class="pre">socket.SOCK_STREAM</span></code></a> and
|
|||
|
<a class="reference internal" href="socket.html#socket.SOCK_DGRAM" title="socket.SOCK_DGRAM"><code class="xref py py-const docutils literal notranslate"><span class="pre">socket.SOCK_DGRAM</span></code></a> are two common values.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="attribute">
|
|||
|
<dt id="socketserver.BaseServer.timeout">
|
|||
|
<code class="descname">timeout</code><a class="headerlink" href="#socketserver.BaseServer.timeout" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>Timeout duration, measured in seconds, or <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a> if no timeout is
|
|||
|
desired. If <a class="reference internal" href="#socketserver.BaseServer.handle_request" title="socketserver.BaseServer.handle_request"><code class="xref py py-meth docutils literal notranslate"><span class="pre">handle_request()</span></code></a> receives no incoming requests within the
|
|||
|
timeout period, the <a class="reference internal" href="#socketserver.BaseServer.handle_timeout" title="socketserver.BaseServer.handle_timeout"><code class="xref py py-meth docutils literal notranslate"><span class="pre">handle_timeout()</span></code></a> method is called.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<p>There are various server methods that can be overridden by subclasses of base
|
|||
|
server classes like <a class="reference internal" href="#socketserver.TCPServer" title="socketserver.TCPServer"><code class="xref py py-class docutils literal notranslate"><span class="pre">TCPServer</span></code></a>; these methods aren’t useful to external
|
|||
|
users of the server object.</p>
|
|||
|
<dl class="method">
|
|||
|
<dt id="socketserver.BaseServer.finish_request">
|
|||
|
<code class="descname">finish_request</code><span class="sig-paren">(</span><em>request</em>, <em>client_address</em><span class="sig-paren">)</span><a class="headerlink" href="#socketserver.BaseServer.finish_request" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>Actually processes the request by instantiating <a class="reference internal" href="#socketserver.BaseServer.RequestHandlerClass" title="socketserver.BaseServer.RequestHandlerClass"><code class="xref py py-attr docutils literal notranslate"><span class="pre">RequestHandlerClass</span></code></a> and
|
|||
|
calling its <a class="reference internal" href="#socketserver.BaseRequestHandler.handle" title="socketserver.BaseRequestHandler.handle"><code class="xref py py-meth docutils literal notranslate"><span class="pre">handle()</span></code></a> method.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="method">
|
|||
|
<dt id="socketserver.BaseServer.get_request">
|
|||
|
<code class="descname">get_request</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#socketserver.BaseServer.get_request" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>Must accept a request from the socket, and return a 2-tuple containing the <em>new</em>
|
|||
|
socket object to be used to communicate with the client, and the client’s
|
|||
|
address.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="method">
|
|||
|
<dt id="socketserver.BaseServer.handle_error">
|
|||
|
<code class="descname">handle_error</code><span class="sig-paren">(</span><em>request</em>, <em>client_address</em><span class="sig-paren">)</span><a class="headerlink" href="#socketserver.BaseServer.handle_error" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>This function is called if the <a class="reference internal" href="#socketserver.BaseRequestHandler.handle" title="socketserver.BaseRequestHandler.handle"><code class="xref py py-meth docutils literal notranslate"><span class="pre">handle()</span></code></a>
|
|||
|
method of a <a class="reference internal" href="#socketserver.BaseServer.RequestHandlerClass" title="socketserver.BaseServer.RequestHandlerClass"><code class="xref py py-attr docutils literal notranslate"><span class="pre">RequestHandlerClass</span></code></a> instance raises
|
|||
|
an exception. The default action is to print the traceback to
|
|||
|
standard error and continue handling further requests.</p>
|
|||
|
<div class="versionchanged">
|
|||
|
<p><span class="versionmodified changed">Changed in version 3.6: </span>Now only called for exceptions derived from the <a class="reference internal" href="exceptions.html#Exception" title="Exception"><code class="xref py py-exc docutils literal notranslate"><span class="pre">Exception</span></code></a>
|
|||
|
class.</p>
|
|||
|
</div>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="method">
|
|||
|
<dt id="socketserver.BaseServer.handle_timeout">
|
|||
|
<code class="descname">handle_timeout</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#socketserver.BaseServer.handle_timeout" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>This function is called when the <a class="reference internal" href="#socketserver.BaseServer.timeout" title="socketserver.BaseServer.timeout"><code class="xref py py-attr docutils literal notranslate"><span class="pre">timeout</span></code></a> attribute has been set to a
|
|||
|
value other than <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a> and the timeout period has passed with no
|
|||
|
requests being received. The default action for forking servers is
|
|||
|
to collect the status of any child processes that have exited, while
|
|||
|
in threading servers this method does nothing.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="method">
|
|||
|
<dt id="socketserver.BaseServer.process_request">
|
|||
|
<code class="descname">process_request</code><span class="sig-paren">(</span><em>request</em>, <em>client_address</em><span class="sig-paren">)</span><a class="headerlink" href="#socketserver.BaseServer.process_request" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>Calls <a class="reference internal" href="#socketserver.BaseServer.finish_request" title="socketserver.BaseServer.finish_request"><code class="xref py py-meth docutils literal notranslate"><span class="pre">finish_request()</span></code></a> to create an instance of the
|
|||
|
<a class="reference internal" href="#socketserver.BaseServer.RequestHandlerClass" title="socketserver.BaseServer.RequestHandlerClass"><code class="xref py py-attr docutils literal notranslate"><span class="pre">RequestHandlerClass</span></code></a>. If desired, this function can create a new process
|
|||
|
or thread to handle the request; the <a class="reference internal" href="#socketserver.ForkingMixIn" title="socketserver.ForkingMixIn"><code class="xref py py-class docutils literal notranslate"><span class="pre">ForkingMixIn</span></code></a> and
|
|||
|
<a class="reference internal" href="#socketserver.ThreadingMixIn" title="socketserver.ThreadingMixIn"><code class="xref py py-class docutils literal notranslate"><span class="pre">ThreadingMixIn</span></code></a> classes do this.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="method">
|
|||
|
<dt id="socketserver.BaseServer.server_activate">
|
|||
|
<code class="descname">server_activate</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#socketserver.BaseServer.server_activate" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>Called by the server’s constructor to activate the server. The default behavior
|
|||
|
for a TCP server just invokes <a class="reference internal" href="socket.html#socket.socket.listen" title="socket.socket.listen"><code class="xref py py-meth docutils literal notranslate"><span class="pre">listen()</span></code></a>
|
|||
|
on the server’s socket. May be overridden.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="method">
|
|||
|
<dt id="socketserver.BaseServer.server_bind">
|
|||
|
<code class="descname">server_bind</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#socketserver.BaseServer.server_bind" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>Called by the server’s constructor to bind the socket to the desired address.
|
|||
|
May be overridden.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="method">
|
|||
|
<dt id="socketserver.BaseServer.verify_request">
|
|||
|
<code class="descname">verify_request</code><span class="sig-paren">(</span><em>request</em>, <em>client_address</em><span class="sig-paren">)</span><a class="headerlink" href="#socketserver.BaseServer.verify_request" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>Must return a Boolean value; if the value is <a class="reference internal" href="constants.html#True" title="True"><code class="xref py py-const docutils literal notranslate"><span class="pre">True</span></code></a>, the request will
|
|||
|
be processed, and if it’s <a class="reference internal" href="constants.html#False" title="False"><code class="xref py py-const docutils literal notranslate"><span class="pre">False</span></code></a>, the request will be denied. This
|
|||
|
function can be overridden to implement access controls for a server. The
|
|||
|
default implementation always returns <a class="reference internal" href="constants.html#True" title="True"><code class="xref py py-const docutils literal notranslate"><span class="pre">True</span></code></a>.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<div class="versionchanged">
|
|||
|
<p><span class="versionmodified changed">Changed in version 3.6: </span>Support for the <a class="reference internal" href="../glossary.html#term-context-manager"><span class="xref std std-term">context manager</span></a> protocol was added. Exiting the
|
|||
|
context manager is equivalent to calling <a class="reference internal" href="#socketserver.BaseServer.server_close" title="socketserver.BaseServer.server_close"><code class="xref py py-meth docutils literal notranslate"><span class="pre">server_close()</span></code></a>.</p>
|
|||
|
</div>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
</div>
|
|||
|
<div class="section" id="request-handler-objects">
|
|||
|
<h2>Request Handler Objects<a class="headerlink" href="#request-handler-objects" title="Permalink to this headline">¶</a></h2>
|
|||
|
<dl class="class">
|
|||
|
<dt id="socketserver.BaseRequestHandler">
|
|||
|
<em class="property">class </em><code class="descclassname">socketserver.</code><code class="descname">BaseRequestHandler</code><a class="headerlink" href="#socketserver.BaseRequestHandler" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>This is the superclass of all request handler objects. It defines
|
|||
|
the interface, given below. A concrete request handler subclass must
|
|||
|
define a new <a class="reference internal" href="#socketserver.BaseRequestHandler.handle" title="socketserver.BaseRequestHandler.handle"><code class="xref py py-meth docutils literal notranslate"><span class="pre">handle()</span></code></a> method, and can override any of
|
|||
|
the other methods. A new instance of the subclass is created for each
|
|||
|
request.</p>
|
|||
|
<dl class="method">
|
|||
|
<dt id="socketserver.BaseRequestHandler.setup">
|
|||
|
<code class="descname">setup</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#socketserver.BaseRequestHandler.setup" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>Called before the <a class="reference internal" href="#socketserver.BaseRequestHandler.handle" title="socketserver.BaseRequestHandler.handle"><code class="xref py py-meth docutils literal notranslate"><span class="pre">handle()</span></code></a> method to perform any initialization actions
|
|||
|
required. The default implementation does nothing.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="method">
|
|||
|
<dt id="socketserver.BaseRequestHandler.handle">
|
|||
|
<code class="descname">handle</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#socketserver.BaseRequestHandler.handle" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>This function must do all the work required to service a request. The
|
|||
|
default implementation does nothing. Several instance attributes are
|
|||
|
available to it; the request is available as <code class="xref py py-attr docutils literal notranslate"><span class="pre">self.request</span></code>; the client
|
|||
|
address as <code class="xref py py-attr docutils literal notranslate"><span class="pre">self.client_address</span></code>; and the server instance as
|
|||
|
<code class="xref py py-attr docutils literal notranslate"><span class="pre">self.server</span></code>, in case it needs access to per-server information.</p>
|
|||
|
<p>The type of <code class="xref py py-attr docutils literal notranslate"><span class="pre">self.request</span></code> is different for datagram or stream
|
|||
|
services. For stream services, <code class="xref py py-attr docutils literal notranslate"><span class="pre">self.request</span></code> is a socket object; for
|
|||
|
datagram services, <code class="xref py py-attr docutils literal notranslate"><span class="pre">self.request</span></code> is a pair of string and socket.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="method">
|
|||
|
<dt id="socketserver.BaseRequestHandler.finish">
|
|||
|
<code class="descname">finish</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#socketserver.BaseRequestHandler.finish" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>Called after the <a class="reference internal" href="#socketserver.BaseRequestHandler.handle" title="socketserver.BaseRequestHandler.handle"><code class="xref py py-meth docutils literal notranslate"><span class="pre">handle()</span></code></a> method to perform any clean-up actions
|
|||
|
required. The default implementation does nothing. If <a class="reference internal" href="#socketserver.BaseRequestHandler.setup" title="socketserver.BaseRequestHandler.setup"><code class="xref py py-meth docutils literal notranslate"><span class="pre">setup()</span></code></a>
|
|||
|
raises an exception, this function will not be called.</p>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
<dl class="class">
|
|||
|
<dt id="socketserver.StreamRequestHandler">
|
|||
|
<em class="property">class </em><code class="descclassname">socketserver.</code><code class="descname">StreamRequestHandler</code><a class="headerlink" href="#socketserver.StreamRequestHandler" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dt id="socketserver.DatagramRequestHandler">
|
|||
|
<em class="property">class </em><code class="descclassname">socketserver.</code><code class="descname">DatagramRequestHandler</code><a class="headerlink" href="#socketserver.DatagramRequestHandler" title="Permalink to this definition">¶</a></dt>
|
|||
|
<dd><p>These <a class="reference internal" href="#socketserver.BaseRequestHandler" title="socketserver.BaseRequestHandler"><code class="xref py py-class docutils literal notranslate"><span class="pre">BaseRequestHandler</span></code></a> subclasses override the
|
|||
|
<a class="reference internal" href="#socketserver.BaseRequestHandler.setup" title="socketserver.BaseRequestHandler.setup"><code class="xref py py-meth docutils literal notranslate"><span class="pre">setup()</span></code></a> and <a class="reference internal" href="#socketserver.BaseRequestHandler.finish" title="socketserver.BaseRequestHandler.finish"><code class="xref py py-meth docutils literal notranslate"><span class="pre">finish()</span></code></a>
|
|||
|
methods, and provide <code class="xref py py-attr docutils literal notranslate"><span class="pre">self.rfile</span></code> and <code class="xref py py-attr docutils literal notranslate"><span class="pre">self.wfile</span></code> attributes.
|
|||
|
The <code class="xref py py-attr docutils literal notranslate"><span class="pre">self.rfile</span></code> and <code class="xref py py-attr docutils literal notranslate"><span class="pre">self.wfile</span></code> attributes can be
|
|||
|
read or written, respectively, to get the request data or return data
|
|||
|
to the client.</p>
|
|||
|
<p>The <code class="xref py py-attr docutils literal notranslate"><span class="pre">rfile</span></code> attributes of both classes support the
|
|||
|
<a class="reference internal" href="io.html#io.BufferedIOBase" title="io.BufferedIOBase"><code class="xref py py-class docutils literal notranslate"><span class="pre">io.BufferedIOBase</span></code></a> readable interface, and
|
|||
|
<code class="xref py py-attr docutils literal notranslate"><span class="pre">DatagramRequestHandler.wfile</span></code> supports the
|
|||
|
<a class="reference internal" href="io.html#io.BufferedIOBase" title="io.BufferedIOBase"><code class="xref py py-class docutils literal notranslate"><span class="pre">io.BufferedIOBase</span></code></a> writable interface.</p>
|
|||
|
<div class="versionchanged">
|
|||
|
<p><span class="versionmodified changed">Changed in version 3.6: </span><code class="xref py py-attr docutils literal notranslate"><span class="pre">StreamRequestHandler.wfile</span></code> also supports the
|
|||
|
<a class="reference internal" href="io.html#io.BufferedIOBase" title="io.BufferedIOBase"><code class="xref py py-class docutils literal notranslate"><span class="pre">io.BufferedIOBase</span></code></a> writable interface.</p>
|
|||
|
</div>
|
|||
|
</dd></dl>
|
|||
|
|
|||
|
</div>
|
|||
|
<div class="section" id="examples">
|
|||
|
<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
|
|||
|
<div class="section" id="socketserver-tcpserver-example">
|
|||
|
<h3><a class="reference internal" href="#socketserver.TCPServer" title="socketserver.TCPServer"><code class="xref py py-class docutils literal notranslate"><span class="pre">socketserver.TCPServer</span></code></a> Example<a class="headerlink" href="#socketserver-tcpserver-example" title="Permalink to this headline">¶</a></h3>
|
|||
|
<p>This is the server side:</p>
|
|||
|
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">socketserver</span>
|
|||
|
|
|||
|
<span class="k">class</span> <span class="nc">MyTCPHandler</span><span class="p">(</span><span class="n">socketserver</span><span class="o">.</span><span class="n">BaseRequestHandler</span><span class="p">):</span>
|
|||
|
<span class="sd">"""</span>
|
|||
|
<span class="sd"> The request handler class for our server.</span>
|
|||
|
|
|||
|
<span class="sd"> It is instantiated once per connection to the server, and must</span>
|
|||
|
<span class="sd"> override the handle() method to implement communication to the</span>
|
|||
|
<span class="sd"> client.</span>
|
|||
|
<span class="sd"> """</span>
|
|||
|
|
|||
|
<span class="k">def</span> <span class="nf">handle</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|||
|
<span class="c1"># self.request is the TCP socket connected to the client</span>
|
|||
|
<span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">request</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="o">.</span><span class="n">strip</span><span class="p">()</span>
|
|||
|
<span class="nb">print</span><span class="p">(</span><span class="s2">"</span><span class="si">{}</span><span class="s2"> wrote:"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">client_address</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span>
|
|||
|
<span class="nb">print</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">)</span>
|
|||
|
<span class="c1"># just send back the same data, but upper-cased</span>
|
|||
|
<span class="bp">self</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">sendall</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">upper</span><span class="p">())</span>
|
|||
|
|
|||
|
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">"__main__"</span><span class="p">:</span>
|
|||
|
<span class="n">HOST</span><span class="p">,</span> <span class="n">PORT</span> <span class="o">=</span> <span class="s2">"localhost"</span><span class="p">,</span> <span class="mi">9999</span>
|
|||
|
|
|||
|
<span class="c1"># Create the server, binding to localhost on port 9999</span>
|
|||
|
<span class="k">with</span> <span class="n">socketserver</span><span class="o">.</span><span class="n">TCPServer</span><span class="p">((</span><span class="n">HOST</span><span class="p">,</span> <span class="n">PORT</span><span class="p">),</span> <span class="n">MyTCPHandler</span><span class="p">)</span> <span class="k">as</span> <span class="n">server</span><span class="p">:</span>
|
|||
|
<span class="c1"># Activate the server; this will keep running until you</span>
|
|||
|
<span class="c1"># interrupt the program with Ctrl-C</span>
|
|||
|
<span class="n">server</span><span class="o">.</span><span class="n">serve_forever</span><span class="p">()</span>
|
|||
|
</pre></div>
|
|||
|
</div>
|
|||
|
<p>An alternative request handler class that makes use of streams (file-like
|
|||
|
objects that simplify communication by providing the standard file interface):</p>
|
|||
|
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyTCPHandler</span><span class="p">(</span><span class="n">socketserver</span><span class="o">.</span><span class="n">StreamRequestHandler</span><span class="p">):</span>
|
|||
|
|
|||
|
<span class="k">def</span> <span class="nf">handle</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|||
|
<span class="c1"># self.rfile is a file-like object created by the handler;</span>
|
|||
|
<span class="c1"># we can now use e.g. readline() instead of raw recv() calls</span>
|
|||
|
<span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rfile</span><span class="o">.</span><span class="n">readline</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
|
|||
|
<span class="nb">print</span><span class="p">(</span><span class="s2">"</span><span class="si">{}</span><span class="s2"> wrote:"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">client_address</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span>
|
|||
|
<span class="nb">print</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">)</span>
|
|||
|
<span class="c1"># Likewise, self.wfile is a file-like object used to write back</span>
|
|||
|
<span class="c1"># to the client</span>
|
|||
|
<span class="bp">self</span><span class="o">.</span><span class="n">wfile</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">upper</span><span class="p">())</span>
|
|||
|
</pre></div>
|
|||
|
</div>
|
|||
|
<p>The difference is that the <code class="docutils literal notranslate"><span class="pre">readline()</span></code> call in the second handler will call
|
|||
|
<code class="docutils literal notranslate"><span class="pre">recv()</span></code> multiple times until it encounters a newline character, while the
|
|||
|
single <code class="docutils literal notranslate"><span class="pre">recv()</span></code> call in the first handler will just return what has been sent
|
|||
|
from the client in one <code class="docutils literal notranslate"><span class="pre">sendall()</span></code> call.</p>
|
|||
|
<p>This is the client side:</p>
|
|||
|
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">socket</span>
|
|||
|
<span class="kn">import</span> <span class="nn">sys</span>
|
|||
|
|
|||
|
<span class="n">HOST</span><span class="p">,</span> <span class="n">PORT</span> <span class="o">=</span> <span class="s2">"localhost"</span><span class="p">,</span> <span class="mi">9999</span>
|
|||
|
<span class="n">data</span> <span class="o">=</span> <span class="s2">" "</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
|
|||
|
|
|||
|
<span class="c1"># Create a socket (SOCK_STREAM means a TCP socket)</span>
|
|||
|
<span class="k">with</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="k">as</span> <span class="n">sock</span><span class="p">:</span>
|
|||
|
<span class="c1"># Connect to server and send data</span>
|
|||
|
<span class="n">sock</span><span class="o">.</span><span class="n">connect</span><span class="p">((</span><span class="n">HOST</span><span class="p">,</span> <span class="n">PORT</span><span class="p">))</span>
|
|||
|
<span class="n">sock</span><span class="o">.</span><span class="n">sendall</span><span class="p">(</span><span class="nb">bytes</span><span class="p">(</span><span class="n">data</span> <span class="o">+</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">,</span> <span class="s2">"utf-8"</span><span class="p">))</span>
|
|||
|
|
|||
|
<span class="c1"># Receive data from the server and shut down</span>
|
|||
|
<span class="n">received</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">sock</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="s2">"utf-8"</span><span class="p">)</span>
|
|||
|
|
|||
|
<span class="nb">print</span><span class="p">(</span><span class="s2">"Sent: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">data</span><span class="p">))</span>
|
|||
|
<span class="nb">print</span><span class="p">(</span><span class="s2">"Received: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">received</span><span class="p">))</span>
|
|||
|
</pre></div>
|
|||
|
</div>
|
|||
|
<p>The output of the example should look something like this:</p>
|
|||
|
<p>Server:</p>
|
|||
|
<div class="highlight-shell-session notranslate"><div class="highlight"><pre><span></span><span class="gp">$</span> python TCPServer.py
|
|||
|
<span class="go">127.0.0.1 wrote:</span>
|
|||
|
<span class="go">b'hello world with TCP'</span>
|
|||
|
<span class="go">127.0.0.1 wrote:</span>
|
|||
|
<span class="go">b'python is nice'</span>
|
|||
|
</pre></div>
|
|||
|
</div>
|
|||
|
<p>Client:</p>
|
|||
|
<div class="highlight-shell-session notranslate"><div class="highlight"><pre><span></span><span class="gp">$</span> python TCPClient.py hello world with TCP
|
|||
|
<span class="go">Sent: hello world with TCP</span>
|
|||
|
<span class="go">Received: HELLO WORLD WITH TCP</span>
|
|||
|
<span class="gp">$</span> python TCPClient.py python is nice
|
|||
|
<span class="go">Sent: python is nice</span>
|
|||
|
<span class="go">Received: PYTHON IS NICE</span>
|
|||
|
</pre></div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<div class="section" id="socketserver-udpserver-example">
|
|||
|
<h3><a class="reference internal" href="#socketserver.UDPServer" title="socketserver.UDPServer"><code class="xref py py-class docutils literal notranslate"><span class="pre">socketserver.UDPServer</span></code></a> Example<a class="headerlink" href="#socketserver-udpserver-example" title="Permalink to this headline">¶</a></h3>
|
|||
|
<p>This is the server side:</p>
|
|||
|
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">socketserver</span>
|
|||
|
|
|||
|
<span class="k">class</span> <span class="nc">MyUDPHandler</span><span class="p">(</span><span class="n">socketserver</span><span class="o">.</span><span class="n">BaseRequestHandler</span><span class="p">):</span>
|
|||
|
<span class="sd">"""</span>
|
|||
|
<span class="sd"> This class works similar to the TCP handler class, except that</span>
|
|||
|
<span class="sd"> self.request consists of a pair of data and client socket, and since</span>
|
|||
|
<span class="sd"> there is no connection the client address must be given explicitly</span>
|
|||
|
<span class="sd"> when sending data back via sendto().</span>
|
|||
|
<span class="sd"> """</span>
|
|||
|
|
|||
|
<span class="k">def</span> <span class="nf">handle</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|||
|
<span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">request</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
|
|||
|
<span class="n">socket</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">request</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
|||
|
<span class="nb">print</span><span class="p">(</span><span class="s2">"</span><span class="si">{}</span><span class="s2"> wrote:"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">client_address</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span>
|
|||
|
<span class="nb">print</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
|
|||
|
<span class="n">socket</span><span class="o">.</span><span class="n">sendto</span><span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">client_address</span><span class="p">)</span>
|
|||
|
|
|||
|
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">"__main__"</span><span class="p">:</span>
|
|||
|
<span class="n">HOST</span><span class="p">,</span> <span class="n">PORT</span> <span class="o">=</span> <span class="s2">"localhost"</span><span class="p">,</span> <span class="mi">9999</span>
|
|||
|
<span class="k">with</span> <span class="n">socketserver</span><span class="o">.</span><span class="n">UDPServer</span><span class="p">((</span><span class="n">HOST</span><span class="p">,</span> <span class="n">PORT</span><span class="p">),</span> <span class="n">MyUDPHandler</span><span class="p">)</span> <span class="k">as</span> <span class="n">server</span><span class="p">:</span>
|
|||
|
<span class="n">server</span><span class="o">.</span><span class="n">serve_forever</span><span class="p">()</span>
|
|||
|
</pre></div>
|
|||
|
</div>
|
|||
|
<p>This is the client side:</p>
|
|||
|
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">socket</span>
|
|||
|
<span class="kn">import</span> <span class="nn">sys</span>
|
|||
|
|
|||
|
<span class="n">HOST</span><span class="p">,</span> <span class="n">PORT</span> <span class="o">=</span> <span class="s2">"localhost"</span><span class="p">,</span> <span class="mi">9999</span>
|
|||
|
<span class="n">data</span> <span class="o">=</span> <span class="s2">" "</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
|
|||
|
|
|||
|
<span class="c1"># SOCK_DGRAM is the socket type to use for UDP sockets</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_DGRAM</span><span class="p">)</span>
|
|||
|
|
|||
|
<span class="c1"># As you can see, there is no connect() call; UDP has no connections.</span>
|
|||
|
<span class="c1"># Instead, data is directly sent to the recipient via sendto().</span>
|
|||
|
<span class="n">sock</span><span class="o">.</span><span class="n">sendto</span><span class="p">(</span><span class="nb">bytes</span><span class="p">(</span><span class="n">data</span> <span class="o">+</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">,</span> <span class="s2">"utf-8"</span><span class="p">),</span> <span class="p">(</span><span class="n">HOST</span><span class="p">,</span> <span class="n">PORT</span><span class="p">))</span>
|
|||
|
<span class="n">received</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">sock</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="s2">"utf-8"</span><span class="p">)</span>
|
|||
|
|
|||
|
<span class="nb">print</span><span class="p">(</span><span class="s2">"Sent: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">data</span><span class="p">))</span>
|
|||
|
<span class="nb">print</span><span class="p">(</span><span class="s2">"Received: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">received</span><span class="p">))</span>
|
|||
|
</pre></div>
|
|||
|
</div>
|
|||
|
<p>The output of the example should look exactly like for the TCP server example.</p>
|
|||
|
</div>
|
|||
|
<div class="section" id="asynchronous-mixins">
|
|||
|
<h3>Asynchronous Mixins<a class="headerlink" href="#asynchronous-mixins" title="Permalink to this headline">¶</a></h3>
|
|||
|
<p>To build asynchronous handlers, use the <a class="reference internal" href="#socketserver.ThreadingMixIn" title="socketserver.ThreadingMixIn"><code class="xref py py-class docutils literal notranslate"><span class="pre">ThreadingMixIn</span></code></a> and
|
|||
|
<a class="reference internal" href="#socketserver.ForkingMixIn" title="socketserver.ForkingMixIn"><code class="xref py py-class docutils literal notranslate"><span class="pre">ForkingMixIn</span></code></a> classes.</p>
|
|||
|
<p>An example for the <a class="reference internal" href="#socketserver.ThreadingMixIn" title="socketserver.ThreadingMixIn"><code class="xref py py-class docutils literal notranslate"><span class="pre">ThreadingMixIn</span></code></a> class:</p>
|
|||
|
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">socket</span>
|
|||
|
<span class="kn">import</span> <span class="nn">threading</span>
|
|||
|
<span class="kn">import</span> <span class="nn">socketserver</span>
|
|||
|
|
|||
|
<span class="k">class</span> <span class="nc">ThreadedTCPRequestHandler</span><span class="p">(</span><span class="n">socketserver</span><span class="o">.</span><span class="n">BaseRequestHandler</span><span class="p">):</span>
|
|||
|
|
|||
|
<span class="k">def</span> <span class="nf">handle</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|||
|
<span class="n">data</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">request</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="s1">'ascii'</span><span class="p">)</span>
|
|||
|
<span class="n">cur_thread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">current_thread</span><span class="p">()</span>
|
|||
|
<span class="n">response</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">(</span><span class="s2">"</span><span class="si">{}</span><span class="s2">: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">cur_thread</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">data</span><span class="p">),</span> <span class="s1">'ascii'</span><span class="p">)</span>
|
|||
|
<span class="bp">self</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">sendall</span><span class="p">(</span><span class="n">response</span><span class="p">)</span>
|
|||
|
|
|||
|
<span class="k">class</span> <span class="nc">ThreadedTCPServer</span><span class="p">(</span><span class="n">socketserver</span><span class="o">.</span><span class="n">ThreadingMixIn</span><span class="p">,</span> <span class="n">socketserver</span><span class="o">.</span><span class="n">TCPServer</span><span class="p">):</span>
|
|||
|
<span class="k">pass</span>
|
|||
|
|
|||
|
<span class="k">def</span> <span class="nf">client</span><span class="p">(</span><span class="n">ip</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
|
|||
|
<span class="k">with</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="k">as</span> <span class="n">sock</span><span class="p">:</span>
|
|||
|
<span class="n">sock</span><span class="o">.</span><span class="n">connect</span><span class="p">((</span><span class="n">ip</span><span class="p">,</span> <span class="n">port</span><span class="p">))</span>
|
|||
|
<span class="n">sock</span><span class="o">.</span><span class="n">sendall</span><span class="p">(</span><span class="nb">bytes</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="s1">'ascii'</span><span class="p">))</span>
|
|||
|
<span class="n">response</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">sock</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="s1">'ascii'</span><span class="p">)</span>
|
|||
|
<span class="nb">print</span><span class="p">(</span><span class="s2">"Received: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">response</span><span class="p">))</span>
|
|||
|
|
|||
|
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">"__main__"</span><span class="p">:</span>
|
|||
|
<span class="c1"># Port 0 means to select an arbitrary unused port</span>
|
|||
|
<span class="n">HOST</span><span class="p">,</span> <span class="n">PORT</span> <span class="o">=</span> <span class="s2">"localhost"</span><span class="p">,</span> <span class="mi">0</span>
|
|||
|
|
|||
|
<span class="n">server</span> <span class="o">=</span> <span class="n">ThreadedTCPServer</span><span class="p">((</span><span class="n">HOST</span><span class="p">,</span> <span class="n">PORT</span><span class="p">),</span> <span class="n">ThreadedTCPRequestHandler</span><span class="p">)</span>
|
|||
|
<span class="k">with</span> <span class="n">server</span><span class="p">:</span>
|
|||
|
<span class="n">ip</span><span class="p">,</span> <span class="n">port</span> <span class="o">=</span> <span class="n">server</span><span class="o">.</span><span class="n">server_address</span>
|
|||
|
|
|||
|
<span class="c1"># Start a thread with the server -- that thread will then start one</span>
|
|||
|
<span class="c1"># more thread for each request</span>
|
|||
|
<span class="n">server_thread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">server</span><span class="o">.</span><span class="n">serve_forever</span><span class="p">)</span>
|
|||
|
<span class="c1"># Exit the server thread when the main thread terminates</span>
|
|||
|
<span class="n">server_thread</span><span class="o">.</span><span class="n">daemon</span> <span class="o">=</span> <span class="kc">True</span>
|
|||
|
<span class="n">server_thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
|
|||
|
<span class="nb">print</span><span class="p">(</span><span class="s2">"Server loop running in thread:"</span><span class="p">,</span> <span class="n">server_thread</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
|
|||
|
|
|||
|
<span class="n">client</span><span class="p">(</span><span class="n">ip</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="s2">"Hello World 1"</span><span class="p">)</span>
|
|||
|
<span class="n">client</span><span class="p">(</span><span class="n">ip</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="s2">"Hello World 2"</span><span class="p">)</span>
|
|||
|
<span class="n">client</span><span class="p">(</span><span class="n">ip</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="s2">"Hello World 3"</span><span class="p">)</span>
|
|||
|
|
|||
|
<span class="n">server</span><span class="o">.</span><span class="n">shutdown</span><span class="p">()</span>
|
|||
|
</pre></div>
|
|||
|
</div>
|
|||
|
<p>The output of the example should look something like this:</p>
|
|||
|
<div class="highlight-shell-session notranslate"><div class="highlight"><pre><span></span><span class="gp">$</span> python ThreadedTCPServer.py
|
|||
|
<span class="go">Server loop running in thread: Thread-1</span>
|
|||
|
<span class="go">Received: Thread-2: Hello World 1</span>
|
|||
|
<span class="go">Received: Thread-3: Hello World 2</span>
|
|||
|
<span class="go">Received: Thread-4: Hello World 3</span>
|
|||
|
</pre></div>
|
|||
|
</div>
|
|||
|
<p>The <a class="reference internal" href="#socketserver.ForkingMixIn" title="socketserver.ForkingMixIn"><code class="xref py py-class docutils literal notranslate"><span class="pre">ForkingMixIn</span></code></a> class is used in the same way, except that the server
|
|||
|
will spawn a new process for each request.
|
|||
|
Available only on POSIX platforms that support <a class="reference internal" href="os.html#os.fork" title="os.fork"><code class="xref py py-func docutils literal notranslate"><span class="pre">fork()</span></code></a>.</p>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
|
|||
|
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
|||
|
<div class="sphinxsidebarwrapper">
|
|||
|
<h3><a href="../contents.html">Table of Contents</a></h3>
|
|||
|
<ul>
|
|||
|
<li><a class="reference internal" href="#"><code class="xref py py-mod docutils literal notranslate"><span class="pre">socketserver</span></code> — A framework for network servers</a><ul>
|
|||
|
<li><a class="reference internal" href="#server-creation-notes">Server Creation Notes</a></li>
|
|||
|
<li><a class="reference internal" href="#server-objects">Server Objects</a></li>
|
|||
|
<li><a class="reference internal" href="#request-handler-objects">Request Handler Objects</a></li>
|
|||
|
<li><a class="reference internal" href="#examples">Examples</a><ul>
|
|||
|
<li><a class="reference internal" href="#socketserver-tcpserver-example"><code class="xref py py-class docutils literal notranslate"><span class="pre">socketserver.TCPServer</span></code> Example</a></li>
|
|||
|
<li><a class="reference internal" href="#socketserver-udpserver-example"><code class="xref py py-class docutils literal notranslate"><span class="pre">socketserver.UDPServer</span></code> Example</a></li>
|
|||
|
<li><a class="reference internal" href="#asynchronous-mixins">Asynchronous Mixins</a></li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<h4>Previous topic</h4>
|
|||
|
<p class="topless"><a href="uuid.html"
|
|||
|
title="previous chapter"><code class="xref py py-mod docutils literal notranslate"><span class="pre">uuid</span></code> — UUID objects according to <strong>RFC 4122</strong></a></p>
|
|||
|
<h4>Next topic</h4>
|
|||
|
<p class="topless"><a href="http.server.html"
|
|||
|
title="next chapter"><code class="xref py py-mod docutils literal notranslate"><span class="pre">http.server</span></code> — HTTP servers</a></p>
|
|||
|
<div role="note" aria-label="source link">
|
|||
|
<h3>This Page</h3>
|
|||
|
<ul class="this-page-menu">
|
|||
|
<li><a href="../bugs.html">Report a Bug</a></li>
|
|||
|
<li>
|
|||
|
<a href="https://github.com/python/cpython/blob/3.7/Doc/library/socketserver.rst"
|
|||
|
rel="nofollow">Show Source
|
|||
|
</a>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<div class="clearer"></div>
|
|||
|
</div>
|
|||
|
<div class="related" role="navigation" aria-label="related navigation">
|
|||
|
<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="http.server.html" title="http.server — HTTP servers"
|
|||
|
>next</a> |</li>
|
|||
|
<li class="right" >
|
|||
|
<a href="uuid.html" title="uuid — UUID objects according to RFC 4122"
|
|||
|
>previous</a> |</li>
|
|||
|
<li><img src="../_static/py.png" alt=""
|
|||
|
style="vertical-align: middle; margin-top: -1px"/></li>
|
|||
|
<li><a href="https://www.python.org/">Python</a> »</li>
|
|||
|
<li>
|
|||
|
<span class="language_switcher_placeholder">en</span>
|
|||
|
<span class="version_switcher_placeholder">3.7.4</span>
|
|||
|
<a href="../index.html">Documentation </a> »
|
|||
|
</li>
|
|||
|
|
|||
|
<li class="nav-item nav-item-1"><a href="index.html" >The Python Standard Library</a> »</li>
|
|||
|
<li class="nav-item nav-item-2"><a href="internet.html" >Internet Protocols and Support</a> »</li>
|
|||
|
<li class="right">
|
|||
|
|
|||
|
|
|||
|
<div class="inline-search" style="display: none" role="search">
|
|||
|
<form class="inline-search" action="../search.html" method="get">
|
|||
|
<input placeholder="Quick search" type="text" name="q" />
|
|||
|
<input type="submit" value="Go" />
|
|||
|
<input type="hidden" name="check_keywords" value="yes" />
|
|||
|
<input type="hidden" name="area" value="default" />
|
|||
|
</form>
|
|||
|
</div>
|
|||
|
<script type="text/javascript">$('.inline-search').show(0);</script>
|
|||
|
|
|
|||
|
</li>
|
|||
|
|
|||
|
</ul>
|
|||
|
</div>
|
|||
|
<div class="footer">
|
|||
|
© <a href="../copyright.html">Copyright</a> 2001-2019, Python Software Foundation.
|
|||
|
<br />
|
|||
|
The Python Software Foundation is a non-profit corporation.
|
|||
|
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
|||
|
<br />
|
|||
|
Last updated on Jul 13, 2019.
|
|||
|
<a href="../bugs.html">Found a bug</a>?
|
|||
|
<br />
|
|||
|
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.0.1.
|
|||
|
</div>
|
|||
|
|
|||
|
</body>
|
|||
|
</html>
|