Python3 ネットワークプログラミング
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 - proto: 通常は入力せず、デフォルトは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がFalseの場合はソケットを非ブロッキングモードに設定し、それ以外の場合はソケットをブロッキングモード(デフォルト)に設定します。非ブロッキングモードでは、recv()を呼び出してもデータが見つからない場合、またはsend()呼び出しがすぐにデータを送信できない場合、socket.error例外が発生します。 |
| s.makefile() | このソケットに関連付けられたファイルを作成します |
簡単な例
サーバー側
socketモジュールのsocket関数を使用してsocketオブジェクトを作成します。socketオブジェクトは他の関数を呼び出してsocketサービスを設定できます。
次に、呼び出すことでbind(hostname, port)関数を呼び出してサービスのport(ポート)を指定します。
次に、socketオブジェクトのacceptメソッドを呼び出します。このメソッドはクライアントの接続を待機し、connectionオブジェクトを返します。これはクライアントに接続されたことを示します。
完全なコードは以下のとおりです:
例
# ファイル名:server.py
# socket、sysモジュールをインポート
import socket
import sys
# socketオブジェクトを作成
serversocket = socket.socket(
socket.AF_INET, socket.SOCK_STREAM)
# ローカルホスト名を取得
host = socket.gethostname()
port = 9999
# ポート番号をバインド
serversocket.bind((host, port))
# 最大接続数を設定、超過した場合はキューに並ぶ
serversocket.listen(5)
while True:
# クライアント接続を確立
clientsocket,addr = serversocket.accept()
print("接続アドレス: %s" % str(addr))
msg='サンプルへようこそ!'+ "\r\n"
clientsocket.send(msg.encode('utf-8'))
clientsocket.close()
クライアント側
次に、上記で作成したサービスに接続する簡単なクライアントの例を作成します。ポート番号は9999です。
socket.connect(hostname, port )メソッドは、ホストがhostnameポートがportのサービスへのTCP接続を開きます。接続後、サーバー側からデータを取得できます。操作完了後は接続を閉じる必要があることを覚えておいてください。
完全なコードは以下のとおりです:
例
# ファイル名:client.py
# socket、sysモジュールをインポート
import socket
import sys
# socketオブジェクトを作成
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# ローカルホスト名を取得
host = socket.gethostname()
# ポート番号を設定
port = 9999
# サービスに接続、ホストとポートを指定
s.connect((host, port))
# 1024バイト未満のデータを受信
msg = s.recv(1024)
s.close()
print (msg.decode('utf-8'))
次に2つのターミナルを開き、最初のターミナルでserver.pyファイルを実行します:
$ python3 server.py
2番目のターミナルでclient.pyファイルを実行します:
$ python3 client.py 欢迎访问サンプル!
このとき、最初のターミナルをもう一度開くと、次の情報が出力されているのがわかります:
连接地址: ('192.168.0.118', 33397)
Python Internet モジュール
以下に、Pythonネットワークプログラミングの重要なモジュールをいくつか示します:
| プロトコル | 機能・用途 | ポート番号 | Python モジュール |
|---|---|---|---|
| HTTP | Webページアクセス | 80 | httplib, urllib, xmlrpclib |
| NNTP | ニュース記事の閲覧と投稿。通称「ポスト」と呼ばれます | 119 | nntplib |
| FTP | ファイル転送 | 20 | ftplib, urllib |
| SMTP | メール送信 | 25 | smtplib |
| POP3 | メール受信 | 110 | poplib |
| IMAP4 | メール取得 | 143 | imaplib |
| Telnet | コマンドライン | 23 | telnetlib |
| Gopher | 情報検索 | 70 | gopherlib, urllib |
詳細は公式サイトのPython Socket Library and Modules。
その他の拡張機能を参照してください