簡體   English   中英

Python 接受的套接字連接未關閉

[英]Python accepted socket connection not closing

我編寫了一個 Pi 硬件接口服務器 (phis),它使用 http 協議來控制連接到我的 Raspberry Pi 的硬件(繼電器、模擬測量等)。 它處理簡單的請求並以純文本響應。 多年來它一直在完美運行,我已經為系統編寫了廣泛的基於瀏覽器的界面。 這是基本結構:

listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listen_socket.bind((HOST, PORT))
listen_socket.listen(1)

read_list = [listen_socket]

while True:
    readable, writeable, errored = select.select(read_list,[], [], 2)
    if len(readable) == 0: # select timed out
        continue

    client_connection, client_address = listen_socket.accept()
    try:
        request = client_connection.recv(1024)
    except Exception:
        print "Exception trying to recv, %s" % time.strftime(date_format)
        sys.exc_clear()
        client_connection.close()
        continue

    words = request.split()

    http_response = """\
HTTP/1.1 200 OK
"""
    try:
        client_connection.sendall(http_response)
    except Exception:
        print "Exception trying to send 1, %s" % time.strftime(date_format)
        sys.exc_clear()
        client_connection.close()
        continue

    http_response = """\
Content-Type: text/plain; charset=utf-8

"""

# perform some action and add text to the http_response (like current CPU temperature, etc)

    try:
        client_connection.sendall(http_response)
    except Exception:
        # log the error, then...
        sys.exc_clear()
        client_connection.close()
        continue

    client_connection.close()

    if words[1] == '/exit':
        sys.exit(0)

當命令是啟動 mjpg_streamer 時會出現問題。 stream 啟動得很好,響應已發送,我可以建立更多連接並發出新命令,但 client_connection.close() 從未真正關閉連接,瀏覽器只是坐在那里等待更多永遠不會出現的東西。 phis 仍在接受新連接並為這些連接提供服務,但如果我使用請求“http://pi:4000/exit”退出服務器,它會干凈利落地執行,但除非我先啟動,否則它不會再次啟動(正在使用套接字)發出停止 mjpg_streams 的請求(也可以正常工作)。

mjpg_streamer 已經在(似乎是)守護進程后台模式下啟動,但在我嘗試讓它工作時,我已經發出命令在每個 python“啟動你的背景孩子並讓它運行”方法中啟動它我能找到( os.system()、subprocess.Popen()、os.fork() 和 os.fork() 兩次,os.setsid() 介於兩者之間)。 沒有任何效果。

If it matters, I'm actually calling a perl script from the phis that starts mjpg_steamer with command line arguments based on arguments passed to the perl script.

我對此進行了很多搜索,發現其他連接不會關閉,但連接不會完美關閉,除非在連接處於活動狀態時生成了一些基於套接字的后台應用程序。 有人知道出了什么問題嗎?

這篇文章中找到了答案(我看到它的那一刻“Duh”!)

我忘記關閉分叉子進程中連接和監聽的 sockets,這些子進程由衍生的守護進程繼承,只要它運行就保持打開狀態。 這是我用來生成將繼續運行(守護進程)的進程的代碼:

def spawnDaemon(syscmd):
    # do the UNIX double-fork magic, see Stevens' "Advanced 
    # Programming in the UNIX Environment" for details (ISBN 0201563177)
    try: 
        pid = os.fork() 
        if pid > 0:
            # parent process, wait for first child, then return and keep running
            os.wait()
            #print "first parent returning"
            return
    except OSError, e:
        print >>sys.stderr, "fork #1 failed: %d (%s)" % (e.errno, e.strerror) 
        sys.exit(1)

    # close the copy of the socket the request came in on
    client_connection.close()

    # close the copy of the server's main listening socket
    listen_socket.close()

    # change process group to detach the child (mjpeg_streamer) from the parent phis
    os.setsid()

    # do second fork
    #print "trying second fork"
    try: 
        pid = os.fork() 
        if pid > 0:
            # exit from second parent
            #print "second parent exiting"
            sys.exit(0) 
    except OSError, e: 
        print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror) 
        sys.exit(1)

    # execute the command
    os.system(syscmd)

    # all done, exit 2nd child
    #print "exiting after executing syscmd"
    sys.exit(0)
# spawnDaemon()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM