【发布时间】:2021-12-06 18:14:54
【问题描述】:
我有一个 tcp 服务器正在运行,它服务于两个设备(客户端)。当我从客户端打开连接并发送数据时,我得到了预期的响应。 但是,如果我关闭客户端连接并再次打开,我会得到“端口已在使用中”。 我已经在设置 socket.SO_REUSEADDR 但没有解决方案。 它正在运行到 Linux Ubuntu。
import socket
import select
#!/usr/bin/python3
def main():
CONNECTION_LIST = [] # list of socket clients
RECV_BUFFER = 4096
PORT = 50001
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(('0.0.0.0', PORT))
server_socket.listen(10)
# Add server socket to the list of readable connections
CONNECTION_LIST.append(server_socket)
print("Server started on port " + str(PORT))
while 1:
# Get the list sockets which are ready to be read through select
read_sockets,write_sockets,error_sockets = select.select(CONNECTION_LIST,[],[])
for sock in read_sockets:
#New connection
if sock == server_socket:
# Handle the case in which there is a new connection received through server_socket
sockfd, addr = server_socket.accept()
CONNECTION_LIST.append(sockfd)
print("Client (%s, %s) connected" % addr)
#Some incoming message from a client
else:
# Data recieved from client, process it
try:
data = sock.recv(RECV_BUFFER)
print(data)
if data.startswith("CLIENT1_"):
sock.sendall("client1")
elif data.startswith("CLIENT2_"):
sock.sendall("client2")
# client disconnected, so remove from socket list
except:
#broadcast_data(sock, "Client (%s, %s) is offline" % addr)
print("Client (%s, %s) is offline" % addr)
sock.close()
CONNECTION_LIST.remove(sock)
continue
server_socket.close()
if __name__ == "__main__":
main()
【问题讨论】:
-
始终将完整的错误消息(从单词“Traceback”开始)作为文本(不是屏幕截图,不是指向外部门户的链接)(不是在 cmets 中)。还有其他有用的信息。
-
您没有显示完整的错误消息 - 目前尚不清楚问题是在服务器上还是客户端有问题重用端口。顺便说一句:如果客户端完成连接,那么它应该使用
close()来确保系统关闭套接字。 -
您的代码有错误的索引 - 我们无法运行它。
-
我在 Linux 上使用netcat 作为客户端测试了您的客户端,一切正常。至于我,您的客户端代码有误 - 但您没有显示此代码,因此我可以确认。
-
或者,当您使用
Ctrl+C关闭服务器时,您应该使用try/except或try/finally来运行server_socket.close()。如果不使用server_socket.close(),SO_REUSEADDR将不起作用