Mac OS Xで単純なWebサーバーをセットアップしようとしていますが、bind
を実行するとエラーが発生し続けます。これが私が実行しているものです(このトランスクリプトはGNU Guileを使用しますが、posixへの便利なインターフェースとして使用します)。
(define addr (inet-aton "127.0.0.1")) ; get internal representation of 127.0.0.1
(define sockaddr (make-socket-address AF_INET addr 8080)) ; make a struct sockaddr
(define sock (socket PF_INET SOCK_STREAM 0)) ; make a socket
(bind sock sockaddr) ; bind the socket to the address
エラーIn procedure bind: can't assign requested address
が発生します。
だから私はanyアドレスを許可してもう一度試しました。
(define anyaddr (make-socket-address AF_INET INADDR_ANY 8080)) ; allow any address
(bind sock anyaddr)
そして、それはうまくいきます。しかし、それは奇妙です。なぜなら、ifconfig lo0
は
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
inet 127.0.0.1 netmask 0xff000000
したがって、ループバックデバイスは127.0.0.1
に割り当てられます。だから私の質問は、なぜ私はそのアドレスにバインドできないのですか?
ありがとう。
更新:route get 127.0.0.1
の出力は
route to: localhost
destination: localhost
interface: lo0
flags: <UP,Host,DONE,LOCAL>
recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire
49152 49152 0 0 0 0 16384 0
それはあなたの問題を直接解決しないので、これは正確な答えではありません...しかし、あなたの問題はギールに特有であるように見えます。つまり、私のOS X 10.6システムでは、例のguileコードを使用した場合と同じ問題が発生します。一方、以下は問題なく機能します。
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('127.0.0.1', 8080))
s.listen(5)
c, addr = s.accept()
c.send('hello\n')
c.close()
このコードを実行すると、ソケットがリッスンしていることがわかります。
netstat -f inet -an | grep 8080
tcp4 0 0 127.0.0.1.8080 *.* LISTEN
そして、ポート8080に接続すると、期待どおりの結果が得られます。
$ telnet localhost 8080
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
hello
Connection closed by foreign Host.
実際、私の場合、問題は、セマンティックソケットアドレスとは関係のない構造内の初期化されていないフィールドにあります。
memset(&sa, 0, sizeof sa)
を追加したところ、バインドされました。
Guileの実装で同じ問題が発生したのはほぼ確実です。つまり、struct sockaddr_in
の文書化されたフィールドのみを初期化します。いずれの場合も、症状はまったく同じでした。INADDR_ANY
バインディングですが、INADDR_LOOPBACK
は同じerrno
で拒否します。
編集:不明な点がある場合は申し訳ありません。誰かが削除した質問に追加したものを指します。つまり、私は(まったくの偶然によって)別のLISP方言の実装でまったく同じ問題に遭遇しました。 gdb
呼び出しの前にstruct sockaddr_in
の内容を示すいくつかのbind
デバッグセッショントレースとともに、観察結果を追加しました。アドレスは、正しく初期化されたsin_family
、sin_addr
、およびsin_port
フィールドを示しました。ただし、構造の先頭にあるsin_len
フィールド(Darwinに存在し、他のプラットフォームには存在しない)は初期化されておらず、最後にsin_zero
パディング配列があります。