from socket import socket, AF_INET, SOCK_STREAM
sock = socket(AF_INET, SOCK_STREAM)
sock.bind(("localhost", 7777))
sock.listen(1)
while True:
try:
connection, address = sock.accept()
print("connected from " + address)
received_message = sock.recv(300)
if not received_message:
break
connection.sendall(b"hello")
except KeyBoardInterrupt:
connection.close()
所以我试图把我的头包裹在套接字周围并拥有这个非常简单的脚本
但出于某种原因,我不能用KeyboardInterrupt
如何用KeyboardInterrupt
杀死脚本,为什么我不能用KeyboardInterrupt
杀死它?
答案 0 :(得分:4)
break
退出while
循环。如果没有break
,循环将不会结束。connection
。from socket import socket, AF_INET, SOCK_STREAM
sock = socket(AF_INET, SOCK_STREAM)
sock.bind(("localhost", 7777))
sock.listen(1)
while True:
connection = None # <---
try:
connection, address = sock.accept()
print("connected from ", address)
received_message = connection.recv(300)
if not received_message:
break
connection.sendall(b"hello")
except KeyboardInterrupt:
if connection: # <---
connection.close()
break # <---
<强>更新强>
KeyBoardInterrupt
应为KeyboardInterrupt
。sock.recv
应为connection.recv
。答案 1 :(得分:2)
尝试向套接字添加超时,如下所示:
from socket import socket, AF_INET, SOCK_STREAM
sock = socket(AF_INET, SOCK_STREAM)
sock.bind(("localhost", 7777))
sock.settimeout(1.0)
sock.listen(1)
while True:
try:
connection, address = sock.accept()
print("connected from " + address)
received_message = sock.recv(300)
if not received_message:
break
connection.sendall(b"hello")
except IOError as msg:
print(msg)
continue
except KeyboardInterrupt:
try:
if connection:
connection.close()
except: pass
break
sock.shutdown
sock.close()
答案 2 :(得分:2)
我在Windows上遇到过这个问题。以下是我处理停止过程的方法:
try:
while self.running:
try:
c, addr = self.socket.accept()
print("Connection accepted from " + repr(addr[1]))
# do special stuff here...
print("sending...")
continue
except (SystemExit, KeyboardInterrupt):
print("Exiting....")
service.stop_service()
break
except Exception as ex:
print("======> Fatal Error....\n" + str(ex))
print(traceback.format_exc())
self.running = False
service.stop_service()
raise
except (SystemExit, KeyboardInterrupt):
print("Force Exiting....")
service.stop_service()
raise
def stop_service(self):
"""
properly kills the process: https://stackoverflow.com/a/16736227/4225229
"""
self.running = False
socket.socket(socket.AF_INET,
socket.SOCK_STREAM).connect((self.hostname, self.port))
self.socket.close()
请注意,要触发KeyboardInterrupt异常,请使用:
Ctrl
+ Fn
+ PageUp(Pause/Break)
答案 3 :(得分:1)
如果远端很少发送数据,则还应该设置连接超时。
在这种情况下,当可以检查KeyboardInterrupt
时,连接将引发超时异常。
from socket import socket, AF_INET, SOCK_STREAM
sock = socket(AF_INET, SOCK_STREAM)
sock.bind(("localhost", 7777))
sock.settimeout(1.0)
sock.listen(1)
while True:
try:
connection, address = sock.accept()
connection.settimeout(1.0)
print("connected from " + address)
received_message = sock.recv(300)
if not received_message:
break
connection.sendall(b"hello")
except socket.timeout:
continue
except IOError as msg:
print(msg)
continue
except KeyboardInterrupt:
try:
if connection:
connection.close()
except: pass
break
sock.shutdown
sock.close()
答案 4 :(得分:1)
尝试使用timeout
使程序从accept
等待过程中定期“跳出”以接收KeyboardInterrupt命令。
以下是套接字服务器的示例:
import socket
host = "127.0.0.1"
port = 23333
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((host,port))
sock.listen()
sock.settimeout(0.5)
print("> Listening {}:{} ...".format(host,port))
try:
while True:
try:
conn, addr = sock.accept()
data = conn.recv(1024)
if not data:
print("x Client disconnected!")
break
else:
print("> Message from client: {}".format(data.decode()))
msg = "> Message from server".format(data.decode()).encode()
conn.sendall(msg)
except socket.timeout:
print("Timeout")
except KeyboardInterrupt:
pass
except KeyboardInterrupt:
print("Server closed with KeyboardInterrupt!")
答案 5 :(得分:0)
对于Windows用户,
以上尝试捕获KeyBoard中断的解决方案似乎无效。我最终在套接字上设置了超时时间。
类似:
server_socket.settimeout(10)
在闲置10秒后会引发异常(例如10秒钟没有收到任何东西)
答案 6 :(得分:0)
可以在单独的进程中捕获CTRL + C事件,然后将其发送回在主进程中运行的另一个线程以杀死套接字。以下示例已在Windows 10上使用Python 3.5.4成功测试。在周围放置一些注释和打印语句,以便您查看正在发生的情况。
from multiprocessing import Pipe, Process
from socket import socket, AF_INET, SOCK_STREAM
from threading import Thread
import time
def detect_interrupt(conn):
try:
print("Listening for KeyboardInterrupt...")
while True:
time.sleep(1)
except KeyboardInterrupt:
print("Detected KeyboardInterrupt!")
print("Sending IPC...")
conn.send(True)
conn.close()
def listen_for_interrupt(conn, sock):
print("Listening for IPC...")
conn.recv()
print("Detected IPC!")
print("Closing sock...")
sock.close()
if __name__ == "__main__":
sock = socket(AF_INET, SOCK_STREAM)
sock.bind(("localhost", 7777))
sock.listen(1)
# Crate a Pipe for interprocess communication
main_conn, detect_conn = Pipe()
# Create a thread in main process to listen on connection
listen_for_interrupt_thread = Thread(
target=listen_for_interrupt, args=(main_conn, sock), daemon=True)
listen_for_interrupt_thread.start()
# Create a separate process to detect the KeyboardInterrupt
detect_interrupt_process = Process(
target=detect_interrupt, args=(detect_conn,))
detect_interrupt_process.start()
connection = None
try:
while True:
print("Running socket accept()")
connection, address = sock.accept()
print("connected from " + address)
received_message = sock.recv(300)
if not received_message:
break
connection.sendall(b"hello")
except KeyboardInterrupt:
print("Handling KeyboardInterrupt")
sock.close()
if connection:
connection.close()