[英]Python tcp/ip Server port in use
我有一个 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()
我只能猜测您使用Ctrl+C
来停止服务器 - 但它会引发错误并且脚本不会运行server_socket.close()
。 如果它没有运行server_socket.close()
那么 socket 仍然是打开的并且SO_REUSEADDR
不能改变它。
您必须使用server_socket.close()
来关闭套接字。
SO_REUSEADDR
仅在正确close
后释放PORT
。 它只通知系统它必须在关闭后立即释放PORT
而不会在短时间内阻塞PORT
- 但这需要正确关闭套接字。
所以你需要try/except
或try/finally
来运行server_socket.close()
try:
server_socket = socket.socket(...)
# ... code ...
finally:
server_socket.close()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.