socket --- socket モジュール

このモジュールは BSD ソケットインターフェイスへのアクセスを提供します。

CPython との違い

効率性と一貫性のため、MicroPython のソケットオブジェクトは stream(ファイルライク)インターフェイスを直接実装しています。CPython では、makefile() メソッドを使用してソケットをファイルライクオブジェクトに変換する必要があります。このメソッドは MicroPython でも引き続きサポートされています(ただし何も行いません)ので、CPython との互換性が重要な場合は必ず使用してください。

ソケットアドレス形式

socket モジュールのネイティブなソケットアドレス形式は、getaddrinfo() 関数によって返される不透明なデータ型です。テキスト形式のアドレス(数値アドレスを含む)を解決するには、この関数を使用する必要があります:

sockaddr = socket.getaddrinfo('www.micropython.org', 80)[0][-1]
# You must use getaddrinfo() even for numeric addresses
sockaddr = socket.getaddrinfo('127.0.0.1', 80)[0][-1]
# Now you can use that address
sock.connect(sockaddr)

getaddrinfo() の使用は、(メモリと処理能力の両面で)最も効率的かつ移植性の高いアドレスの扱い方です。

socket モジュールは、以下で説明するように、タプルを使ってアドレスを指定する CPython 互換の方法も提供します。OpenMV Cam では socket モジュールは組み込みです。数値アドレスはタプル形式で直接指定できますが、ドメイン名はまず getaddrinfo() で解決する必要があります。

まとめると:

  • ホスト名を解決するには、常に getaddrinfo() を使用してください。

  • 以下で説明するタプルアドレスは、数値アドレスのショートカットとして、簡単なちょっとした処理や対話的な使用に利用できます。

socket モジュールのタプルアドレス形式:

  • IPv4: (ipv4_address, port)。ここで ipv4_address はドット表記の数値 IPv4 アドレスの文字列(例: "8.8.8.8")であり、port は 1~65535 の範囲の整数ポート番号です。ドメイン名は ipv4_address として受け付けられません。まず getaddrinfo() を使用して解決してください。

  • IPv6: (ipv6_address, port, flowinfo, scopeid)。ここで ipv6_address はコロン表記の数値 IPv6 アドレスの文字列(例: "2001:db8::1")であり、port は 1~65535 の範囲の整数ポート番号です。flowinfo は 0 でなければなりません。scopeid はリンクローカルアドレスのインターフェイススコープ識別子です。ドメイン名は ipv6_address として受け付けられません。まず getaddrinfo() を使用して解決してください。

関数

socket.getaddrinfo(host: str, port: int, af: int = 0, type: int = 0, proto: int = 0, flags: int = 0, /) List[Tuple]

ホスト/ポート引数を、そのサービスに接続するソケットを作成するために必要なすべての引数を含む 5 要素タプルのシーケンスに変換します。引数 aftypeprotosocket 関数と同じ意味を持ちます)は、返されるアドレスの種類をフィルタリングするために使用できます。パラメータが指定されないか 0 の場合、アドレスのすべての組み合わせが返される可能性があります(ユーザー側でのフィルタリングが必要になります)。

結果として得られる 5 要素タプルのリストは、次の構造を持ちます:

(family, type, proto, canonname, sockaddr)

次の例は、指定された URL に接続する方法を示します:

s = socket.socket()
# This assumes that if "type" is not specified, an address for
# SOCK_STREAM will be returned, which may be not true
s.connect(socket.getaddrinfo('www.micropython.org', 80)[0][-1])

フィルタリングパラメータの推奨される使用方法:

s = socket.socket()
# Guaranteed to return an address which can be connect'ed to for
# stream operation.
s.connect(socket.getaddrinfo('www.micropython.org', 80, 0, SOCK_STREAM)[0][-1])

CPython との違い

この関数でエラーが発生した場合、CPython は socket.gaierror 例外(OSError のサブクラス)を発生させます。MicroPython には socket.gaierror がなく、直接 OSError を発生させます。getaddrinfo() のエラー番号は別個の名前空間を形成しており、errno モジュールのエラー番号と一致しない場合がある点に注意してください。getaddrinfo() のエラーを区別するため、それらは負の数で表され、標準的なシステムエラーは正の数で表されます(エラー番号は例外オブジェクトの e.args[0] プロパティを使用してアクセスできます)。負の値の使用は暫定的な仕様であり、将来変更される可能性があります。

socket.inet_ntop(af: int, bin_addr: bytes) str

指定されたアドレスファミリ af のバイナリネットワークアドレス bin_addr をテキスト表現に変換します:

>>> socket.inet_ntop(socket.AF_INET, b"\x7f\0\0\1")
'127.0.0.1'
socket.inet_pton(af: int, txt_addr: str) bytes

指定されたアドレスファミリ af のテキスト形式ネットワークアドレス txt_addr をバイナリ表現に変換します:

>>> socket.inet_pton(socket.AF_INET, "1.2.3.4")
b'\x01\x02\x03\x04'

定数

socket.AF_INET: int

IPv4 アドレスファミリ。

socket.AF_INET6: int

IPv6 アドレスファミリ。

socket.SOCK_STREAM: int

ストリーム(TCP)ソケットタイプ。

socket.SOCK_DGRAM: int

データグラム(UDP)ソケットタイプ。

socket.SOCK_RAW: int

Raw ソケットタイプ。

socket.IPPROTO_IP: int

IP プロトコルレベル。IP_* オプションとともに setsockopt()level 引数として使用されます。

socket.IPPROTO_TCP: int

TCP プロトコル。これを socket に渡す必要はありません(SOCK_STREAM ソケットタイプが自動的に選択します)。唯一の実際の用途は、TCP_* オプションとともに setsockopt()level 引数として使用することです。

socket.SOL_SOCKET: int

ソケットオプションレベル。SO_* オプションとともに setsockopt()level 引数として使用されます。

socket.SO_REUSEADDR: int

まだ TIME_WAIT 状態にあるアドレス/ポートへのソケットのバインドを許可します。

socket.SO_BROADCAST: int

ブロードキャストアドレスへのデータグラム送信を許可します。

socket.SO_KEEPALIVE: int

接続済みソケットでのキープアライブプローブの定期送信を有効にします。

socket.SO_SNDTIMEO: int

送信タイムアウト(ミリ秒単位)。setsockopt()value 引数として渡されます。

socket.SO_RCVTIMEO: int

受信タイムアウト(ミリ秒単位)。setsockopt()value 引数として渡されます。

socket.IP_ADD_MEMBERSHIP: int

マルチキャストグループに参加します。IPPROTO_IP レベルの setsockopt() オプションです。

socket.IP_DROP_MEMBERSHIP: int

マルチキャストグループから離脱します。IPPROTO_IP レベルの setsockopt() オプションです。

socket.TCP_NODELAY: int

Nagle アルゴリズムを無効にします。IPPROTO_TCP レベルの setsockopt() オプションです。

socket.MSG_PEEK: int

recv()recvfrom() 用: データを入力キューから削除せずに返します。

socket.MSG_DONTWAIT: int

recv()recvfrom() 用: 操作を非ブロッキングモードで実行します。

クラス

class socket.socket(af: int = AF_INET, type: int = SOCK_STREAM, proto: int = IPPROTO_TCP, /)

指定されたアドレスファミリ、ソケットタイプ、プロトコル番号を使用して新しいソケットを作成します。proto の指定はほとんどの場合不要です(また推奨されません)。type 引数が必要なプロトコルを自動的に選択します:

# Create STREAM TCP socket
socket(AF_INET, SOCK_STREAM)
# Create DGRAM UDP socket
socket(AF_INET, SOCK_DGRAM)
close() None

ソケットを閉じた状態にマークし、すべてのリソースを解放します。これが起こると、ソケットオブジェクトに対する以降のすべての操作は失敗します。プロトコルがサポートしている場合、リモート側は EOF 通知を受け取ります。

ソケットはガベージコレクション時に自動的に閉じられますが、作業が終わったらできるだけ早く close() で明示的に閉じることを推奨します。

bind(address: Any) None

ソケットを address にバインドします。ソケットはまだバインドされていてはなりません。

listen(backlog: int = 2) None

サーバーが接続を受け付けられるようにします。backlog を指定する場合、0 以上でなければなりません(それより小さい場合は 0 に設定されます)。これは、新しい接続を拒否する前にシステムが許可する未受理接続の数を指定します。指定されない場合は、適切なデフォルト値が選択されます。

accept() Tuple['socket', Tuple]

接続を受け付けます。ソケットはアドレスにバインドされ、接続を待ち受けている必要があります。戻り値はペア (conn, address) で、conn は接続上でデータを送受信できる新しいソケットオブジェクトであり、address は接続の相手側でソケットにバインドされたアドレスです。

connect(address: Any) None

address にあるリモートソケットに接続します。

send(bytes: bytes) int

ソケットにデータを送信します。ソケットはリモートソケットに接続されている必要があります。送信されたバイト数を返しますが、これはデータの長さより小さい場合があります(「ショートライト」)。

sendall(bytes: bytes) None

ソケットにすべてのデータを送信します。ソケットはリモートソケットに接続されている必要があります。send() とは異なり、このメソッドはデータをチャンクごとに連続して送信することで、すべてのデータを送信しようとします。

非ブロッキングソケットでのこのメソッドの動作は未定義です。このため、MicroPython では代わりに write() メソッドを使用することを推奨します。これはブロッキングソケットに対して同じ「ショートライトなし」のポリシーを持ち、非ブロッキングソケットでは送信されたバイト数を返します。

recv(bufsize: int, flags: int = 0) bytes

ソケットからデータを受信します。戻り値は受信したデータを表すバイトオブジェクトです。一度に受信するデータの最大量は bufsize で指定します。

オプションの flags 引数はメッセージフラグ(MSG_PEEKMSG_DONTWAIT)のビット単位 OR で、CPython と同じ意味を持ちます。

sendto(bytes: bytes, address: Any) int

ソケットにデータを送信します。送信先ソケットは address で指定されるため、ソケットはリモートソケットに接続されていてはなりません。

recvfrom(bufsize: int, flags: int = 0) Tuple[bytes, Tuple]

ソケットからデータを受信します。戻り値はペア (bytes, address) で、bytes は受信したデータを表すバイトオブジェクトであり、address はデータを送信したソケットのアドレスです。

オプションの flags 引数の説明については、recv() 関数を参照してください。

setsockopt(level: int, optname: int, value: int | bytes) None

指定されたソケットオプションの値を設定します。必要なシンボリック定数は socket モジュールで定義されています(SO_* など)。value は整数、またはバッファを表すバイトライクオブジェクトです。

settimeout(value: float | None) None

ブロッキングソケット操作にタイムアウトを設定します。value 引数は秒を表す非負の浮動小数点数、または None です。0 以外の値が指定されると、操作が完了する前にタイムアウト期間の値が経過した場合、以降のソケット操作は OSError 例外を発生させます。0 が指定されると、ソケットは非ブロッキングモードになります。None が指定されると、ソケットはブロッキングモードになります。

移植性が高く汎用的な代替手段は、select.poll オブジェクトを使用することです。これにより、複数のオブジェクトを同時に待機できます(ソケットだけでなく、ポーリングをサポートする汎用の stream オブジェクトも対象です)。例:

# Instead of:
s.settimeout(1.0)  # time in seconds
s.read(10)  # may timeout

# Use:
poller = select.poll()
poller.register(s, select.POLLIN)
res = poller.poll(1000)  # time in milliseconds
if not res:
    # s is still not ready for input, i.e. operation timed out

CPython との違い

CPython はタイムアウト時に socket.timeout 例外を発生させます。これは OSError のサブクラスです。MicroPython は代わりに直接 OSError を発生させます。例外をキャッチするために except OSError: を使用すれば、コードは MicroPython と CPython の両方で動作します。

setblocking(flag: bool) None

ソケットのブロッキングモードまたは非ブロッキングモードを設定します。flag が false の場合、ソケットは非ブロッキングに設定され、それ以外の場合はブロッキングモードに設定されます。

このメソッドは、特定の settimeout() 呼び出しの短縮形です:

  • sock.setblocking(True)sock.settimeout(None) と等価です

  • sock.setblocking(False)sock.settimeout(0) と等価です

makefile(mode: str = 'rb', buffering: int = 0, /) Any

ソケットに関連付けられたファイルオブジェクトを返します。返される正確な型は makefile() に渡された引数によって異なります。サポートはバイナリモード('rb'、'wb'、'rwb')のみに限定されています。CPython の引数 encodingerrorsnewline はサポートされていません。

CPython との違い

MicroPython はバッファ付きストリームをサポートしていないため、buffering パラメータの値は無視され、0(バッファなし)として扱われます。

CPython との違い

makefile() によって返されたファイルオブジェクトを閉じると、元のソケットも閉じられます。

read(size: int | None = None) bytes

ソケットから最大 size バイトを読み取ります。バイトオブジェクトを返します。size が指定されない場合、ソケットから EOF まで利用可能なすべてのデータを読み取ります。そのため、このメソッドはソケットが閉じられるまで戻りません。この関数は要求された分だけ可能な限り多くのデータを読み取ろうとします(「ショートリードなし」)。ただし、非ブロッキングソケットではこれが不可能な場合があり、その場合はより少ないデータが返されます。

readinto(buf: bytearray | memoryview, nbytes: int | None = None) int

buf にバイトを読み込みます。nbytes が指定された場合は、最大でそのバイト数を読み取ります。それ以外の場合は、最大で len(buf) バイトを読み取ります。read() と同様に、このメソッドは「ショートリードなし」のポリシーに従います。

戻り値: 読み取られて buf に格納されたバイト数。

readline() bytes

改行文字で終わる 1 行を読み取ります。

戻り値: 読み取られた行。

write(buf: bytes) int

バイトのバッファをソケットに書き込みます。この関数はすべてのデータをソケットに書き込もうとします(「ショートライトなし」)。ただし、非ブロッキングソケットではこれが不可能な場合があり、その場合の戻り値は buf の長さより小さくなります。

戻り値: 書き込まれたバイト数。

注釈

MicroPython は socket.error を実装していません。CPython には非推奨の socket.error 例外があり、これは OSError のエイリアスです。MicroPython では、ソケット関連のエラーをキャッチするために OSError を直接使用してください。