簡體   English   中英

Python 服務器“通常每個套接字地址只允許使用一次”

[英]Python server “Only one usage of each socket address is normally permitted”

我正在嘗試在 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 中編程。關於如何解決這個問題的任何想法?

在 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

祝你好運。

在調用 bind() 之前啟用SO_REUSEADDR套接字選項。 這允許地址/端口立即重用,而不是停留在 TIME_WAIT 狀態幾分鍾,等待遲到的數據包到達。

s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

在@JohnKugelman 發表的文章中指出,即使在啟用SO_REUSEADDR您也不能像以前一樣使用套接字連接到相同的遠程端:

SO_REUSADDR 允許您使用卡在 TIME_WAIT 中的端口,但您仍然無法使用該端口與它連接的最后一個位置建立連接。

我看到你只是在測試/玩耍。 但是,為避免此錯誤,您確實需要確保正確終止連接。 您還可以弄亂操作系統的 tcp 時間: http : //www.linuxquestions.org/questions/linux-networking-3/decrease-time_wait-558399/

出於測試目的,如果您只是以循環方式更改serverPort也沒有問題,您怎么看?

這可能是因為您沒有終止服務器代碼並嘗試在另一個 cmd 上再次運行它。 服務器不能托管在相同的端口號上,嘗試殺死以前托管的服務器。

關閉套接字很重要(特別是在 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()

幫助?

如果您嘗試重新運行服務器而不停止服務器的最后一刻,它將無法工作。 如果你想停止當前的瞬間去

外殼--> 重新啟動外殼。

如果您已經在不停止服務器的情況下關閉了外殼程序,請轉到任務管理器並在后台處理器中結束任務python 進程。 這將停止服務器的最后一刻。

我將端口號更改為不同的端口號並且可以正常工作。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM