2016-03-27 14 views
2

私はこのように、ポート6379上のサーバソケットを作成しました:なぜこのポートにredisがバインドできますか?しかし、私はPythonではできません。

Python 13800 IPv4 TCP localhost:6379 (LISTEN) 

>>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
>>> s.bind(('localhost', 6379)) 
>>> s.listen(1) 

lsofのは、それがLISTEN状態であることを示している(私は読みやすくするためのlsofの列の一部を削除しました)

...今私は... ESTABLISHEDショーlsofを... ...

>>> s.connect(('localhost', 6379)) 

をクライアントソケットを作成し、接続します

Python 13800 IPv4 TCP localhost:6379 (LISTEN) 
Python 13838 IPv4 TCP localhost:63075->localhost:6379 (ESTABLISHED) 

次に、私はredisサーバーを起動します。

Python 13800 IPv4 TCP localhost:6379 (LISTEN) 
Python 13838 IPv4 TCP localhost:63075->localhost:6379 (ESTABLISHED) 
redis-ser 13855 IPv6 TCP *:6379 (LISTEN) 
redis-ser 13855 IPv4 TCP *:6379 (LISTEN) 

私は別の接続を開始するためにRedisのために何かを追加します::私はlsofの中で見ることができます

>>> r = redis.StrictRedis('localhost', 6379) 
>>> r.set('foo', 'bar') 

を...ここでは6379を使用しているように見えるすべてのもの、のlsofの礼儀です。 ..

Python 13800 IPv4 TCP localhost:6379 (LISTEN) 
Python 13838 IPv4 TCP localhost:63075->localhost:6379 (ESTABLISHED) 
redis-ser 13855 IPv6 TCP *:6379 (LISTEN) 
redis-ser 13855 IPv4 TCP *:6379 (LISTEN) 
redis-ser 13855 IPv6 TCP localhost:6379->localhost:63084 (ESTABLISHED) 

私の質問は逆です最初に "redis-server"を実行し、ポート6379にバインドされたソケットを作成しようとすると、 "address already in use"エラーが表示されます。

なぜ、RedisはPythonが既に存在するときにポートを使用することができますが、その逆はできません。例えば

...

redis --port 1234 

...正常に動作しますが、私はそれが実行している間、Pythonのソケットを作成しようとした場合:

>>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
>>> s.bind(('localhost', 1234)) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 228, in meth 
    return getattr(self._sock,name)(*args) 
socket.error: [Errno 48] Address already in use 
+0

編集タイトル「connect」ではなく「bind」ですか? – dwks

答えて

1

2つの可能性:

  1. pythonがlocalhostにバインドされている間、redisは "*"にバインドされていることに気づくでしょう。したがって、redisが2番目に起動されると、より一般的にリスンしているため、バインドすることができます。ローカルホストからの着信接続があり、pythonの代わりにredisがそれを処理できます。しかし、redisが最初にリッスンすると、別のプログラムで扱うことのできるアドレスがないため、同じポートで開くことはできません。詳細については、UNIXプログラムrouteの詳細を参照してください。

  2. 複数のサーバーが同じポートでリッスンできるようにするSO_REUSEPORTオプションがあり、着信接続がランダムサーバーに送信されます。 Can two applications listen to the same port? redisはロードバランシングをサポートするためにこれを使用している可能性があります。私は、Pythonプログラムがこのフラグを指定していなければ、そのリスンが拒否されることを期待します。

関連する問題