##
17.2.3 Example

Here are four minimal example programs using the TCP/IP protocol: a server that echoes all data that it receives back (servicing only one client), and a client using it. Note that a server must perform the sequence `socket()`, `bind()`, `listen()`, `accept()` (possibly repeating the `accept()` to service more than one client), while a client only needs the sequence `socket()`, `connect()`. Also note that the server does not `send()`/`recv()` on the socket it is listening on but on the new socket returned by `accept()`.

The first two examples support IPv4 only.

    # Echo server program
    import socket

    HOST = ''                 # Symbolic name meaning the local host
    PORT = 50007              # Arbitrary non-privileged port
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((HOST, PORT))
    s.listen(1)
    conn, addr = s.accept()
    print 'Connected by', addr
    while 1:
        data = conn.recv(1024)
        if not data: break
        conn.send(data)
    conn.close()

    # Echo client program
    import socket

    HOST = 'daring.cwi.nl'    # The remote host
    PORT = 50007              # The same port as used by the server
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((HOST, PORT))
    s.send('Hello, world')
    data = s.recv(1024)
    s.close()
    print 'Received', repr(data)

The next two examples are identical to the above two, but support both IPv4 and IPv6. The server side will listen to the first address family available (it should listen to both instead). On most of IPv6-ready systems, IPv6 will take precedence and the server may not accept IPv4 traffic. The client side will try to connect to the all addresses returned as a result of the name resolution, and sends traffic to the first one connected successfully.

    # Echo server program
    import socket
    import sys

    HOST = ''                 # Symbolic name meaning the local host
    PORT = 50007              # Arbitrary non-privileged port
    s = None
    for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
        af, socktype, proto, canonname, sa = res
        try:
    	s = socket.socket(af, socktype, proto)
        except socket.error, msg:
    	s = None
    	continue
        try:
    	s.bind(sa)
    	s.listen(1)
        except socket.error, msg:
    	s.close()
    	s = None
    	continue
        break
    if s is None:
        print 'could not open socket'
        sys.exit(1)
    conn, addr = s.accept()
    print 'Connected by', addr
    while 1:
        data = conn.recv(1024)
        if not data: break
        conn.send(data)
    conn.close()

    # Echo client program
    import socket
    import sys

    HOST = 'daring.cwi.nl'    # The remote host
    PORT = 50007              # The same port as used by the server
    s = None
    for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_STREAM):
        af, socktype, proto, canonname, sa = res
        try:
    	s = socket.socket(af, socktype, proto)
        except socket.error, msg:
    	s = None
    	continue
        try:
    	s.connect(sa)
        except socket.error, msg:
    	s.close()
    	s = None
    	continue
        break
    if s is None:
        print 'could not open socket'
        sys.exit(1)
    s.send('Hello, world')
    data = s.recv(1024)
    s.close()
    print 'Received', repr(data)

This example connects to an SSL server, prints the server and issuer's distinguished names, sends some bytes, and reads part of the response:

    import socket

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('www.verisign.com', 443))

    ssl_sock = socket.ssl(s)

    print repr(ssl_sock.server())
    print repr(ssl_sock.issuer())

    # Set a simple HTTP request -- use httplib in actual code.
    ssl_sock.write("""GET / HTTP/1.0\r
    Host: www.verisign.com\r\n\r\n""")

    # Read a chunk of data.  Will not necessarily
    # read all the data returned by the server.
    data = ssl_sock.read()

    # Note that you need to close the underlying socket, not the SSL object.
    del ssl_sock
    s.close()

At this writing, this SSL example prints the following output (line breaks inserted for readability):

    '/C=US/ST=California/L=Mountain View/
     O=VeriSign, Inc./OU=Production Services/
     OU=Terms of use at www.verisign.com/rpa (c)00/
     CN=www.verisign.com'
    '/O=VeriSign Trust Network/OU=VeriSign, Inc./
     OU=VeriSign International Server CA - Class 3/
     OU=www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign'