Python客户端代码获取地址已在使用中错误

问题描述 投票:0回答:1

我有一个简单的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()调用,我的代码可以正常工作。我尝试设置套接字选项(在上面的代码中作了注释),并在将LOCALPORT属性设置为上述client_port值的情况下使用pycurl,但仍然遇到相同的错误。

错误消息背后的原因可能是什么?我想我可以打开和关闭插座,所以操作系统应该释放端口以备将来使用(我认为)?

谢谢

PS:这是一个小项目,而不是生产系统,因此不必理会“为什么使用端口号标识客户端”

python sockets http client-server bind
1个回答
0
投票

会话关闭后会有TIME_WAIT,以确保网络中仍然没有实时数据包。当您重新创建相同的元组并且其中一个数据包显示出来时,它将被视为有效的数据包。您的连接将导致错误状态。通常2xpacket最大期限,在丢弃数据包之前

在创建具有相同元组的连接之前,来自上一个会话的所有数据包都必须是无效的。

尝试使用;

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

socket.listen([backlog])

© www.soinside.com 2019 - 2024. All rights reserved.