Python socket的accept()方法无法中断导致程序无法退出

在学习Python网络编程时,遇到一个问题:使用socket的accept方法监听TCP请求时,程序在阻塞模式下无法通过Ctrl-C正常退出。原因是Python 3.5及以上版本中,socket.accept在被中断时会重试系统调用,而不是抛出异常。为了解决这个问题,可以将socket放入守护线程执行,主线程捕获到信号后退出,从而实现程序的正常退出。
部署运行你感兴趣的模型镜像

学到了Python的网络编程,练习socket的使用,用它编写一个简单的服务监听程序。

用套接字监听TCP请求的程序

""" 
2020-11-18 16:54:08+0800 chenxizhan new
"""
import os.path
import socket

print('pid:', os.getpid())

def task(host, port):

    s = socket.socket()
    print('监听:{}:{}'.format(host, port))
    s.bind((host, port))
    s.listen()
    while True:
        s2, (host, port) = s.accept()
        print('收到连接请求', host, port)
        s2.close()


def main():
    host, port = ('127.0.0.1', 9090)
    task(host, port)


if __name__ == "__main__":
    main()
    print('done')

在这里插入图片描述但Ctrl-C无法终止程序,只能通过命令行窗口的方式(或者使用kill命令)它。

ps:Python socket有非阻塞模式、超时模式、阻塞模式三种,这种情况是阻塞模式下发生的。

原因

socket.accept() 的文档中有如下描述:

Changed in version 3.5: If the system call is interrupted and the signal handler does not raise an exception, the method now retries the system call instead of raising an InterruptedError exception (see PEP 475 for the rationale).

就是说套接字的accept()方法等待连接的时候,键盘中断信号被Python“吃掉“了。

解决方法

把socket放到守护线程中执行,主线程捕捉到信号后退出,程序就会随之退出。

The entire Python program exits when no alive non-daemon threads are left.

""" 一个简单的HTTP服务器
2020-11-18 16:54:08+0800 chenxizhan new
"""
import os.path
import socket
import threading
import time


print('pid:', os.getpid())


def task(host, port):

    s = socket.socket()
    print('监听:{}:{}'.format(host, port))
    s.bind((host, port))
    s.listen()
    while True:
        s2, (host, port) = s.accept()
        print('收到连接请求', host, port)
        s2.close()


def main():
    host, port = ('127.0.0.1', 9090)
    t = threading.Thread(target=task, args=(host, port))
    t.daemon = True
    t.start()

    while True:
        try:
            time.sleep(10)
        except KeyboardInterrupt:
            print('收到键盘信号 Ctrl-C,Bye!')
            exit(0)


if __name__ == "__main__":
    main()
    print('done')

您可能感兴趣的与本文相关的镜像

Python3.10

Python3.10

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值