17.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', 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'
ご意見やご指摘をお寄せになりたい方は、 このドキュメントについて... をご覧ください。