【问题标题】:Python tcp/ip Server port in usePython tcp/ip 服务器端口正在使用中
【发布时间】: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/excepttry/finally 来运行server_socket.close()。如果不使用server_socket.close()SO_REUSEADDR 将不起作用

标签: python linux tcpclient


【解决方案1】:

我只能猜测您使用 Ctrl+C 来停止服务器 - 但它会引发错误并且脚本无法运行 server_socket.close()。如果它没有运行server_socket.close(),那么套接字仍然是打开的,SO_REUSEADDR 不能改变它。

你必须使用server_socket.close()来关闭socket。

SO_REUSEADDR 只是在正确的close 之后释放PORT。它只通知系统它必须在关闭后立即释放PORT 而不会在短时间内阻塞PORT - 但这需要正确关闭套接字。

所以你需要try/excepttry/finally 来运行server_socket.close()

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

【讨论】:

    猜你喜欢
    • 2017-03-23
    • 2010-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-23
    • 1970-01-01
    • 1970-01-01
    • 2015-05-29
    相关资源
    最近更新 更多