当前位置: 首页 > 编程日记 > 正文

Lighttpd1.4.20源代码分析 笔记 状态机之错误处理和连接关闭

这里所说的错误有两种:
1.http协议规定的错误,如404错误。
2.server执行过程中的错误。如write错误。

对于http协议规定的错误,这里的“错误”是针对client的。

lighttpd返回相应的错误提示文件之后,相当于顺利的完毕了一次请求,仅仅是结果和client想要的不一样而已。

对于server执行中的错误,状态机进入CON_STATE_ERROR状态。常见的错误原因:client提前断开连接。

比方你不停的刷新页面。在你刷新的时候,前一次的连接没有完毕,但被浏览器强行断开。对于server而言,刷新前后的两个连接是不相干的,server在接收后一个连接的时候仍然会继续处理前一次的连接。而前一次的连接已断开,这就产生了连接错误。

进入CON_STATE_ERROR状态后。假设前面的请求处理已经得到了结果。也就是http_status不为空。那么调用plugins_call_handle_request_done告诉插件请求处理结束:

            /* even if the connection was drop we still have to write it to the access log */if (con->http_status) {plugins_call_handle_request_done(srv, con);}

假设使用了ssl,关闭ssl连接:

#ifdef USE_OPENSSLif (srv_sock->is_ssl) {/* 关闭ssl连接 */}ERR_clear_error();
#endif

接着:

            switch(con->mode) {case DIRECT:
#if 0log_error_write(srv, __FILE__, __LINE__, "sd","emergency exit: direct",con->fd);
#endifbreak;default:switch(r = plugins_call_handle_connection_close(srv, con)) {case HANDLER_GO_ON:case HANDLER_FINISHED:break;default:log_error_write(srv, __FILE__, __LINE__, "");break;}break;}connection_reset(srv, con);

假设连接模式不是DIRECT,调用plugins_call_handle_connection_close告诉插件连接已经关闭。

假设设置了keep_alive。此时可能是server首先关闭连接的。调用shutdown关闭连接的读和写。假设关闭没有出错,状态机进入CON_STATE_CLOSE状态。

假设没有设置keep_alive或者shutdown调用失败,那么直接关闭连接。结束状态机的执行。

            /* close the connection */if ((con->keep_alive == 1) &&(0 == shutdown(con->fd, SHUT_WR))) {con->close_timeout_ts = srv->cur_ts;connection_set_state(srv, con, CON_STATE_CLOSE);if (srv->srvconf.log_state_handling) {log_error_write(srv, __FILE__, __LINE__, "sd","shutdown for fd", con->fd);}} else {connection_close(srv, con);}con->keep_alive = 0;srv->con_closed++;

注意到。这里server主动关闭连接的时候用的是shutdown而不是close:

1.close使用引用计数,在计数为0时才关闭套接字;shutdown无论引用计数,直接激发TCP的正常连接终止序列。

2.close终止读和写两个方向的数据传送。shutdown能够指定仅仅关闭连接的读,或仅仅关闭连接的写。或两者均关闭。

以上lighttpd是关闭了连接的写这一半,对于TCP套接字来说。这叫做半关闭:当前留在套接字发送缓冲区的数据仍然能够发送。可是进程不能再对其调用写函数(因为读端没有关闭,所以server仍然能够读数据),当数据发送完毕之后,TCP连接终止。

另外。注意一下:con->close_timeout_ts = srv->cur_ts;将close_timeout_ts的值设置为当前时间,在以下会用到。

在CON_STATE_CLOSE阶段:

        case CON_STATE_CLOSE:if (srv->srvconf.log_state_handling) {log_error_write(srv, __FILE__, __LINE__, "sds","state for fd", con->fd, connection_get_state(con->state));}if (con->keep_alive) {if (ioctl(con->fd, FIONREAD, &b)) {log_error_write(srv, __FILE__, __LINE__, "ss","ioctl() failed", strerror(errno));}if (b > 0) {char buf[1024];log_error_write(srv, __FILE__, __LINE__, "sdd","CLOSE-read()", con->fd, b);/* */read(con->fd, buf, sizeof(buf));} else {/* nothing to read */con->close_timeout_ts = 0;}} else {con->close_timeout_ts = 0;}if (srv->cur_ts - con->close_timeout_ts > 1) {connection_close(srv, con);if (srv->srvconf.log_state_handling) {log_error_write(srv, __FILE__, __LINE__, "sd","connection closed for fd", con->fd);}}break;

假设缓冲区中还有数据,server会把数据读出来(然后丢弃),以腾出内存空间。

假设没有数据可读,那么设置close_timeout_ts=0,关闭连接。

假设有数据可读,读取数据之后,连接依旧处在CON_STATE_CLOSE状态中(在出了CON_STATE_ERROR后。进入CON_STATE_CLOSE,这段时间cur_ts是没有改变的。假设有数据可读,此时const_time_ts是等于cur_ts的,因此连接并未被关闭),连接相应的fd被增加到fdevent系统中监听读事件。

假设缓冲区中还有数据,那么在connection_handle_fdevent 函数中,也有上面这段代码,再次执行之,直到数据读完。

随着close_timeout_ts被设置为0,在下次joblist的调度中,状态机将会关闭连接,清理全部资源。

至此,连接正式关闭。

关于状态机的简单解析就到此为止~

转载于:https://www.cnblogs.com/yutingliuyl/p/7365725.html

相关文章:

资料分享:送你一本《数据结构(C语言版)》电子书!

要想写出可复用、可扩展、易维护、灵活性好的代码,「数据结构」这一关必须要过啊! 在数据结构与算法的众多教材中,奉为经典的当属清华大学严蔚敏老师的著作。很多学校也选择这本书作为考研指定教材。 正在学习数据结构与算法这门课程的同学…

零基础学python培训需要学习多久?

Python是一种入门比较简单的编程语言,但是如果是零基础学员,学习起来还是需要时间的,那么零基础学python培训需要学习多久呢?我们来看看小编的详细介绍吧。 零基础学python培训需要学习多久? 现在的培训机构,一般Python的培训时…

拖动无标题窗体

方法一: 当用户点击窗体的时候欺骗系统,用户是点在标题栏上,这样就完成了无标题栏窗体的拖动,实现如下: 在 MESSAGE_HANDLER(WM_NCHITTEST, OnNcHitTest) 这个函数的方法里 : LRESULT CNyWnd::OnNcHitTest(…

如何利用 C# 爬取Gate.io交易所的公告!

对于大部分程序员来说,都希望自己或多或少拥有一些比特币(BTC)。获取 BTC 的途径除了挖矿计算 Hash 值之外,就是去交易所购买了。 由于 BTC 的价格波动非常剧烈,入手 BTC 的时机就显得尤为关键。在交易所搞活动时入手…

人的原罪、本我和超我

摘自:https://www.zhihu.com/question/31362451/answer/51606300人的原罪的存在,因为人人皆有,所以在潜意识中,形成了对本我的接纳,而神爱世人与宽恕的存在,形成了本我与超我的良性互动。 在这样的关系中&a…

软件测试的准入准出是什么?标准是什么?

测试的准入准出是指什么情况下可以开始当前版本的测试工作,什么情况下可以结束当前版本的测试工作。不同项目、不同公司的测试准入准出标准都会有所不同。下面介绍一些通用的测试准入准出标准。 测试准入标准如下: (1)开发编码结束,开发人员在…

如何利用 C# 爬取 One 持有者返利数据!

去年,10月份写过一篇图文 「One」的投资价值分析,多半年过去了,回头看看当时的判断还是合理的。 投资这种事情需要有自己的策略,更需要理性。任何决策都需要以数据作为判断的基础,哪么是否还继续持有 ONE呢&#xff1f…

04.微博消息的语言检测

04.微博消息的语言检测 郑昀 201010 隶属于《02.数据解析》小节 大意是,封装Google语言检测ajax web service的接口,输入一段话,输出语言种类。这个方法是从RssMeme.com看来的,经测试效果还不错,可用于检测微博客消息的…

CIO时代学院院长姚乐:传统行业遇上大数据 拥抱智能化未来

近几年,互联网行业发展突飞猛进,“大数据”技术瞬间变得炙手可热,当然,对于发展中的大数据技术而言,很多行业都不会错失良机。近日,CIO时代学院院长、中国新一代IT产业推进联盟秘书长姚乐在“2016CIO时代中…

自动化测试的优势和局限性有哪些

自动化测试只是众多测试中的一种,并不比人工测试更高级更先进。和人工测试相比自动化测试有一定的优势和劣势,具体如下。 1.优势 (1)自动化测试具有一致性和重复性的特点,而且测试更客观,提高了软件测试的准确度、精确度和可信任度…

也分享一个存储过程代码生成器 开源

可以通过 FILE>OPTION 修改前缀,作者等信息。。。。。 完全傻瓜式应用,开源,方便进行个性化开发。。。 工具地址:http://spgen.codeplex.com/ Stored Procedure Generator (for SQL Server 2000/2005) 虽然这样写,但…

如何利用 C# 爬取BigOne交易所的公告!

在当今这个时代,投资可以说是每个人都应该学会的一项技能。拥有一些数字货币是程序员的信仰!交易所是进入数字货币世界最方便的一扇门,今天我就带着大家爬取 Bigone 交易所的公告数据。 首先,我们来看一下要爬取的页面以及对应的…

如何提升自己的Web前端技术

如何提升自己的Web前端技术?问这个问题的一般都是有一些web基础的同学,还有一部分是自学的web前端技术,对自己目前的能力还比较模糊,下面小编就这个问题为大家做下详细的介绍。 如何提升自己的Web前端技术?在IT行业,任何一种专业…

tomcat 性能设置

Tomcat性能调优: 找到Tomcat根目录下的conf目录,修改server.xml文件的内容。对于这部分的调优,我所了解到的就是无非设置一下Tomcat服务器的最大并发数和Tomcat初始化时创建的线程数的设置,当然还有其他一些性能调优的设置&#x…

SAP的安装后基本设定

SAPLogon登录时候是乱码,设定登陆配置的代码页属性,勾选Unicode off SAP英文系统下中文显示乱码 设定字符集为GB2312 RZ10常用的配置参数rz10 编辑系统参数文件 rdisp/gui_auto_logout & rdisp/keepalive 用于控制闲置时间(秒) login/system_client 用于控制默认…

如何通过 Scratch 教小朋友编程思维?

寒假的时候,我带着自己的小孩学 Scratch,希望通过这种图形化的语言来训练他的编程思维。开学之后,很多事情需要处理,所以拖到现在才写总结。希望对大家有所启发。 在介绍如何做这件事情之前,先介绍一个学习方面的基本…

零基础怎么学习UI设计?有哪些简单的学习方法?

UI设计近几年的就业前景是非常好的,所以很多人都想要学习UI设计,那么零基础怎么学习UI设计?有哪些简单的学习方法?下面小编就给大家做下详细的介绍。 零基础怎么学习UI设计?有哪些简单的学习方法? UI设计行业是很注重技术的,零基础如果直…

让资源管理器不显示最近常用文件夹

右键点任务栏,点“属性”->Startmenu->在Privacy框中,把第二个√ 去掉,如下图所示:

C# 写Windows服务

服务是一个运行在后台的程序,他没有界面,不能交互,只能孤独的独自运行。 在开始->运行->输入services.msc可以打开服务管理器,这里可以查看和管理服务   很多时候都会用到服务,因为服务简化了我们的操作&#…

技术图文:如何利用 C# 爬取 ONE 的交易数据?

投资一个金融产品,最基本的就是拿到这个金融产品的交易数据,对这些数据进行可视化来判断趋势。去年,我在听 李笑来 讲区块链的课程上知道了 BigOne 这个由 INB 投资的交易所,而 ONE 是 BigOne 的平台币,持有 ONE 可享受…

java程序猿必读的学习书籍,良心推荐!

每年都有很多人想要学习java技术,有的是自学,有的是报班学习,但是都免不了要看书籍学习,书籍学习带来的知识更加牢记,也可以随时做笔记,下面小编就为大家推荐java程序猿必读的学习书籍,希望能帮…

Autools学习总结(一)

一、Makefile 简介 在编写C/C程序的时候,我们经常需要编译并运行代码。在程序规模较小的情况下,可以简单地直接调用编译器来完成这项工作。然而,在很多情况下程序往往包括大量的代码文件,手动调用编译器变得麻烦无比。尤其要命的是…

简单的实现IOCP服务器模型

其实已经有很多大佬将原理讲的十分详细了,所以就不花费时间将原理再一次重复讲一遍,有需要的可以自行去查看。 http://blog.csdn.net/beyond_cn/article/details/9336043 这篇文章是我看的,原理介绍十分详细。不过有一些操作感觉比较复杂因此…

资料分享:送你一本《数据结构与算法JavaScript描述》电子书!

数据结构 是掌握计算机编程必须具备的技能。通常情况下,我想掌握一门编程语言所用的方法就是利用这门语言把数据结构中线性表、栈、队列、字符串、动态数字、整数集合、树、图、搜索、排序等涉及的算法全部写一遍。写完之后,基本上就把这门语言搞定了。 …

Python中爬虫框架或模块的区别

Python中爬虫框架或模块的区别,我们在Python的学习过程中,需要不断的总结知识点,这样我们才能进步的更快一些。 (1)爬虫框架或模块 Python自带爬虫模块:urllib、urllib2; 第三方爬虫模块:requests,aiohttp;…

SQL SERVER 2000写存储过程出现列名无效的解决方法

举一个Northwind的例子。DECLARE m_LastName nvarchar(20) DECLARE Sql varchar(256)SET m_LastName Fuller SET Sql SELECT * FROM Employees WHERE LastName char(39) m_LastName char(39) EXEC(Sql) 注意,要加上char(39)就可以了。转载于:https://www.cnblo…

如何利用 C# + Python 破解猫眼电影的反爬虫机制?

在 如何利用 C# 爬取「猫眼电影:最受期待榜」及对应影片信息! 这篇图文中可以看到猫眼电影对“本月新增想看人数” 和 “总想看人数”进行了字符集加密。 在 如何利用 C# 爬取「猫眼电影:国内票房榜」及对应影片信息! 这篇图文中也…

ZooKeeper学习笔记1-----------安装启动

ZooKeeper是一套协作服务,主要用来构建分布式架构的应用,通过ZooKeeper我们可以安全的处理分布式应用下的局部故障问题。我们知道ZooKeeper就是Hadoop中的分布式协作服务组件。下面我们进入ZooKeeper的安装部署。 安装Zookeeper https://zookeeper.apach…

软件测试培训完就业方向怎么选择

软件测试技术在近几年的发展前景是非常好的,越来越多的人都想要学习软件测试技术,报班是大多数人的选择,但是大家对于“软件测试培训完就业方向怎么选择”这个问题比较迷茫,我们来看看下面的详细介绍。 软件测试培训完就业方向怎么…

LeetCode实战:合并两个有序链表

题目英文: Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists. Example: Input: 1->2->4, 1->3->4 Output: 1->1->2->3->4->4 题目中…