簡體   English   中英

Python 客戶端代碼獲取地址已在使用錯誤

[英]Python client code gets Address already in use error

我有一個簡單的 Python HTTP 服務器,它還連接其他 HTTP 服務器以獲取一些數據。 雖然,連接到其他服務器,我的服務器充當 http 客戶端,但為傳入連接請求創建的套接字仍繼續從端口 8080 偵聽(我有一個不同的客戶端套接字)。

我需要連接和獲取數據的其他服務器列表存儲在 JSON 文件中,我有這樣的代碼

with open(myjsonfile, 'r') as json_file:
    entries = json.load(json_file)
    for entry in entries.keys():
        address = entries[entry]['address'] 
        port = int(entries[entry]['port'])
        client_port = config.server_port + 50000
        host = gethostname()

        # request the TXT file
        sock = socket(AF_INET,SOCK_STREAM)
        # sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        sock.bind((host, client_port))
        sock.connect((address, port))
        reqmsg = "GET /" + config.txt_name + " HTTP/1.0\r\n\r\n"
        sock.sendall(reqmsg.encode())
        response = ''
        response = sock.recv(2048).decode()
        pos = response.find("\r\n\r\n")
        txt_data = response[pos+4:]
        # processing the received data here
        sock.close()

        # request the IMG file
        sock = socket(AF_INET,SOCK_STREAM)
        # sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        sock.bind((host, client_port))
        sock.connect((address, port))
        reqmsg = "GET /" + config.img_name + " HTTP/1.0\r\n\r\n"
        sock.sendall(reqmsg.encode())
        response = b''
        while True:
            recvdata = sock.recv(2048)
            if (len(recvdata) < 1): 
                break
            response = response + recvdata
        pos = response.find(b"\r\n\r\n")
        img_data = response[pos+4:]
        # working with the image here
        sock.close()

我必須為我的客戶端使用一個設置的端口號,因為這是服務器識別我的方式。 但是,有時我會在第二個socket.bind()調用(圖像的那個)中收到“地址已在使用”錯誤。 如果沒有bind()調用,我的代碼可以正常工作。 我嘗試設置套接字選項(在上面的代碼中注釋掉)並使用 pycurl 並將LOCALPORT屬性設置為上面的client_port值,但仍然得到相同的錯誤。

錯誤消息背后的原因可能是什么? 我想我打開和關閉 sockets 所以操作系統應該釋放端口以供進一步使用(我認為)?

謝謝

PS:這是一個小項目,不是生產系統,所以不要糾結“為什么要使用端口號來識別客戶端”

session 關閉后有一個 TIME_WAIT,以確保網絡中仍然沒有活動數據包。當您重新創建相同的元組並且其中一個數據包出現時,它將被視為您的連接的有效數據包這將導致錯誤 state。通常 2xpacket max age,在數據包被丟棄之前

在使用相同的元組創建連接之前,來自先前 session 的所有數據包必須是死的。

嘗試使用;

...
sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sock.listen([backlog])
sock.bind((host, client_port))
...

socket.listen([積壓])

暫無
暫無

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

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