<!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>TCP/IP Client and Server — 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="socket – Network Communication" href="index.html" /> <link rel="next" title="User Datagram Client and Server" href="udp.html" /> <link rel="prev" title="Addressing, Protocol Families and Socket Types" href="addressing.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="udp.html" title="User Datagram Client and Server" accesskey="N">next</a> |</li> <li class="right" > <a href="addressing.html" title="Addressing, Protocol Families and Socket Types" accesskey="P">previous</a> |</li> <li><a href="../contents.html">PyMOTW</a> »</li> <li><a href="../internet_protocols.html" >Internet Protocols and Support</a> »</li> <li><a href="index.html" accesskey="U">socket – Network Communication</a> »</li> </ul> </div> <div class="sphinxsidebar"> <div class="sphinxsidebarwrapper"> <h3><a href="../contents.html">Table Of Contents</a></h3> <ul> <li><a class="reference internal" href="#">TCP/IP Client and Server</a><ul> <li><a class="reference internal" href="#echo-server">Echo Server</a></li> <li><a class="reference internal" href="#echo-client">Echo Client</a></li> <li><a class="reference internal" href="#client-and-server-together">Client and Server Together</a></li> <li><a class="reference internal" href="#easy-client-connections">Easy Client Connections</a></li> <li><a class="reference internal" href="#choosing-an-address-for-listening">Choosing an Address for Listening</a></li> </ul> </li> </ul> <h4>Previous topic</h4> <p class="topless"><a href="addressing.html" title="previous chapter">Addressing, Protocol Families and Socket Types</a></p> <h4>Next topic</h4> <p class="topless"><a href="udp.html" title="next chapter">User Datagram Client and Server</a></p> <h3>This Page</h3> <ul class="this-page-menu"> <li><a href="../_sources/socket/tcp.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="tcp-ip-client-and-server"> <h1>TCP/IP Client and Server<a class="headerlink" href="#tcp-ip-client-and-server" title="Permalink to this headline">¶</a></h1> <p>Sockets can be configured to act as a <em>server</em> and listen for incoming messages, or connect to other applications as a <em>client</em>. After both ends of a TCP/IP socket are connected, communication is bi-directional.</p> <div class="section" id="echo-server"> <h2>Echo Server<a class="headerlink" href="#echo-server" title="Permalink to this headline">¶</a></h2> <p>This sample program, based on the one in the standard library documentation, receives incoming messages and echos them back to the sender. It starts by creating a TCP/IP socket.</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="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> </pre></div> </div> <p>Then <tt class="xref py py-func docutils literal"><span class="pre">bind()</span></tt> is used to associate the socket with the server address. In this case, the address is <tt class="docutils literal"><span class="pre">localhost</span></tt>, referring to the current server, and the port number is 10000.</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># Bind the socket to the port</span> <span class="n">server_address</span> <span class="o">=</span> <span class="p">(</span><span class="s">'localhost'</span><span class="p">,</span> <span class="mi">10000</span><span class="p">)</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'starting up on </span><span class="si">%s</span><span class="s"> port </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="n">server_address</span> <span class="n">sock</span><span class="o">.</span><span class="n">bind</span><span class="p">(</span><span class="n">server_address</span><span class="p">)</span> </pre></div> </div> <p>Calling <tt class="xref py py-func docutils literal"><span class="pre">listen()</span></tt> puts the socket into server mode, and <tt class="xref py py-func docutils literal"><span class="pre">accept()</span></tt> waits for an incoming connection.</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># Listen for incoming connections</span> <span class="n">sock</span><span class="o">.</span><span class="n">listen</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">while</span> <span class="bp">True</span><span class="p">:</span> <span class="c"># Wait for a connection</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'waiting for 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">sock</span><span class="o">.</span><span class="n">accept</span><span class="p">()</span> </pre></div> </div> <p><tt class="xref py py-func docutils literal"><span class="pre">accept()</span></tt> returns an open connection between the server and client, along with the address of the client. The connection is actually a different socket on another port (assigned by the kernel). Data is read from the connection with <tt class="xref py py-func docutils literal"><span class="pre">recv()</span></tt> and transmitted with <tt class="xref py py-func docutils literal"><span class="pre">sendall()</span></tt>.</p> <div class="highlight-python"><div class="highlight"><pre> <span class="k">try</span><span class="p">:</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'connection from'</span><span class="p">,</span> <span class="n">client_address</span> <span class="c"># Receive the data in small chunks and retransmit it</span> <span class="k">while</span> <span class="bp">True</span><span class="p">:</span> <span class="n">data</span> <span class="o">=</span> <span class="n">connection</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="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'received "</span><span class="si">%s</span><span class="s">"'</span> <span class="o">%</span> <span class="n">data</span> <span class="k">if</span> <span class="n">data</span><span class="p">:</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'sending data back to the client'</span> <span class="n">connection</span><span class="o">.</span><span class="n">sendall</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'no more data from'</span><span class="p">,</span> <span class="n">client_address</span> <span class="k">break</span> <span class="k">finally</span><span class="p">:</span> <span class="c"># Clean up the connection</span> <span class="n">connection</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> </pre></div> </div> <p>When communication with a client is finished, the connection needs to be cleaned up using <tt class="xref py py-func docutils literal"><span class="pre">close()</span></tt>. This example uses a <tt class="docutils literal"><span class="pre">try:finally</span></tt> block to ensure that <tt class="xref py py-func docutils literal"><span class="pre">close()</span></tt> is always called, even in the event of an error.</p> </div> <div class="section" id="echo-client"> <h2>Echo Client<a class="headerlink" href="#echo-client" title="Permalink to this headline">¶</a></h2> <p>The client program sets up its <a class="reference internal" href="index.html#module-socket" title="socket: Network communication"><tt class="xref py py-class docutils literal"><span class="pre">socket</span></tt></a> differently from the way a server does. Instead of binding to a port and listening, it uses <tt class="xref py py-func docutils literal"><span class="pre">connect()</span></tt> to attach the socket directly to the remote address.</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="c"># Create a TCP/IP socket</span> <span class="n">sock</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">)</span> <span class="c"># Connect the socket to the port where the server is listening</span> <span class="n">server_address</span> <span class="o">=</span> <span class="p">(</span><span class="s">'localhost'</span><span class="p">,</span> <span class="mi">10000</span><span class="p">)</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'connecting to </span><span class="si">%s</span><span class="s"> port </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="n">server_address</span> <span class="n">sock</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">server_address</span><span class="p">)</span> </pre></div> </div> <p>After the connection is established, data can be sent through the <a class="reference internal" href="index.html#module-socket" title="socket: Network communication"><tt class="xref py py-class docutils literal"><span class="pre">socket</span></tt></a> with <tt class="xref py py-func docutils literal"><span class="pre">sendall()</span></tt> and received with <tt class="xref py py-func docutils literal"><span class="pre">recv()</span></tt>, just as in the server.</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">try</span><span class="p">:</span> <span class="c"># Send data</span> <span class="n">message</span> <span class="o">=</span> <span class="s">'This is the message. It will be repeated.'</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'sending "</span><span class="si">%s</span><span class="s">"'</span> <span class="o">%</span> <span class="n">message</span> <span class="n">sock</span><span class="o">.</span><span class="n">sendall</span><span class="p">(</span><span class="n">message</span><span class="p">)</span> <span class="c"># Look for the response</span> <span class="n">amount_received</span> <span class="o">=</span> <span class="mi">0</span> <span class="n">amount_expected</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="p">)</span> <span class="k">while</span> <span class="n">amount_received</span> <span class="o"><</span> <span class="n">amount_expected</span><span class="p">:</span> <span class="n">data</span> <span class="o">=</span> <span class="n">sock</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">16</span><span class="p">)</span> <span class="n">amount_received</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'received "</span><span class="si">%s</span><span class="s">"'</span> <span class="o">%</span> <span class="n">data</span> <span class="k">finally</span><span class="p">:</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'closing socket'</span> <span class="n">sock</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> </pre></div> </div> <p>When the entire message is sent and a copy received, the socket is closed to free up the port.</p> </div> <div class="section" id="client-and-server-together"> <h2>Client and Server Together<a class="headerlink" href="#client-and-server-together" title="Permalink to this headline">¶</a></h2> <p>The client and server should be run in separate terminal windows, so they can communicate with each other. The server output is:</p> <div class="highlight-python"><pre>$ python ./socket_echo_server.py starting up on localhost port 10000 waiting for a connection connection from ('127.0.0.1', 52186) received "This is the mess" sending data back to the client received "age. It will be" sending data back to the client received " repeated." sending data back to the client received "" no more data from ('127.0.0.1', 52186) waiting for a connection</pre> </div> <p>The client output is:</p> <div class="highlight-python"><pre>$ python socket_echo_client.py connecting to localhost port 10000 sending "This is the message. It will be repeated." received "This is the mess" received "age. It will be" received " repeated." closing socket $</pre> </div> </div> <div class="section" id="easy-client-connections"> <h2>Easy Client Connections<a class="headerlink" href="#easy-client-connections" title="Permalink to this headline">¶</a></h2> <p>TCP/IP clients can save a few steps by using the convenience function <tt class="xref py py-func docutils literal"><span class="pre">create_connection()</span></tt> to connect to a server. The function takes one argument, a two-value tuple containing the address of the server, and derives the best address to use for the connection.</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="k">def</span> <span class="nf">get_constants</span><span class="p">(</span><span class="n">prefix</span><span class="p">):</span> <span class="sd">"""Create a dictionary mapping socket module constants to their names."""</span> <span class="k">return</span> <span class="nb">dict</span><span class="p">(</span> <span class="p">(</span><span class="nb">getattr</span><span class="p">(</span><span class="n">socket</span><span class="p">,</span> <span class="n">n</span><span class="p">),</span> <span class="n">n</span><span class="p">)</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">dir</span><span class="p">(</span><span class="n">socket</span><span class="p">)</span> <span class="k">if</span> <span class="n">n</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">prefix</span><span class="p">)</span> <span class="p">)</span> <span class="n">families</span> <span class="o">=</span> <span class="n">get_constants</span><span class="p">(</span><span class="s">'AF_'</span><span class="p">)</span> <span class="n">types</span> <span class="o">=</span> <span class="n">get_constants</span><span class="p">(</span><span class="s">'SOCK_'</span><span class="p">)</span> <span class="n">protocols</span> <span class="o">=</span> <span class="n">get_constants</span><span class="p">(</span><span class="s">'IPPROTO_'</span><span class="p">)</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">create_connection</span><span class="p">((</span><span class="s">'localhost'</span><span class="p">,</span> <span class="mi">10000</span><span class="p">))</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'Family :'</span><span class="p">,</span> <span class="n">families</span><span class="p">[</span><span class="n">sock</span><span class="o">.</span><span class="n">family</span><span class="p">]</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'Type :'</span><span class="p">,</span> <span class="n">types</span><span class="p">[</span><span class="n">sock</span><span class="o">.</span><span class="n">type</span><span class="p">]</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'Protocol:'</span><span class="p">,</span> <span class="n">protocols</span><span class="p">[</span><span class="n">sock</span><span class="o">.</span><span class="n">proto</span><span class="p">]</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span> <span class="k">try</span><span class="p">:</span> <span class="c"># Send data</span> <span class="n">message</span> <span class="o">=</span> <span class="s">'This is the message. It will be repeated.'</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'sending "</span><span class="si">%s</span><span class="s">"'</span> <span class="o">%</span> <span class="n">message</span> <span class="n">sock</span><span class="o">.</span><span class="n">sendall</span><span class="p">(</span><span class="n">message</span><span class="p">)</span> <span class="n">amount_received</span> <span class="o">=</span> <span class="mi">0</span> <span class="n">amount_expected</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="p">)</span> <span class="k">while</span> <span class="n">amount_received</span> <span class="o"><</span> <span class="n">amount_expected</span><span class="p">:</span> <span class="n">data</span> <span class="o">=</span> <span class="n">sock</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">16</span><span class="p">)</span> <span class="n">amount_received</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'received "</span><span class="si">%s</span><span class="s">"'</span> <span class="o">%</span> <span class="n">data</span> <span class="k">finally</span><span class="p">:</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'closing socket'</span> <span class="n">sock</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> </pre></div> </div> <p><tt class="xref py py-func docutils literal"><span class="pre">create_connection()</span></tt> uses <tt class="xref py py-func docutils literal"><span class="pre">getaddrinfo()</span></tt> to find candidate connection parameters, and returns a <a class="reference internal" href="index.html#module-socket" title="socket: Network communication"><tt class="xref py py-class docutils literal"><span class="pre">socket</span></tt></a> opened with the first configuration that creates a successful connection. The <tt class="xref py py-attr docutils literal"><span class="pre">family</span></tt>, <tt class="xref py py-attr docutils literal"><span class="pre">type</span></tt>, and <tt class="xref py py-attr docutils literal"><span class="pre">proto</span></tt> attributes can be examined to determine the type of <a class="reference internal" href="index.html#module-socket" title="socket: Network communication"><tt class="xref py py-class docutils literal"><span class="pre">socket</span></tt></a> being returned.</p> <div class="highlight-python"><pre>$ python socket_echo_client_easy.py Family : AF_INET Type : SOCK_STREAM Protocol: IPPROTO_TCP sending "This is the message. It will be repeated." received "This is the mess" received "age. It will be" received " repeated." closing socket</pre> </div> </div> <div class="section" id="choosing-an-address-for-listening"> <h2>Choosing an Address for Listening<a class="headerlink" href="#choosing-an-address-for-listening" title="Permalink to this headline">¶</a></h2> <p>It is important to bind a server to the correct address, so that clients can communicate with it. The previous examples all used <tt class="docutils literal"><span class="pre">'localhost'</span></tt> as the IP address, which limits connections to clients running on the same server. Use a public address of the server, such as the value returned by <tt class="xref py py-func docutils literal"><span class="pre">gethostname()</span></tt>, to allow other hosts to connect. This example modifies the echo server to listen on an address specified via a command line argument.</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="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"># Bind the socket to the address given on the command line</span> <span class="n">server_name</span> <span class="o">=</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="n">server_address</span> <span class="o">=</span> <span class="p">(</span><span class="n">server_name</span><span class="p">,</span> <span class="mi">10000</span><span class="p">)</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'starting up on </span><span class="si">%s</span><span class="s"> port </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="n">server_address</span> <span class="n">sock</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="n">sock</span><span class="o">.</span><span class="n">listen</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">while</span> <span class="bp">True</span><span class="p">:</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'waiting for 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">sock</span><span class="o">.</span><span class="n">accept</span><span class="p">()</span> <span class="k">try</span><span class="p">:</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'client connected:'</span><span class="p">,</span> <span class="n">client_address</span> <span class="k">while</span> <span class="bp">True</span><span class="p">:</span> <span class="n">data</span> <span class="o">=</span> <span class="n">connection</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="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'received "</span><span class="si">%s</span><span class="s">"'</span> <span class="o">%</span> <span class="n">data</span> <span class="k">if</span> <span class="n">data</span><span class="p">:</span> <span class="n">connection</span><span class="o">.</span><span class="n">sendall</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="k">break</span> <span class="k">finally</span><span class="p">:</span> <span class="n">connection</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> </pre></div> </div> <p>A similar modification to the client program is needed before the server can be tested.</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="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 on the server given by the caller</span> <span class="n">server_address</span> <span class="o">=</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="mi">10000</span><span class="p">)</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'connecting to </span><span class="si">%s</span><span class="s"> port </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="n">server_address</span> <span class="n">sock</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">server_address</span><span class="p">)</span> <span class="k">try</span><span class="p">:</span> <span class="n">message</span> <span class="o">=</span> <span class="s">'This is the message. It will be repeated.'</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'sending "</span><span class="si">%s</span><span class="s">"'</span> <span class="o">%</span> <span class="n">message</span> <span class="n">sock</span><span class="o">.</span><span class="n">sendall</span><span class="p">(</span><span class="n">message</span><span class="p">)</span> <span class="n">amount_received</span> <span class="o">=</span> <span class="mi">0</span> <span class="n">amount_expected</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">message</span><span class="p">)</span> <span class="k">while</span> <span class="n">amount_received</span> <span class="o"><</span> <span class="n">amount_expected</span><span class="p">:</span> <span class="n">data</span> <span class="o">=</span> <span class="n">sock</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">16</span><span class="p">)</span> <span class="n">amount_received</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'received "</span><span class="si">%s</span><span class="s">"'</span> <span class="o">%</span> <span class="n">data</span> <span class="k">finally</span><span class="p">:</span> <span class="n">sock</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> </pre></div> </div> <p>After starting the server with the argument <tt class="docutils literal"><span class="pre">farnsworth.hellfly.net</span></tt>, the <strong class="command">netstat</strong> command shows it listening on the address for the named host.</p> <div class="highlight-python"><pre>$ host farnsworth.hellfly.net farnsworth.hellfly.net has address 192.168.1.17 $ netstat -an Active Internet connections (including servers) Proto Recv-Q Send-Q Local Address Foreign Address (state) ... tcp4 0 0 192.168.1.17.10000 *.* LISTEN ...</pre> </div> <p>Running the the client on another host, passing <tt class="docutils literal"><span class="pre">farnsworth.hellfly.net</span></tt> as the host where the server is running, produces:</p> <div class="highlight-python"><pre>$ hostname homer $ python socket_echo_client_explicit.py farnsworth.hellfly.net connecting to farnsworth.hellfly.net port 10000 sending "This is the message. It will be repeated." received "This is the mess" received "age. It will be" received " repeated."</pre> </div> <p>And the server output is:</p> <div class="highlight-python"><pre>$ python ./socket_echo_server_explicit.py farnsworth.hellfly.net starting up on farnsworth.hellfly.net port 10000 waiting for a connection client connected: ('192.168.1.8', 57471) received "This is the mess" received "age. It will be" received " repeated." received "" waiting for a connection</pre> </div> <p>Many servers have more than one network interface, and therefore more than one IP address. Rather than running separate copies of a service bound to each IP address, use the special address <tt class="xref py py-const docutils literal"><span class="pre">INADDR_ANY</span></tt> to listen on all addresses at the same time. Although <a class="reference internal" href="index.html#module-socket" title="socket: Network communication"><tt class="xref py py-mod docutils literal"><span class="pre">socket</span></tt></a> defines a constant for <tt class="xref py py-const docutils literal"><span class="pre">INADDR_ANY</span></tt>, it is an integer value and must be converted to a dotted-notation string address before it can be passed to <tt class="xref py py-func docutils literal"><span class="pre">bind()</span></tt>. As a shortcut, use the empty string <tt class="docutils literal"><span class="pre">''</span></tt> instead of doing the conversion.</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="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"># Bind the socket to the address given on the command line</span> <span class="n">server_address</span> <span class="o">=</span> <span class="p">(</span><span class="s">''</span><span class="p">,</span> <span class="mi">10000</span><span class="p">)</span> <span class="n">sock</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="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'starting up on </span><span class="si">%s</span><span class="s"> port </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="n">sock</span><span class="o">.</span><span class="n">getsockname</span><span class="p">()</span> <span class="n">sock</span><span class="o">.</span><span class="n">listen</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">while</span> <span class="bp">True</span><span class="p">:</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'waiting for 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">sock</span><span class="o">.</span><span class="n">accept</span><span class="p">()</span> <span class="k">try</span><span class="p">:</span> <span class="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'client connected:'</span><span class="p">,</span> <span class="n">client_address</span> <span class="k">while</span> <span class="bp">True</span><span class="p">:</span> <span class="n">data</span> <span class="o">=</span> <span class="n">connection</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="k">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="s">'received "</span><span class="si">%s</span><span class="s">"'</span> <span class="o">%</span> <span class="n">data</span> <span class="k">if</span> <span class="n">data</span><span class="p">:</span> <span class="n">connection</span><span class="o">.</span><span class="n">sendall</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="k">break</span> <span class="k">finally</span><span class="p">:</span> <span class="n">connection</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> </pre></div> </div> <p>To see the actual address being used by a socket, call its <tt class="xref py py-func docutils literal"><span class="pre">getsockname()</span></tt> method. After starting the service, running <strong class="command">netstat</strong> again shows it listening for incoming connections on any address.</p> <div class="highlight-python"><pre>$ netstat -an Active Internet connections (including servers) Proto Recv-Q Send-Q Local Address Foreign Address (state) ... tcp4 0 0 *.10000 *.* LISTEN ...</pre> </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="udp.html" title="User Datagram Client and Server" >next</a> |</li> <li class="right" > <a href="addressing.html" title="Addressing, Protocol Families and Socket Types" >previous</a> |</li> <li><a href="../contents.html">PyMOTW</a> »</li> <li><a href="../internet_protocols.html" >Internet Protocols and Support</a> »</li> <li><a href="index.html" >socket – Network Communication</a> »</li> </ul> </div> <div class="footer"> © Copyright Doug Hellmann. Last updated on Oct 24, 2010. Created using <a href="http://sphinx.pocoo.org/">Sphinx</a>. <br/><a href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/" rel="license"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/88x31.png"/></a> </div> </body> </html>