2017-06-06 28 views
0

我試圖用Python中的套接字模塊製作一個簡單的聊天系統。一切正常,除了我需要在每次關閉服務器時終止進程。我不想每次都這樣做。 所以我的問題是:Python套接字 - 如何關閉服務器?

我怎麼能做一個功能,當我鍵入關機在服務器終端,它關閉整個服務器?

我已經嘗試過這樣做:

def close(self): server.close(self) server.shutdown(self)

但它不工作。當我輸入close()時,沒有任何反應。沒有。

繼承人server.py的完整代碼: https://pastebin.com/gA4QYmQe 每個幫助都很有用。謝謝。

+0

請問您是否可以修改您的文章以包含更多的代碼?此代碼段中的「服務器」實例是什麼?你的服務器程序的整體結構是什麼? 「關機」是什麼意思?完成程序?停止收聽新的連接?關閉所有現有連接但保持服務器程序運行? – Hannu

+0

我編輯了第一篇文章。它應該關閉整個服務器(關閉程序) – smaxxx

+0

如果您有興趣,請再次發表評論。這現在只接受一個併發連接,並且在客戶端關閉連接時不能很好地恢復。通常這些都是爲了讓主程序在accept()中等待,並且當建立一個新的連接時,它啓動一個以sock和address作爲參數的線程,當主程序返回accept()時,線程處理單個連接。立即。當客戶端關閉連接時,服務它的線程終止,而其他客戶端連接和主循環保持不變。 – Hannu

回答

0

嗯...有很多問題與代碼(「我的IP」和「SERVERIP」很可能不是你想要的,但是這是題外話。

你的close()函數有「self」參數,這是毫無意義的,因爲這不是一個類,如果你想從你的try-except結構中調用它,你還需要將close函數移動到你的代碼的開頭,你需要調用shutdown()第一,然後關閉(),和關機需要一個說法。我修改了close()來做到這一點,它的工作原理。

def close(): 
    server.shutdown(socket.SHUT_RDWR) 
    server.close() 
    print ("closed") 

當你打開你的插座,你也應該設置到SO_REUSEADDR使地址可重複使用(這意味着,如果你關閉它,你可以重新啓動服務器,而不是等待一分鐘TIME_WAIT狀態與您的服務器端口來完成):

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 

但究竟如何,你調用close( )當你在某處輸入「shutdown」時?你沒有這樣做。你的程序在套接字循環中,並沒有讀取鍵盤輸入。

我沒有看到任何添加鍵盤輸入到這個程序。首先,它會增加複雜性,因爲您使用兩個可能的阻塞輸入(套接字輸入和鍵盤輸入)進行操作,您需要管理這些輸入。這是可能的,但絕對複雜。其次,按Control + C而不是輸入「關機」並按回車會更快。

您目前在鍵盤中斷後沒有關閉。我把它添加到KeyboardInterrupt內部(你可以移除的外部 - 它沒有做任何事情,也沒有到達),它現在關閉你的程序,關閉所有連接。請記住,在嘗試之前,你的代碼底部靠攏()函數前:聲明:

except KeyboardInterrupt: 
     print("[!] Keyboard Interrupted!") 
     close() 
     break 

如果你想有一個遠程關機(如果鍵入「關機」到插座服務器關閉),您可以將其添加到您的服務器迴路中:

if message == "shutdown": 
    close() 
    exit(0) 

還有其他問題。例如,如果你啓動你的服務器,連接它並關閉連接,你的服務器退出,因爲它不會返回到listen()。

這也是(在我看來),有些糟糕的編程,因爲你使用「服務器」作爲全局變量。我寧願創建一個類並將所有套接字操作放入其中,但如果樣式不重要,則應該可以工作。

Hannu

相關問題