##
7.2.3 例

以下はTCP/IPプロトコルの簡単なサンプルとして、受信したデータをクライアン トにそのまま返送するサーバ(接続可能なクライアントは一件のみ)と、サーバに 接続するクライアントの例を示します。サーバでは、`socket()`・ `bind()`・`listen()`・`accept()`を実行し(複数のクラ イアントからの接続を受け付ける場合、`accept()`を複数回呼び出しま す)、クライアントでは`socket()`と`connect()`だけを呼び出 しています。サーバでは`send()`/`recv()`メソッドはlisten中 のソケットで実行するのではなく、`accept()`で取得したソケットに対 して実行している点にも注意してください。

次のクライアントとサーバは、IPv4のみをサポートしています。

    # 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.

次のサンプルは上記のサンプルとほとんど同じですが、IPv4とIPv6の両方をサ ポートしています。サーバでは、IPv4/v6の両方ではなく、利用可能な最初のア ドレスファミリだけをlistenしています。ほとんどのIPv6対応システムではIPv6 が先に現れるため、サーバはIPv4には応答しません。クライアントでは名前解決 の結果として取得したアドレスに順次接続を試み、最初に接続に成功したソケッ トにデータを送信しています。

    # 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`