英文:
How to exit Python's tcp accept function?
问题
这个程序无法退出,因为accept
函数会阻塞。
如果希望程序在超时后即使accept
函数仍在运行时也能退出,可以进行以下操作:
import socket
import time
HOST = "127.0.0.1" # 标准回环接口地址(本地主机)
PORT = 65432 # 要监听的端口(非特权端口 > 1023)
def connect():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
print("监听中")
s.listen()
s.settimeout(5) # 设置超时时间为5秒
print("等待连接")
try:
conn, addr = s.accept()
except socket.timeout:
print("超时,退出程序")
return
print(f"已连接 {addr}")
with conn:
while True:
data = conn.recv(1024)
if not data:
break
conn.sendall(data)
def main():
connect()
if __name__ == "__main__":
main()
上述代码使用settimeout
函数来设置accept
函数的超时时间,如果在5秒内没有连接到达,程序会超时退出。
英文:
This program cannot exit because the accept function blocks.
What can be done so that the program exits after a timeout even if the accept function is still running?
# taken from https://realpython.com/python-sockets/#echo-server
import socket
HOST = "127.0.0.1" # Standard loopback interface address (localhost)
PORT = 65432 # Port to listen on (non-privileged ports are > 1023)
def connect ():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
print("listening")
s.listen()
print("accepting")
conn, addr = s.accept() # If these lines are
with conn: # commented, the program
print(f"Connected by {addr}") # exits normally.
while True: # This is why I think
data = conn.recv(1024) # that the *accept* function
if not data: # is the problem
break #
conn.sendall(data) #
def main():
connect()
if __name__ == "__main__":
main()
答案1
得分: 1
你可以在服务器套接字上设置超时时间:
>>> import socket
>>> s=socket.socket()
>>> s.bind(('',5000))
>>> s.listen()
>>> s.settimeout(5) # 5秒
>>> s.accept() # 在这里等待...
Traceback (most recent call last): # 5秒后...
File "<stdin>", line 1, in <module>
File "D:\dev\Python311\Lib\socket.py", line 294, in accept
fd, addr = self._accept()
^^^^^^^^^^^^^^
TimeoutError: 超时
如果要实现其他行为,可以捕获超时。例如:
def accept(s):
''' 等待最多5秒的连接。'''
s.settimeout(5)
try:
results = s.accept()
except TimeoutError:
return None
s.settimeout(None) # 禁用超时
return results
英文:
You can set a timeout on the server socket:
>>> import socket
>>> s=socket.socket()
>>> s.bind(('',5000))
>>> s.listen()
>>> s.settimeout(5) # 5 seconds
>>> s.accept() # waits here...
Traceback (most recent call last): # 5 seconds later...
File "<stdin>", line 1, in <module>
File "D:\dev\Python311\Lib\socket.py", line 294, in accept
fd, addr = self._accept()
^^^^^^^^^^^^^^
TimeoutError: timed out
Catch time timeout if you want to implement other behavior. For example:
def accept(s):
''' Wait up to 5 seconds for connection.'''
s.settimeout(5)
try:
results = s.accept()
except TimeoutError:
return None
s.settimeout(None) # disable timeout
return results
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论