##
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', repr(data)

次のサンプルは上記のサンプルとほとんど同じですが、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', repr(data)

次の例ではSSLサーバに接続し、サーバおよび発行者の識別名(distinguished name) を表示し、いくらかのバイトを送り、レスポンスの一部を読みます:

    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()

執筆時点で、このSSL実行例は次のような出力を表示しました (読み易いように改行は入れてあります):

    '/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'