DICOM:剖析Orthanc中的Web Server,Mongoose之“连接请求触发的事件序列”(二)

背景:

Orthanc是本专栏中介绍过的一款新型DICOM服务器,具有轻量级、支持REST的特性,可将任意运行Windows和Linux系统的计算机变成DICOM服务器,即miniPACS。Orthanc内嵌多种模块,数据库管理简单,且不依赖于第三方软件。因此通过剖析Orthanc源码可以学习到搭建DICOM系统中的各个环节,例如SQLite嵌入型数据库、GoogleLog日志库、DCMTK医学DICOM库,以及近期要介绍的开源Web Server,Mongoose。

题记:

近期计划参照官网剖析Mongoose源码的同时进行实例讲解。开源软件的一大优势就是源代码公开,通过剖析源码可以学习其优良的设计架构和实现模式,然而对于代码上万行,甚至十几万行开源软件,单纯的钻研源代码可能会陷入其中而无法自拔。往往在感叹作者设计巧妙时,迷失了方向;在为各种逻辑求根溯源时,失去了信心;最终在悔恨自己能力有限的同时,放弃了努力。很多良好的架构和模式,其实不一定是设计出来的,至少可以说不是“提前”设计出来的。任何开源项目都是从无到有,从起步到成熟,一开始就阅读已成熟的源码,享受别人思想果实自然会“无福消受”。要想搞清楚为何设计这种数据结构?为何设计如此运行逻辑?——要从应用场景(context)出发,考虑项目的起源和应用,切记任何设计都是为应用服务的。因此后续博文会采用源码分析+实例讲解的方式来进行剖析和学习,还是那句话“看源码累了就调试调试实例,调试累了就钻研钻研源码”,劳(源码)逸(实例)结合,脚踏实地,Keep
Running……

HTTP请求:

当今互联网和移动互联网已经人人皆知,平时我们上网最用的就是HTTP请求,即从客户端(PC、手机)到服务器的请求消息。至于HTTP请求的具体格式就不介绍了,既然是协议就是用来约定双方交互的规则,让服务端知道客户端想做啥,同时让客户端理解服务端给了啥。

HTTP是基于TCP/IP的应用层协议,因此在服务端和客户端交流信息之前首先要建立TCP连接。关于连接建立的方式有很多,比如每次请求都建立新的连接、网页不同部分请求建立不同的连接等等。借用博文Tornado HTTP服务器的基本流程中的一张HTTP流程图,大多数HTTP服务端该流程基本相似,Mongoose也一样,如下图所示:

Mongoose与Fossa:

上一篇专栏博文介绍了Mongoose是一个小型的、可嵌入的HTTP Server。只要在自己工程中引入mongoose.h和mongosoe.c源码文件即可快速开启一个HTTP Server。Mongoose支持REST和JSON-RPC服务(这也是我打算分析Mongoose的根本原因,希望仿照Orthanc将Mongoose嵌入到传统PACS系统中,对传统PACS系统进行分布式改造)。

打开Mongoose在Github上的仓库你会发现Mongoose是建立在NS Skeleton框架之上的,而NS Skeleton者的就是Fossa。官方对Fossa的描述为:Fossa是一个用C语言编写的支持多协议的网络编程库。采用基于事件驱动的模式,方便用户实现各种网络协议,开发可扩展网络应用。

        截至目前我们可以认为Fossa是底层网络开发库,Mongoose是对Fossa的一次封装,强化了事件驱动,方便用户快速上手,而Orthanc是将Mongoose进行了再一次封装,强化了REST功能,并提供了与SQLite数据库和DICOM协议相关的接口。

Mongoose与Fossa的事件:

如上所述Fossa是基于事件驱动的,Mongoose是对Fossa的封装,因此同样采用事件驱动方式。但是两者的事件略有不同,如下表所示:

Fossa Mongoose

NS_CONNECT


MG_CONNECT


NS_RECV


MG_REQUEST


NS_SEND


MG_POLL


NS_POLL


MG_REPLY


NS_ACCEPT


MG_CLOSE


NS_CLOSE


MG_HTTP_ERROR

Fossa官网中对于HTTP请求中的事件做了较详细的介绍,如下表。可能是Mongoose对Fossa封装变动不大的原因,在Mongoose官网中并未找到关于MG_XXX事件的详细说明,文档API.md中只是介绍了各个事件的使用方式。

NS_ACCEPT:当监听端口接收到新的请求连接时,触发NS_ACCEPT事件
NS_CONNECT:当使用ns_connect创建新的连出连接时,无论新的连接创建失败还是成功,都触发NS_CONNECT事件
NS_RECV:当新数据接收完成且写入到接收缓冲区后,触发NS_RECV事件
NS_SEND:当数据被写入远程节点且从输出缓冲区清除后,触发NS_SEND事件
NS_POLL:NS_POLL会被发送到ns_mgr_poll的连接链表中的每个连接,用于进行清理工作(housekeeping),例如检测是否超时、发送心电包等等。
NS_CLOSE:连接断开时触发。【注】:具体的NS_CLOSE事件何时出发官方文档中并未给出,后续通过多组实例测试再详细介绍事件触发条件。

实例讲解:

实例测试:

简单的理论介绍后,已经大致了解了HTTP请求的流程。首先,需要绑定端口(在Windows下就是socket操作),建立TCP连接;然后再根据不同的事件进行相应的处理。         为了更直观的了解Mongoose中HTTP请求的具体流程,我们以安装说明文档Embbed.md中的例子为基础,在VS中添加NS_ENDALBE_DEBUG预定义,开启Mongoose源码中原本存在的调试信息;另外修改mongoose.c中的mg_ev_handler函数,对Fossa的每一种事件添加调试语句,输出当前事件类型。

1)重新生成MongooseEmbbed工程,开启调试状态;

2)打开谷歌浏览器,输入:http://localhost:8080,调试结果如下:

默认情况下Mongoose与其他Http Server相同,会默认显示当前目录下的文件。并添加了超链接。上图右侧就是MongooseEmbbed工程所在的主目录下所有文件的索引,并且已经给出了各个索引的超链接。

Mongoose事件触发流程调试:

从控制台输出的信息可以看出启动初期浏览器还未发起任何请求之前,程序处于主函数内的for循环中,循环输出调试信息;

当浏览器地址栏中输入http://localhost:8080后,接下来的for循环中,mg_poll_server函数输出了NS_ACCEPT调试信息,说明触发了NS_ACCEPT事件;

下一个循环中,同时输出了NS_POLL和NS_RECV两种事件的调试信息;

然后同时输出了NS_POLL、NS_SEND、NS_CLOSE三种事件调试信息;

最后进入NS_POLL的轮询状态,

从目前的调试信息来看,Mongoose对于浏览器发起的连接请求处理的基本流程遵循:NS_ACCEPT->NS_RECV->NS_SEND->NS_POLL->NS_CLOSE。这与Fossa官方说明基本相同,但是在整个流程中会出现多次NS_POLL和NS_ACCEPT,这究竟是什么原因呢?想要搞清楚整个问题,需要对HTTP
Web Server的整体响应流程有详细的了解,需要分析ns_poll_server源码中的具体流程。目前该部分思路还未整理完成,打算放到下一篇博文中,敬请关注。

作者:[email protected]

时间:2015-02-07

时间: 2024-10-05 13:31:16

DICOM:剖析Orthanc中的Web Server,Mongoose之“连接请求触发的事件序列”(二)的相关文章

DICOM:剖析Orthanc中的Web Server, Mongoose

背景: DICOM专栏文章中介绍过解构PACS(分布式PACS)Orthanc的安装和使用,以及相关插件.SQLite数据库等主要模块的分析,此次简单介绍Orthanc中嵌入的Web Server,Mongoose.依托于Mongoose这一轻量级Web Server,Orthanc很好的实现了RESTful API与传统DICOM服务的整合,这也是实现分布式PACS的关键.博文中先给出Mongoose的安装和简单的与C/C++的嵌入式编程,让大家对Mongoose有一个初步的认识,后续再深入分

DICOM:剖析Orthanc中的Web Server,Mongoose之 Flag bit & Event(三)

背景: Orthanc是本专栏中介绍过的一款新型DICOM服务器,具有轻量级.支持REST的特性,可将任意运行Windows和Linux系统的计算机变成DICOM服务器,即miniPACS.Orthanc内嵌多种模块,数据库管理简单,且不依赖于第三方软件.因此通过剖析Orthanc源码可以学习到搭建DICOM系统中的各个环节,例如SQLite嵌入型数据库.GoogleLog日志库.DCMTK医学DICOM库,以及近期要介绍的开源Web Server,Mongoose. 上一篇博文中简单的分析了M

ubuntu16.04-x64系统中Jexus web server部署.NetCore和端口分析引发的猜想!

您有这样的牢骚么? 有一周没更新博客了,简单说下在干什么吧:主要是公司安排对接某旅游大公司的接口,接口数量倒也就10个左右,对接完后还需要加入到业务系统中和App端,因此还是需要花点时间的:时间上来说业务需求安排在6月最后一周上线,整个3周的时间,就本人一人负责,由于在这之前对接过另外一个公司接口,我已经搭建好了整体架构和提供给app端接口了,因此主要还是对接某公司接口而已,至于细节上的东西改改后台系统,调调数据格式应该就差不多了:就本人开发的熟练度来讲一周时间基本能搞定,其他剩余时间就测试,喝

Tomcat是怎么工作的(2) -- 动手实现山寨版的简单Web Server

本文先讲解一下Java web server都是怎么工作的.web server也叫HTTP server——顾名思义它是用HTTP协议和客户端交互的.客户端一般就是各种各样的浏览器了.相信所有朋友都清楚这个基本事实,否则你也不会看到这个系列文章了. 基于Java的web server必然用到两个极其重要的类:java.net.Socket和java.net.ServerSocket,然后以HTTP消息进行交互. 1. HTTP协议简介(The Hypertext Transfer Protoc

转载的web server实例

asp.net—web server模拟网上购物 2014-05-08     我来说两句   来源:asp.net—web server模拟网上购物   收藏    我要投稿 在学vb的时候学到了api函数,今天学习asp.net中的web server,web server和api函数一样都是为用户提供了一个接口,客户端可以在远程直接调用,不需要知道它具体的算法,难易程度,可以直接使用方法. 一.基础 概念: 1.web服务是应用程序 2.它向外界暴露了一个能够通过web进行调用的api 3

Asp.net中的web.config配置

目录 Asp.net中的web.config配置... 1 一. 配置文件保存位置... 2 二. 配置文件加载顺序... 2 三. 配置文件节点介绍... 3 1. . 3 2. . 5 3. . 5 4. . 6 . 11 四. 针对配置文件的一些编程操作... 11 1. 运行时进行配置文件的修改... 11 2. 配置节点的加密... 12 web.config是asp.net中保存配置信息(比如数据库连接字符串等)的重要文件.它是基于xml的文本文件方式放在Web应用程序的任何目录中,

Web安全测试之跨站请求伪造(CSRF)篇

跨站请求伪造(即CSRF)被Web安全界称为诸多漏洞中“沉睡的巨人”,其威胁程度由此“美誉”便可见一斑.本文将简单介绍该漏洞,并详细说明造成这种漏洞的原因所在,以及针对该漏洞的黑盒测试与灰盒子测试具体方法和示例,最后提提了一些防范该攻击的建议,希望本文对读者的安全测试能够有所启发. 一.CSRF概述 我们首先来了解一下什么是跨站请求伪造(CSRF)?跨站请求伪造是一种挟制终端用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法.攻击者只要借助少许的社会工程诡计,例如通过电子邮件或者是聊天

DICOM医学图像处理:深入剖析Orthanc的SQLite,了解WADO & RESTful API

背景: 上一篇博文简单翻译了Orthanc官网给出的CodeProject上"利用Orthanc Plugin SDK开发WADO插件"的博文,其中提到了Orthanc从0.8.0版本之后支持快速查询,而原本的WADO请求需要是直接借助于Orthanc内部的REST API逐级定位.那么为什么之前的Orthanc必须要逐级来定位WADO请求的Instance呢?新版本中又是如何进行改进的呢?此篇博文通过分析Orthanc内嵌的SQLite数据库,来剖析Orthanc的RESTful A

DICOM:深入剖析Orthanc的SQLite,了解WADO&RESTful API

背景: 上一篇博文简单翻译了Orthanc官网给出的CodeProject上"利用Orthanc Plugin SDK开发WADO插件"的博文,其中提到了Orthanc从0.8.0版本之后支持快速查询,而原本的WADO请求需要是直接借助于Orthanc内部的REST API逐级定位.那么为什么之前的Orthanc必须要逐级来定位WADO请求的Instance呢?新版本中又是如何进行改进的呢?此篇博文通过分析Orthanc内嵌的SQLite数据库,来剖析Orthanc的RESTful A