原创翻译 在Windows CE上实现一个全功能的webserver

简介: 本文转载自微软嵌入式中文社区 www.msembed.com  摘要当开发人员在Windows CE上实现一个webserver时,他们通常会想到要实现PC平台上的webserver有的大多数的功能。

本文转载自微软嵌入式中文社区 www.msembed.com

 

 

摘要
当开发人员在Windows CE上实现一个webserver时,他们通常会想到要实现PC平台上的webserver有的大多数的功能。但是对于Windows CE IIS来说这不可行。Windows CE IIS对于有些功能特性不支持,例如过程标号(session ID).本文描述了如何通过互联网服务器应用程序编程接口(ISAPI)来实现这些功能特性。最后,文章用一个例子来说明如何来做这件事情。

结构图

 

Isapi扩展动态连接库
Windows CE IIS不支持Web服务器有时需要的两项功能,它们是
 

  • 事务间的状态(States between Transactions)
  • 过程标号的管理

 

ISAPI(Internet server application programming interface)扩展可以使我们支持这些特性。以下部分是怎样来实现。

 


ISAPI被开发出用来给应用程序开发人员一个有力的方法来扩展IIS的功能。为了生成Windows CE Web Server的ISAPI扩展,需要编译生成一个动态连接库,该动态连接库导出如下标准ISAPI入口:
GetExtensionVersion
HttpExtensionProc
TerminateExtension (可选)
  

 

GetExtensionVersion在动态连接库第一次被装载时被调用,HttpExtensionProc在每个接入请求来到时都被调用,TerminateExtension在动态连接库被卸载时被调用。和Web服务器的交互通过标准的ISAPI回调函数来进行,比如ReadClient和WriteClient等。
 

 

因为所有的请求都只被这个动态连接库处理,所以以下功能可以被实现:
 

  • 过程标号(Session Id)的管理
  • 提供登录认证
  • 发送定制化文件
  • 一些实时变量,例如CPU的温度、使用情况、风扇转速、连结的设备和IP设置等都可以轻松地通过调用对应的API而获得并嵌入页面中。
     

 

怎样装载ISAPI扩展动态连接库
 除了编译过程中加入web server组件外,还需加入以下的注册表项来实现动态连接库的自动装载:
[HKEY_LOCAL_MACHINE/COMM/HTTPD/VROOTS//]
  @="//windows//sampleisapi.dll"
"a"=dword: 0 ;用于移除认证
 Web服务器在收到来自任意客户端的一个请求后将装载此动态连接库。此动态连接库可以处理任意数量的客户端的请求。
 
 

被导出的函数
 HttpExtensionProc在每个请求到来后都被调用。对此请求的处理在此函数中进行。
 1.GetExtensionVersion
此函数在动态连接库第一次被装载时调用。

 

2.HttpExtensionProc

这是此动态连接库唯一重要的函数。此函数在每个请求到来后都被调用。GetServerVariable函数可以用来获得查询字符串值,根据收到的查询结果,用WriteClient 函数可以将相应的被请求文件写回到客户端。若需从客户端读取数据,可以使用ReadClient函数。
 此函数的原型如下:

DWORD WINAPI HttpExtensionProc (LPEXTENSION_CONTROL_BLOCK lpECB);

这里的 LPEXTENSION_CONTROL_BLOCK 被声明如下.

typedef struct _ EXTENSION_CONTROL_BLOCK 
{

 

DWORD cbSize
DWORD dwVersion
HCONN ConnID
DWORD dwHttpStatusCode
CHAR lpszLogData[HSE_LOG_BUFFER_LEN]; 
LPSTR lpszMethod
LPSTR lpszQueryString
LPSTR lpszPathInfo
LPSTR lpszPathTranslated
DWORD cbTotalBytes
DWORD cbAvailable
LPBYTE lpbData
LPSTR lpszContentType
BOOL (WINAPI* GetServerVariable); 
BOOL (WINAPI* WriteClient); 
BOOL (WINAPI* ReadClient); 
BOOL (WINAPI* ServerSupportFunction);

EXTENSION_CONTROL_BLOCK, LPEXTENSION_CONTROL_BLOCK;

3.TerminateExtension

此函数在动态连接库被卸载时调用。  

GetServerVariable
GetServerVariable函数被用来获取服务器变量,例如IP地址,查询字符串等。
1.原型
BOOL WINAPI GetServerVariable(HCONN hConn, LPSTR lpszVariableName, VOID lpvBuffer, LPDWORD lpdwSizeofBuffer );
 

 

2.参数
hConn
指定连结句柄。这是HttpExtensionProc函数的输入参数。
lpszVariableName

一个NULL结尾的字符串用以标明被请求的服务器变量。
lpvBuffer

指向接受被请求信息的缓冲区。
lpdwSizeofBuffer
指向一个DWORD变量,该变量表明了lpvBuffer指向的缓冲区的大小。在成功调用后,此DWORD值为传到缓冲区的字节数目,包括Null结尾字节。
一些可以用GetServerVariable函数来获取的重要变量如下:
PATH_INFO 由客户端给出的URL的尾部路径信息。
QUERY_STRING 指定了URL中的第一个问号后的信息。
REMOTE_ADDR 指定了客户端的IP地址。

实现示例
正如已经提到的,ISAPI扩展动态连接库的主要用途是管理过程标号(session id)和获得一些实时参数如IP地址设置等。

 


1.用字符串参数调用外部动态连接库并将返回结果插入到发送给客户端的HTML输出中
我们刚才已经提到,要发送给客户端的html和java脚本文件是在存储设备上已有的。现在在存储这些文件之前,一些特殊符号可以被包含在html文件中来提示ISAPI动态连接库这些符号应被替换为一些实时变量。例如以下格式可以被包含在html文件里
!!DllName!!FunctionName!!

 


例如如果你想显示设备的IP地址,你可以加入如下的符号序列来告诉ISAPI将此符号序列替换为IP地址。
!!NetStatusDll!!GetIPAddress!!

 


在将文件发送到客户端之前,ISAPI动态连接库会解析文件中的符号序列。当找到以上序列后,将替换序列中的DllName和FunctionName。装载动态连接库后将调用解析到的函数,并将序列替换为函数返回的字符串。在上面这个例子中,NetStatus.dll通过调用LoadLibrary API被装载,函数GetIPAddress的地址通过调用GetProcAddress API而获得,最后函数GetIPAddress被调用。

 


同样地,当使用者希望设置设备上的实时变量时,发出的消息数据也可以包含符号序列。例如如果使用者希望从远程客户端为设备设置IP地址时,带有DllName和FunctionName的符号序列可以被加入到点击网页上的某个按钮时发出的消息数据中。

 


2.管理过程标号
    可以生成下表来管理过程标号:

  IP地址

  过程标号

  最后的Tick (ms)

   176.234.11.23

   12avcdefdef

   10000

   23.123.45.6

   234rfvdadds

   23456

   145.67.89.90

   123456asdfg

   45678


 当从一个新的客户端(例如新的IP地址)收到请求后,一个随机过程标号被生成并分配给该IP地址,同时此标号被存入XML数据库中。不论什么时候从任何客户端收到请求后,该表中的数据将被检查,如果对应的客户端项已存在于表中,则网页内容将被发送至客户端。如果客户端项不存在,那么只有登录页面被发送至客户端。表中的最后Tick数可以用来判断过程是否超时。

 


 总结
 本文解释了Isapi扩展动态连接库的用法。Isapi扩展动态连接库多用于需要使用一些实时变量如CPU温度,IP地址设置等的网页文件中。

相关文章
|
3月前
|
存储 算法 C++
【Qt应用开发】复刻经典:基于Qt实现Windows风格计算器(加减乘除、删除、归零功能全解析)
在Qt中,"栈"的概念主要体现在两个层面:一是程序设计中的数据结构——栈(Stack),二是用户界面管理中的QStackedWidget控件。下面我将分别简要介绍这两个方面:
122 4
|
15天前
|
Linux Android开发 iOS开发
Windows平台RTSP|RTMP播放器如何实现实时录像功能
Windows平台RTSP、RTMP播放器实时录像接口设计,实际上,除了Windows平台,我们Linux、Android、iOS平台也是一样的设计,单纯的录像模块,如果做的全面,也不是一两个接口可以搞定的
|
2月前
|
存储 开发者 C#
WPF与邮件发送:教你如何在Windows Presentation Foundation应用中无缝集成电子邮件功能——从界面设计到代码实现,全面解析邮件发送的每一个细节密武器!
【8月更文挑战第31天】本文探讨了如何在Windows Presentation Foundation(WPF)应用中集成电子邮件发送功能,详细介绍了从创建WPF项目到设计用户界面的全过程,并通过具体示例代码展示了如何使用`System.Net.Mail`命名空间中的`SmtpClient`和`MailMessage`类来实现邮件发送逻辑。文章还强调了安全性和错误处理的重要性,提供了实用的异常捕获代码片段,旨在帮助WPF开发者更好地掌握邮件发送技术,提升应用程序的功能性与用户体验。
40 0
|
2月前
|
API C# Shell
WPF与Windows Shell完美融合:深入解析文件系统操作技巧——从基本文件管理到高级Shell功能调用,全面掌握WPF中的文件处理艺术
【8月更文挑战第31天】Windows Presentation Foundation (WPF) 是 .NET Framework 的关键组件,用于构建 Windows 桌面应用程序。WPF 提供了丰富的功能来创建美观且功能强大的用户界面。本文通过问题解答的形式,探讨了如何在 WPF 应用中集成 Windows Shell 功能,并通过具体示例代码展示了文件系统的操作方法,包括列出目录下的所有文件、创建和删除文件、移动和复制文件以及打开文件夹或文件等。
50 0
|
2月前
|
C# Windows 监控
WPF应用跨界成长秘籍:深度揭秘如何与Windows服务完美交互,扩展功能无界限!
【8月更文挑战第31天】WPF(Windows Presentation Foundation)是 .NET 框架下的图形界面技术,具有丰富的界面设计和灵活的客户端功能。在某些场景下,WPF 应用需与 Windows 服务交互以实现后台任务处理、系统监控等功能。本文探讨了两者交互的方法,并通过示例代码展示了如何扩展 WPF 应用的功能。首先介绍了 Windows 服务的基础知识,然后阐述了创建 Windows 服务、设计通信接口及 WPF 客户端调用服务的具体步骤。通过合理的交互设计,WPF 应用可获得更强的后台处理能力和系统级操作权限,提升应用的整体性能。
74 0
|
2月前
|
Kubernetes Cloud Native 开发者
探索云原生技术:Kubernetes入门与实践探索Windows操作系统的隐藏功能
【8月更文挑战第31天】在数字化转型的浪潮中,云原生技术成为企业提升敏捷性、效率和可靠性的关键。本文将带你了解云原生的核心组件之一——Kubernetes(K8s),通过浅显易懂的语言和实际代码示例,引导你步入这一强大工具的世界。无论你是初学者还是有经验的开发者,本篇都将为你打开一扇通向高效资源管理与自动化部署的大门。
|
2月前
|
编解码 开发工具 C#
[大牛直播SDK]Windows平台RTMP直播推送模块功能设计
大牛直播SDK采用全自研框架,具备高度可扩展性与自适应算法,显著降低延迟并提高采集编码效率。SDK以模块化设计,支持RTMP推流及多种音视频编码格式(如AAC、SPEEX、H.264、H.265),并能与播放器SDK组合实现丰富功能,包括流媒体转发、内置RTSP服务等。提供了详尽的参数配置选项,支持多摄像头、屏幕采集与水印叠加,并兼容Windows 7及以上操作系统。该SDK以C++/C#双接口形式提供,集成简便,同时包含调试与发布版本库,便于开发者快速上手。此外,支持断网重连、实时预览及多种编码前后的数据对接需求。
|
4月前
|
人工智能 安全 数据库
Windows的新Recall功能:隐私和安全的噩梦?
Windows的新Recall功能:隐私和安全的噩梦?
|
3月前
|
C# 开发者 Windows
4款.NET开源、功能强大的Windows桌面工具箱
4款.NET开源、功能强大的Windows桌面工具箱
|
4月前
|
网络架构 Windows
windows电脑开机自动启动FRP客户端CMD代码,增加延时15秒功能
经常使用FRP客户端的都知道,FRP客户端启动时需要电脑有网络,否则会自动退出。我们的电脑在启动时,受路由器网络的影响,很多时间并不能第一时间建立起网络来,所以很容易受到网络影响,让FRP客户端自动启动发生故障。而这里的解决办法就是增加一段代码,可以延时15秒再执行。