我尝试用Python中的socket模块制作一个简单的聊天系统。一切正常,除了每次我想关闭服务器时都需要终止该进程。我不想每次都这样做。所以我的问题是:
我怎样才能创建一个函数,当我输入shutdown时时,它会关闭整个服务器?
我已经尝试这样做:
def close(self):
server.close(self)
server.shutdown(self)
但这不起作用。当我输入 close() 时,什么也没有发生。没有什么。
这是 server.py 的完整代码: https: //pastebin.com/gA4QYmQe 每个帮助都很有用。谢谢。
嗯...代码有很多问题(你的“MY IP”和“SERVERIP”可能不是你想要的,但这不是重点。
您的 close() 函数有一个“self”参数,这是没有意义的,因为这不是一个类。如果您想从 try- except 结构中调用 close 函数,您还需要将其移至代码的开头。您需要先调用 shutdown(),然后调用 close(),shutdown 需要一个参数。我修改了您的 close() 来执行此操作并且它有效。
def close():
server.shutdown(socket.SHUT_RDWR)
server.close()
print ("closed")
Run Code Online (Sandbox Code Playgroud)
当您打开套接字时,您还应该设置 SO_REUSEADDR 以使地址可重用(这意味着如果您关闭服务器,您可以再次启动服务器,而不是等待 TIME_WAIT 状态一分钟以完成服务器端口):
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
Run Code Online (Sandbox Code Playgroud)
但是,当您在某处键入“shutdown”时,您到底是如何调用 close() 的呢?你没有这样做。您的程序位于套接字循环中,并且没有读取键盘输入。
我认为向该程序添加键盘输入没有任何意义。首先,它增加了复杂性,因为您正在使用两个可能阻塞的输入(套接字输入和键盘输入)进行操作,并且您需要对此进行管理。这是可能的,但绝对复杂。其次,按 Control + C 比键入“shutdown”并按 Enter 键更快。
目前,您在键盘中断后不会调用 close。我将其添加到内部 KeyboardInterrupt(您可以删除外部 - 它不执行任何操作并且永远不会到达),现在它会整齐地关闭您的程序,关闭所有连接。请记住将 close() 函数从代码底部移到 try: 语句之前的前面:
except KeyboardInterrupt:
print("[!] Keyboard Interrupted!")
close()
break
Run Code Online (Sandbox Code Playgroud)
如果您想要远程关闭(如果您在套接字中键入“shutdown”,服务器就会关闭),您可以将其添加到服务器循环中:
if message == "shutdown":
close()
exit(0)
Run Code Online (Sandbox Code Playgroud)
还有其他问题。例如,如果您启动服务器,连接到它并关闭连接,您的服务器将退出,因为它不会返回listen()。
(在我看来)这也是有点糟糕的编程,因为您使用“服务器”作为全局变量。我宁愿创建一个类并将所有套接字操作放入其中,但如果样式不重要,这应该可以工作。
汉努
| 归档时间: |
|
| 查看次数: |
26335 次 |
| 最近记录: |