嗯...有很多問題與代碼(「我的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
請問您是否可以修改您的文章以包含更多的代碼?此代碼段中的「服務器」實例是什麼?你的服務器程序的整體結構是什麼? 「關機」是什麼意思?完成程序?停止收聽新的連接?關閉所有現有連接但保持服務器程序運行? – Hannu
我編輯了第一篇文章。它應該關閉整個服務器(關閉程序) – smaxxx
如果您有興趣,請再次發表評論。這現在只接受一個併發連接,並且在客戶端關閉連接時不能很好地恢復。通常這些都是爲了讓主程序在accept()中等待,並且當建立一個新的連接時,它啓動一個以sock和address作爲參數的線程,當主程序返回accept()時,線程處理單個連接。立即。當客戶端關閉連接時,服務它的線程終止,而其他客戶端連接和主循環保持不變。 – Hannu