繁体   English   中英

Python tcp/ip 服务器端口正在使用中

[英]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/excepttry/finally来运行server_socket.close()

    try:
        server_socket = socket.socket(...)
        # ... code ...
    finally:
        server_socket.close()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM