rontolisp:tcp-listen
(rontolisp:tcp-listen port &optional host)
port で listen する TCP ソケットをバインドし、
rontolisp:tcp-accept と close で
使うリスナーハンドルを返します。ポート 0 を指定すると空いている
エフェメラルポートが選ばれます — 実際のポートは
rontolisp:tcp-local-port で取得できます。
host を省略するとすべてのインターフェースにバインドし、"127.0.0.1" のような
アドレス文字列を渡すと特定のインターフェースだけにバインドします。
サーバーはループで接続を受け付けます。accept されたハンドルは双方向ストリーム
です(rontolisp:tcp-accept を参照):
(let ((listener (rontolisp:tcp-listen 7777)))
(do ((n 1 (+ n 1))) (nil)
(let ((sock (rontolisp:tcp-accept listener)))
(do ((line (read-line sock) (read-line sock)))
((null line) (close sock))
(write-line line sock))))) ; echo every client forever
バックエンドごとの対応
- インタープリタと JVM: JDK の
java.net.ServerSocketを使用します (インタープリタではSO_REUSEADDR付き)。バインド失敗(ポート使用中など)は エラーを通知します。 - WASM: コンポーネント専用で、
wasi:sockets@0.3.0上で動作します。hostは IPv4 リテラルである必要があります。--componentでコンパイルし、非同期 フラグに加えて-S tcp=y -S inherit-network=yを付けて実行します。バインド 失敗はnilを返します。Preview 1(コアモジュール)モードでは コンパイルエラーです。 - ブラウザプレイグラウンド: 非対応(ブラウザのサンドボックスに生の TCP は ありません)。
制限事項
- リスナーハンドルが対応するのは
rontolisp:tcp-accept、rontolisp:tcp-local-port、closeのみで、それ自体はバイトストリームでは ありません。 - 共通のソケット制限(TCP のみ、WASM では IPv4 リテラルのみ)は
rontolisp:tcp-connectを参照してください。 このリスナーが扱うのは平文の TCP です。TLS リスナーにはrontolisp:tls-listenを使ってください (インタープリタ/JVM のみ)。