我有一个简单的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:这是一个小项目,而不是生产系统,因此不必理会“为什么使用端口号标识客户端”
会话关闭后会有TIME_WAIT,以确保网络中仍然没有实时数据包。当您重新创建相同的元组并且其中一个数据包显示出来时,它将被视为有效的数据包。您的连接将导致错误状态。通常2xpacket最大期限,在丢弃数据包之前
在创建具有相同元组的连接之前,来自上一个会话的所有数据包都必须是无效的。
尝试使用;
...
sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sock.listen([backlog])
sock.bind((host, client_port))
...