Python ネットワークプログラミング

Python は2つのレベルでアクセスできるネットワークサービスを提供します:

  • 低レベルのネットワークサービスは基本的な Socket をサポートしており、標準の BSD Sockets API を提供し、基盤となるオペレーティングシステムの Socket インターフェースのすべてのメソッドにアクセスできます。
  • 高レベルのネットワークサービスモジュール SocketServer は、サーバー中心のクラスを提供し、ネットワークサーバーの開発を簡素化できます。

Socket とは?

Socket は「套接字(ソケット)」とも呼ばれ、アプリケーションは通常「ソケット」を通じてネットワークにリクエストを送信したり、ネットワークリクエストに応答したりして、ホスト間または1台のコンピュータ上のプロセス間で通信できるようにします。


socket() 関数

Python では、socket() 関数を使用してソケットを作成します。構文は次のとおりです:

socket.socket([family[, type[, proto]]])

パラメータ

  • family: ソケットファミリは AF_UNIX または AF_INET を使用できます。
  • type: ソケットタイプは、コネクション型かコネクションレス型かによって分類できます:SOCK_STREAM 或 SOCK_DGRAM。
  • protocol: 通常は未入力でデフォルトは 0 です。

Socket オブジェクト(組み込み)メソッド

関数 説明
サーバー側ソケット
s.bind() アドレス(host, port)をソケットにバインドする。AF_INET では、アドレスはタプル(host, port)の形式で表される。
s.listen() TCP リッスンを開始する。backlog は、接続を拒否する前にオペレーティングシステムが保留できる最大接続数を指定する。この値は少なくとも 1 である必要があり、ほとんどのアプリケーションでは 5 に設定すれば十分である。
s.accept() TCP クライアント接続をパッシブに受け入れ、(ブロッキング方式で)接続の到着を待つ。
クライアント側ソケット
s.connect() TCP サーバー接続をアクティブに初期化する。通常、address の形式はタプル(hostname, port)である。接続エラーが発生した場合は、socket.error エラーを返す。
s.connect_ex() connect() 関数の拡張バージョンで、エラー時には例外をスローする代わりにエラーコードを返す。
共通用途のソケット関数
s.recv() TCP データを受信し、データは文字列形式で返される。bufsize は受信する最大データ量を指定する。flag はメッセージに関するその他の情報を提供するが、通常は無視できる。
s.send() TCP データを送信し、string 内のデータを接続されたソケットに送信する。戻り値は送信されたバイト数で、この数値は string のバイトサイズより小さくなる場合がある。
s.sendall() TCP データを完全に送信する。string 内のデータを接続されたソケットに送信するが、返る前にすべてのデータを送信しようとする。成功した場合は None を返し、失敗した場合は例外をスローする。
s.recvfrom() UDP データを受信する。recv() と似ているが、戻り値は(data, address)である。data は受信データを含む文字列で、address はデータを送信したソケットアドレスである。
s.sendto() UDP データを送信し、データをソケットに送信する。address は(ipaddr, port)形式のタプルで、リモートアドレスを指定する。戻り値は送信されたバイト数である。
s.close() ソケットを閉じる。
s.getpeername() 接続されたソケットのリモートアドレスを返す。戻り値は通常タプル(ipaddr, port)である。
s.getsockname() ソケット自身のアドレスを返す。通常はタプル(ipaddr, port)である。
s.setsockopt(level,optname,value) 指定されたソケットオプションの値を設定する。
s.getsockopt(level,optname[.buflen]) ソケットオプションの値を返す。
s.settimeout(timeout) ソケット操作のタイムアウト期間を設定する。timeout は浮動小数点数で、単位は秒である。値が None の場合はタイムアウト期間がないことを意味する。一般に、タイムアウト期間はソケットを作成した直後に設定する必要がある。接続操作(connect() など)に使用される可能性があるためである。
s.gettimeout() 現在のタイムアウト期間の値を返す。単位は秒である。タイムアウト期間が設定されていない場合は None を返す。
s.fileno() ソケットのファイルディスクリプタを返す。
s.setblocking(flag) flag が 0 の場合はソケットを非ブロッキングモードに設定し、それ以外の場合はソケットをブロッキングモード(デフォルト)に設定する。非ブロッキングモードでは、recv() 呼び出しでデータが見つからない場合、または send() 呼び出しでデータをすぐに送信できない場合、socket.error 例外が発生する。
s.makefile() このソケットに関連付けられたファイルを作成する。

簡単なインスタンス

サーバー側

socket モジュールのsocket関数を使用して socket オブジェクトを作成します。socket オブジェクトは他の関数を呼び出して socket サービスを設定できます。

ここで、bind(hostname, port)関数を呼び出してサービスのport(ポート)を指定できます。。

次に、socket オブジェクトのacceptメソッドを呼び出します。このメソッドはクライアントの接続を待機し、connectionオブジェクトを返します。これはクライアントに接続されたことを示します。

完全なコードは次のとおりです:

インスタンス

#!/usr/bin/python # -*- coding: UTF-8 -*- # ファイル名:server.py import socket # socket モジュールをインポート s = socket.socket() # socket オブジェクトを作成 host = socket.gethostname() # ローカルホスト名を取得 port = 12345 # ポートを設定 s.bind((host, port)) # ポートをバインド s.listen(5) # クライアントの接続を待機 while True: c,addr = s.accept() # クライアント接続を確立 print '接続アドレス:', addr c.send('サンプルへようこそ!') c.close() # 接続を閉じる

クライアント側

次に、上記で作成したサービスに接続する簡単なクライアントインスタンスを作成します。ポート番号は 12345 です。

socket.connect(hostname, port )メソッドで、ホストがhostnameポートがportのサーバーへの TCP 接続を開きます。接続後、サーバー側からデータを取得できます。操作が完了したら接続を閉じる必要があることを忘れないでください。

完全なコードは次のとおりです:

インスタンス

#!/usr/bin/python # -*- coding: UTF-8 -*- # ファイル名:client.py import socket # socket モジュールをインポート s = socket.socket() # socket オブジェクトを作成 host = socket.gethostname() # ローカルホスト名を取得 port = 12345 # ポート番号を設定 s.connect((host, port)) print s.recv(1024) s.close()

ここで2つのターミナルを開き、最初のターミナルで server.py ファイルを実行します:

$ python server.py

2番目のターミナルで client.py ファイルを実行します:

$ python client.py 
欢迎访问サンプル!

このとき、最初のターミナルをもう一度開くと、次の情報が出力されているのがわかります:

连接地址: ('192.168.0.118', 62461)

Python Internet モジュール

以下に、Python ネットワークプログラミングの重要なモジュールをいくつか示します:

プロトコル機能・用途ポート番号Python モジュール
HTTPウェブページアクセス80httplib, urllib, xmlrpclib
NNTPニュース記事の閲覧と投稿。通称「ポスト」と呼ばれます。119nntplib
FTPファイル転送20ftplib, urllib
SMTPメール送信25smtplib
POP3メール受信110poplib
IMAP4メール取得143imaplib
Telnetコマンドライン23telnetlib
Gopher情報検索70gopherlib, urllib

詳細については、公式サイトのPython Socket Library and Modules。

その他の拡張