##
7.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', `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', `data`