python的HttpServer出现socket.accept()阻塞卡死

《bug记录》在利用TCP协议创建【服务器-客户端交互程序】中出现的一些问题 在利用TCP协议创建【服务器-客户端交互程序】中出现的一些问题 阅读详情
最近想用python做一个我微信公众号的后台,结果发现,服务器刚启动的一个多小时微信发的消息是有回复,但过几个小时之后,所有给服务器发现的请求都没有回复了,找了两天问题,昨晚上还弄半夜3点。总算把问题给解决了。

服务器用的是下边这个类:

class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):

和一个处理http各种do_请求的Handler:

class myHandler(BaseHTTPRequestHandler):

我这里只处理三个do_请求,do_GET,do_POST,do_HEAD.
作为http服务器,这部分所有的处理逻辑都是一样的。不多说了。下面我说一下问题出现的原因和处理办法。
出现问题的情况
先看下边服务器log输出,可以看到有不明身份的域名对服务器的433端口使用了get请求。
python的HttpServer出现socket.accept()阻塞卡死 - ♂苹果 - 眼睛想旅行
 这个域名会每过几个小时就对我的服务器进行一次get请求。当出现这个get请求之后,服务器就好像挂掉了一样,所有再向服务器发送的任何请求都不会有回应。感觉很奇怪,但因为对方使用的是三级域名请求,我又没有办法使用IP地址过滤的方法拒绝他,只有当服务器被请求挂掉之后,我才能有办法获取到对方的IP地址。
我就先把这个叫作请求攻击吧,因为每次请求之间都间隔几个小时,就折腾了两天时间,开始的时候以为是多线程对象调用引起的线程死锁,在这个处理思路上就花了一天时间,然后使用单线程启动服务器后看到上边的log,就知道问题所在了。
对问题情况模拟重现
作为程序员在解决bug的问题上,最重要的是要找到解决这个bug的钥匙,也就是让bug可以人为控制的重现。但凡不能重现的bug,都是让人揪心的bug.下边是bug重现方法。其实也很简单。
1.再次启动服务器,
2.用我电脑上的socket调试工具连接服务器的443端口
3.当socket成功连接上服务器的443端口,但不发送任何数据
4.给http服务器发送任意请求
5.服务器不会对任何请求进行回应
6.当从socket工具断开443端口连接时,服务器这时会回复第4步发送的http请求
找到问题了,也可以重现了,那接下来就是对问题的处理。
查看python库的httpServer的源码,找到出现问题的位置
 查看到python库代码之后,发现HttpServer在有客户端连接上后,HTTPServer的_handle_request_noblock()函数中会调用socket的一个socket.accept()方法,这个方法返回客户端IP地址端口以及回复消息的request连接。
当我只作443端口的连接,而不发http请求时,HTTPServer就是阻塞在这个socket.accept()方法调用上。而accept并没有超时参数设置。
mac os系统下,python的HTTPServer相关源码在下边路的两个文件中:

/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/BaseHTTPServer.py

/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py

这两个文件一个是Socket服务器,一个是HTTP服务器,自然了,HTTP服务器类是继承自Socket类的了。
先是SocketServer得到客户端连接,会触发自已的_handle_request_noblock()函数,在这个函数中,连接和请求会转发给HTTPServer来处理。看下图代码部分:
python的HttpServer出现socket.accept()阻塞卡死 - ♂苹果 - 眼睛想旅行
 handle_request是服务器发出的一次客户端请求检测,超时没有发现客户端就调用超时handle_timeout()函数并返回。
当发现有客户端连接时,会调用_handle_request_nolock()方法,在这个方法中有一个获取客户端请求和客户端地址的get_request()方法。这个方法其实在HTTPServer中有实现,看下图代码:
python的HttpServer出现socket.accept()阻塞卡死 - ♂苹果 - 眼睛想旅行
 在这里,调用了socket.accept()函数用以返回客户端请求和客户端连接地址信息。当只作socket连接而不发送http请求时,这个accept就被阻塞了,python的HTTPServer是多线程连接,单线程处理消息,所以这个消息不接收到,就会阻塞后边的所有请求。
想办法解决问题 
找到问题所在了,那么接下来就是真正的解决问题,我试过了很多办法,包括在accept()之前查看客户端信息,设置socket设置方法setsocketopt()或者设置超时,但都解决不了。最后想到看python有没有调用函数超时的处理逻辑,一搜,还真有。下边是找到的处理办法:
我作的处理逻辑:
python的HttpServer出现socket.accept()阻塞卡死 - ♂苹果 - 眼睛想旅行
 到些问题理论上得到解决,我设置的accept()调用超时是2秒。接下来就是测试。
问题还是存在
以为找到了解决办法,但我的http服务器是在子线程里启动的,上边python调用函数超时装饰器办法还是解决不了问题。
python的HttpServer出现socket.accept()阻塞卡死 - ♂苹果 - 眼睛想旅行
 好吧,既然这样,有两种办法来解决这个问题,
第一种,找一个可以在子线程中使用的函数调用超时解决方案。
第二种,把http服务器放到主线程里,把任务处理逻辑放到子线程里。
以上两种方法理论上都是可以了。第二中方法要改很多代码,但实现起来技术难度要低一些。但我想试试第二种方法,于是到处找解决方案。到是让我找到一个。
用文中所说的方法,好像可以实现子线程调用函数超时,赶紧试一下。
经过测试,文中的方法是把accept()方法放在了另一个新建的子线程中去调用。这样httpserver的accept()将不会被阻塞,所有新的http请求都可以正常相应了,虽基socket连接攻击端看到socket还是保持连接着的,但实际上socket连接的accept进程已经被终止了,如果这时候socket连接攻击端发送消息时,就会显示socket已断开。
总结
在处理这个问题时,找到了一些相关的socket知识。在这里收藏一下,说不定以后会用到。
python socket.setsocketopt()方法中参数的设置方法比较奇特,socket底层其实是C语言写的,在设置指针数据类型的参数时用到了struct库,
可以看一下例子:
python的HttpServer出现socket.accept()阻塞卡死 - ♂苹果 - 眼睛想旅行
 
【Lane】 Ultra-Fast-Lane-Detection 复现 引言 车道线检测源码复现以及训练自己的数据集 1 环境搭建 conda create -n lane python=3.7 conda activate lane # 激活环境 conda install pytorch torchvision cudatoolkit=10.1 -c pytorch pip install -r requirements.txt 2 下载项目源码 若在服务器上可以用指令下载,否则直接在网址中下载 git clone https://github.com/cfzd/U 阅读详情

相关推荐

c#笔记之mes上传Http协议版

HTTP(超文本传输协议) 是一种典型的协议。

qq_61441787的博客 345

使用TcpListener的AcceptSocket()方法和AcceptTcpClient()方法接受远端数据时,程序总是好像死机一样!请问如何解决?

为什么我在使用TcpListener的AcceptSocket()方法和AcceptTcpClient()方法接受远端数据时,程序总是好像死机一样。进行调试时关标停在AcceptSocket()方法或AcceptTcpClient()方法上就不动了,一直等到数据读入才向下继续执行。请问解决这种死机的现象应该怎么做?谢谢具体代码如下://///////////////////////////////

qirenli_cn的专栏 6862

用Plecs搞定半桥LLC谐振变换器仿真:从开环模型搭建到闭环PI调参全流程

本文详细介绍了使用Plecs仿真工具进行半桥LLC谐振变换器从开环模型搭建到闭环PI调参的全流程操作。涵盖仿真环境准备、关键元件参数计算、波形异常排查、闭环控制实现及PI参数整定等核心内容,特别针对仿真中的收敛性问题提供实用解决方案,助力电力电子设计者高效完成LLC变换器仿真验证。

weixin_28455801的博客 571

如何解决TCP协议中serverSocket.accept()阻塞和读取类inputstream.read(byte[] byte0)函数的阻塞问题?

在写一个简单的后台服务项目的时候,遇到底层客户端端WiFi模块断线,而导致1.服务程序跑飞,2.线程内存不能合理释放; 标题1.解决inputstream.read(byte[] byte0)函数的阻塞 ,下面是才开始时的代码. ``` ss = new ServerSocket(10086); System.out.println("=============S...

weixin_42353390的博客 5167

Cadence Sigrity

目录 一、PowerSI 1、PowerSI仿真前设置 2、PowerSI提取S参数 (1)检查叠层 (2)选择需要提取的走线和GND (3)设置端口 (4)设置提取频率和提取方式 (5)运行仿真 一、PowerSI PowerSI是一个交流分析工具,适用于频域仿真。 S参数提取 电源阻抗提取 全波参数提取 阻抗、耦合检查 谐振分析 1、PowerSI仿真前设置 打开PCB文件: 打开后如图: 设置为单色后: 仿真前的设置:

fang_yang_wa的博客 3万+

内网(极空间)搭建gitlab跳板机转发端口及域名配置

然后,回头尝试用内网地址+15022 clone,成功,用公网的ip+15222 clone失败,那就是定位到时nginx转发的问题了。首先想到的就是 git clone是通过ssh的22端口进行下载的,那就需要打通22端口,则又配置22端口的nginx转发。然后,我通过ssh命令,做一个端口转发,以实现内网穿透,将服务端口链接到跳板机上。然后穿透到阿里云服务器跳板机的端口,只能内网访问,需要用nginx做个转发,才能用公网ip进行访问。然后,如上,我的80端口,映射15080,22端口映射15022。

God丶Davide的博客 6074

python socket accept 卡死的搞笑理由

这几天总被一个问题困扰,客户端没问题能连上,也能发数据,但tcp服务端经常没反应,感觉卡死在accept。而且有时正常,有时不正常,没规律。直到看到这篇文章,才恍然大悟:https://jingyan.baidu.com/article/ce09321bb95dda2bff858f26.html ...

caohh163的博客 2835

汽车Bootloader流程

根据ISO14229-1 写的汽车行业 Bootloader流程 1:编程前 → 先读取软硬件版本号 22 F1 XX 软件信息 22 F1 XX 硬件信息 → 进入扩展会话extend diagnostic sessions 功能寻址 10 03 → 编程条件检测routine control:ECU升级条件的判断,如车速,检测车的型号 31 01 02 03 → 关闭DTC检测,(由于很多节点收不到其它节点的报文后会记录DTC故障)功能寻址 85 02 → 关闭诊断通讯(禁止各个节点的应用报...

weixin_41320142的博客 2831

Tornado IOLoop 完全指南:主事件循环的接口、原理与实战

Tornado 的 `tornado.ioloop` 模块是整个框架的调度中枢。它提供一个基于非阻塞 socket 的 I/O 事件循环(event loop),承载着 HTTP 服务器、WebSocket、异步客户端等所有组件的读写事件分发与定时任务执行。读完本篇,你将掌握 `IOLoop` 的获取与生命周期管理、文件描述符事件注册、回调与定时器调度、`PeriodicCallback` 周期性

gitblog_00631的博客 917

本地AI助手部署指南:DeepSeek Harness与Ollama集成实践

AI Agent作为当前人工智能领域的热门技术,通过模拟人类决策过程,能够自主规划、调用工具并执行复杂任务。其核心原理在于将大语言模型的推理能力与外部工具API相结合,形成可闭环的工作流。这种技术架构的价值在于显著提升了AI系统的实用性和自动化水平,使其从单纯的对话工具转变为能够解决实际问题的智能助手。在应用场景上,AI Agent广泛应用于代码生成、数据分析、自动化办公等领域。本文聚焦于如何通过DeepSeek Harness平台与Ollama本地模型的集成,实现隐私安全、离线可用的AI助手部署方案,特别

dengjuanshou7445的博客 475

基于C++和Qt开发IEC104规约主站调试软件(第二章)

本章节主要讲解iec104主站软件界面设计和从站的连接功能以及部分功能代码的展示。

半青年的博客 860

智能人脸识别门禁系统

本项目是基于RK3399Pro-D嵌入式开发板的智能人脸识别门禁系统,采用C++17和Python混合开发,充分利用RK3399Pro的NPU硬件加速能力,实现了高精度、低延迟的人脸识别和考勤管理功能。需求状态实现方式验证结果人脸注册(一张照片)✅拍照/上传 → 特征提取 → 人脸库通过人脸识别✅通过人员管理CRUD✅Web界面增删改查通过多部门管理✅支持5个部门通过考勤打卡✅上下班切换通过事件记录✅JSON存储通过系统设置✅考勤时间配置通过。

m0_71999702的博客 398

【自动驾驶轨迹规划之hybrid A*算法】

本文参考论文:https://ai.stanford.edu/~ddolgov/papers/dolgov_gpp_stair08.pdf 这篇文章是基于经典A*算法与reeds-shepp曲线的,不清楚的读者请参考【自动驾驶轨迹规划5之A*算法】_无意2121的博客-优快云博客【自动驾驶轨迹规划之dubins曲线与reeds-shepp曲线】_无意2121的博客-优快云博客 目录 1 hybrid A* 算法创新点 1.1 搜索方式 1.2 车辆运动学模型 1.3 reeds-shepp曲

weixin_65089713的博客 1万+

Python HTTP请求实战:从requests基础到生产级API客户端构建

HTTP请求是现代软件系统间通信的基石,其本质是客户端与服务端基于TCP/IP和应用层协议(如HTTP/1.1)完成状态交换的过程。理解请求方法语义、Header作用机制、状态码含义及超时控制等核心原理,直接决定API集成的稳定性与可维护性。在Python生态中,requests库凭借简洁接口与底层可控性,成为REST API调用的事实标准;而Session复用、异常分层捕获、指数退避重试等工程实践,则构成健壮客户端的关键技术价值。本文聚焦真实开发场景——如401认证失败、429限流处理、JSON序列化陷阱

cuiji1279的博客 355

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Python socket 编程中 accept 阻塞问题的一种解决方法

Python socket 编程中的 accept 阻塞问题的一种解决方法         在进行 Python socket TCP server 端编程时,需要在其运行时接收停止命令事件,停止整个服务程序。虽然这是不常见的需求,但实现起来颇有些周折,其中 accept 执行时的阻塞问题是关键所在。         一般情况下,Python Socket 的 accept 是阻塞执行的,它的阻塞能够屏蔽程序对CTRL-C的接收

luhanhua的专栏 6283

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

python socket server accpet 时间_Python socket.accept()未收到任何连接请求

proxy_thread=threading.Thread(target=proxy_handler,args=(client_socket,remote_addr,receive_first))proxy_thread.start()deftimeout(local_host,local_port):t=5whileTrue:ifstatus.connectedisTrue:breakift&l...

weixin_39831170的博客 368

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

python requests 超时。卡住没反应的处理方法。

网络请求不可避免会遇上请求超时的情况,在 requests 中,如果不设置你的程序可能会永远失去响应。 超时又可分为连接超时和读取超时,简单的说,连接超时就是发起请求连接到连接建立之间的最大时长,读取超时就是连接成功开始到服务器返回响应之间等待的最大时长。 requests最近出现了两次异常, 一次是返回的数据不完整,print(response.text)显示,字符串的后半段没有读取出来。 还有一次是requests卡死了,一直没有返回。 百度查到的信息如下:python requests

bigcarp的专栏 1万+

解决python程序中Socket accept的阻塞问题

一、项目背景 先说下我程序中Socket的用途吧,这样也好参照。我是想用手机的小程序跟阿里云服务器(Windows系统,非Linux系统)上的python程序进行通信,我的小程序会不定期拍摄照片上传到OSS云存储上,同时使用request(POST)的http请求将上传的图片的地址发送给阿里云上的python程序,然后python程序对地址的照片进行下载处理。 过程当中,我设想的是在python程序使用Socket创建TCP服务端,然后使用while循环来一直接收小程序发...

m0_52239706的博客 4299

ServerSocket 用法详解

<br />在客户/服务器通信模式中,服务器端需要创建监听特定端口的ServerSocket,ServerSocket负责接收客户连接请求。本章首先介绍ServerSocket类的各个构造方法,以及成员方法的用法,接着介绍服务器如何用多线程来处理与多个客户的通信任务。<br />本章提供线程池的一种实现方式。线程池包括一个工作队列和若干工作线程。服务器程序向工作队列中加入与客户通信的任务,工作线程不断从工作队列中取出任务并执行它。本章还介绍了java.util.concurrent包中的线程池类的用法,在服

Mr. David 专栏 3128

python中Socket.accept()的返回值是什么

python

1301

python socket (非阻塞、重启端口立即释放)通信

client端 #!/usr/bin/env python #coding:utf-8 import socket #socket.setdefaulttimeout(0.5) #链接服务端ip和端口 ip_port = ('127.0.0.1',9999) #生成一个句柄 sk = socket.socket() try: #请求连接服务端 sk.conn...

学习、记录、分享 3935

Pyhton学习笔记——socket异常处理

一个健壮的程序应该有完善的对于异常中断的处理功能,那么在socket编程中常见的异常有哪些,该如何处理呢?     我们知道socket通信的进行,无非就是绑定主机,端口,监听,接收连接,发送接收数据等等,这些行为如果出错,系统都会返回错误的,为了使得我们的程序有错误检查的功能,我们可以在程序内部加入异常处理,使程序运行到错误处就中断程序运行并打印出出错的地方和具体错误,使程序变得友好。 So

NeverSayNever 2440

Python - 【socket】 服务端Server异常重启处理简单示例Demo(二)

Python - 【socket】 服务端Server异常重启处理

Mr_WoLong 1007

chatgpt赋能python:Python重新启动程序:一种快速重启的方法

本文由chatgpt生成,文章没有在chatgpt生成的基础上进行任何的修改。以上只是chatgpt能力的冰山一角。作为通用的Aigc大模型,只是展现它原本的实力。对于颠覆工作方式的ChatGPT,应该选择拥抱而不是抗拒,未来属于“会用”AI的人。🧡AI职场汇报智能办公文案写作效率提升教程 🧡专注于AI+职场+办公方向。下图是课程的整体大纲下图是AI职场汇报智能办公文案写作效率提升教程中用到的ai工具。

xuhss_com的博客 807

python——网络编程

1.常用函数表格 family 说明 AF_INET IPv4协议 AF_INET6 IPv6协议 AF_LOCAL Unix域协议 AF_ROUTE 路由套接字 AF_KEY 密钥套接字 type 说明 SOCK_STREAM 字节流套接字 SOCK_DGRAM 数据包套接字 SOCK_SEQPACKET...

霹雳牛爸爸___ 4459
上一篇: mac系统下的ch340芯片驱动
下一篇: esp8266发送https请求
woodcol
博客等级 码龄19年 288粉丝 429原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值