connect()
自動的に割り当てられたエフェメラル ポート (5000 ~ 65534) の範囲内のポートを使用して localhost に接続すると、Winsock ソケットを確実に取得できます。具体的には、Windows は、クライアント ソケットのローカル ポート番号として割り当てようとする次のポートであるシステム全体のローリング ポート番号を持っているようです。割り当てられた番号がターゲット ポート番号のすぐ下になるまでソケットを作成し、ソケットを繰り返し作成してそのポート番号に接続しようとすると、通常はソケットをそれ自体に接続できます。
最初に、localhost の特定のポートに繰り返し接続しようとするアプリケーションで発生しました。サービスがリッスンしていない場合、接続を正常に確立し、最初に送信したメッセージを受信することはほとんどありません (たまたま Redis です)。PING
指図)。
Python での例 (ターゲット ポートを何もリッスンせずに実行):
import socket
TARGET_PORT = 49400
def mksocket():
return socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
while True:
sock = mksocket()
sock.bind(('127.0.0.1', 0))
host, port = sock.getsockname()
if port > TARGET_PORT - 10 and port < TARGET_PORT:
break
print port
while port < TARGET_PORT:
sock = mksocket()
err = None
try:
sock.connect(('127.0.0.1', TARGET_PORT))
except socket.error, e:
err = e
host, port = sock.getsockname()
if err:
print 'Unable to connect to port %d, used local port %d: %s' % (TARGET_PORT, port, err)
else:
print 'Connected to port %d, used local port %d' (TARGET_PORT, port)
私の Mac マシンでは、これは最終的にUnable to connect to port 49400, used local port 49400
. 私の Windows 7 マシンでは、接続が正常に確立され、出力されConnected to port 49400, used local port 49400
ます。結果のソケットは、送信されたすべてのデータを受信します。
これは Winsock のバグですか? これは私のコードのバグですか?
編集:これは、問題のある接続が表示されたTcpViewのスクリーンショットです。