web-dev-qa-db-ja.com

Python server "通常、各ソケットアドレスの使用は1つだけ許可されます。

pythonに非常に基本的なサーバーを作成しようとしています。このサーバーは、ポートでリッスンし、クライアントが接続を試み、データを受信し、何かを送信してから再度リッスンするときにTCP接続を作成します(そしてプロセスを無期限に繰り返します)。これは私がこれまでに持っているものです:

from socket import *

serverName = "localhost"
serverPort = 4444
BUFFER_SIZE = 1024

s = socket(AF_INET, SOCK_STREAM)
s.bind((serverName, serverPort))
s.listen(1)

print "Server is ready to receive data..."

while 1:
        newConnection, client = s.accept()
        msg = newConnection.recv(BUFFER_SIZE)

        print msg

        newConnection.send("hello world")
        newConnection.close()

時々これは完全にうまくいくようです(ブラウザで「localhost:4444」を指定すると、サーバーはHTTP GETリクエストを出力し、ウェブページは「hello world」というテキストを出力します)。しかし、最後の数分でサーバーを閉じた後にサーバーを起動しようとすると、散発的に次のエラーメッセージが表示されます。

Traceback (most recent call last):
  File "path\server.py", line 8, in <module>
    s.bind((serverName, serverPort))
  File "C:\Python27\lib\socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted

Windows 7を使用してpythonでプログラミングしています。これを修正する方法についてのアイデアはありますか?

18
scaevity

Bind()を呼び出す前に SO_REUSEADDR ソケットオプションを有効にします。これにより、アドレス/ポートを数分間TIME_WAIT状態のままにして、遅延パケットが到着するのを待つのではなく、すぐに再利用できます。

s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
19
John Kugelman

Windowsでは、次の手順を試すことができます。

1.ポートを使用しているプロセスを確認します。

# 4444 is your port number
netstat -ano|findstr 4444

次のようなものが得られます。

# 19088 is the PID of the process
TCP    0.0.0.0:4444           *:*                                    19088

2.このプロセスを強制終了します

と:

tskill 19088

または:

taskkill /F /PID 19088

幸運を。

13
Rosin

@JohnKugelmanが投稿した 記事 では、SO_REUSEADDRソケットを使用して、以前と同じリモートエンドに接続することはできません。

SO_REUSADDRを使用すると、TIME_WAITでスタックしているポートを使用できますが、そのポートを使用して、最後に接続した場所への接続を確立することはできません。

あなたはただテスト/プレイしているだけです。ただし、このエラーを回避するには、接続を適切に終了する必要があります。オペレーティングシステムのTCPタイミングを台無しにすることもできます。 http://www.linuxquestions.org/questions/linux-networking-3/decrease-time_wait-558399/

テスト目的で、ラウンドロビン方式でserverPortを変更するだけでも問題ありませんが、どう思いますか?

3

(特にWindowsでは)ソケットを閉じることが重要です。それ以外の場合は、Pythonを閉じた後、タイムアウトするまで待つ必要があります。

でしょうか:

try:
    while 1:
        newConnection, client = s.accept()
        msg = newConnection.recv(BUFFER_SIZE)

        print msg

        newConnection.send("hello world")
        newConnection.close()
finally:
    s.close()

助けて?

0
jcater

サーバーコードを終了せず、別のcmdで再度実行しようとしたことが原因である可能性があります。サーバーを同じポート番号でホストすることはできません。以前にホストされていたサーバーを強制終了してください。

0
Rohan Desia

サーバーの最後の瞬間を停止せずにサーバーを再実行しようとすると、機能しません。現在のインスタントを停止する場合は、

シェル->シェルを再起動します

サーバーを停止せずにシェルを既に閉じている場合は、タスクマネージャーおよびタスクの終了 pythonバックグラウンドプロセッサのプロセス。サーバーの最後の瞬間を停止します。

0

ポート番号を別のポート番号に変更しましたが、機能します。

if __name__ == '__main__':
    socketio.run(app, debug = True, use_reloader = False, port=1111)
0
Jelly