私の環境ではGaucheのネットワーク関係の関数がエラーになる。Windows9x系は想定していないためだと思っていたけれど、WindowsXPで試してもやっぱりエラーになってしまった。いずれにしても、問題はソケットをポートに結びつける部分にあるようなので、仮想ポートを用いてあらためて必要な関数を定義して使っている。過去の記事では完全仮想ポートを用いた実装を紹介した。(id:SaitoAtsushi:20051127:1133066434)
だが、問題点が多く、非効率的であったので再度挑戦した。今回は仮想バッファポートを使って実装している。バッファリングモードの選択もできるようになり、リファレンスマニュアルにある本来の仕様をほぼ満たせたと思う。net.scmにこの関数を書いておけばhttp通信等の高レベル関数も問題なく使えるはず。(今のところ、私の環境では使えてる。)
(define (socket-input-port socket . args) (let* ((fill (lambda(buffer) (let* ((dest-size (u8vector-length buffer)) (str (socket-recv socket dest-size))) (string->u8vector! buffer 0 str) (string-length str)))) (filenum (lambda() socket-fd)) (mode (get-keyword :buffering args :modest)) (sock-port (make <buffered-input-port> :fill fill :filenum filenum))) ((setter port-buffering) sock-port mode) sock-port)) (define (socket-output-port socket . args) (let* ((flush (lambda(buffer flag) (let ((dest-size (u8vector-length buffer))) (socket-send socket (u8vector->string buffer))))) (filenum (lambda() socket-fd)) (mode (get-keyword :buffering args :line)) (sock-port (make <buffered-output-port> :flush flush :filenum filenum))) ((setter port-buffering) sock-port mode) sock-port))