WINDOWS平台下使用ACE框架的异步串口操作
2013-07-02 09:42
351 查看
利用ACE当中的包装类进行串口操作在ACE目录下的examples/IPC_SAP/DEV_SAP有例子做详细介绍。但是这里的例子是阻塞模式的。于是我试图使用ACE当中的一些框架来做一个异步的串口操作。
ACE当中可以使用的异步操作框架有Reactor和Proactor等。Reactor采用Bridge模式有多个实现,在Windows下面默认的实现是ACE_WFMO_Reactor,他内部使用WaitForMuiltiObject来等待OVERLAPPED当中的event句柄,LINUX下使用ACE_Select_Reacotr实现,内部使用select函数来分配操作。当然在WINDOWS平台下我们也可以手动来指定使用ACE_Select_Reactor作为Reactor引擎的实现。然而在WINDOWS下select函数只能对socket句柄进行分配,因此我们不能使用这个实现的Reactor引擎来进行异步的串口操作。于是,我们开始考虑默认的ACE_WFMO_Reactor实现来进行异步串口操作的开发,但是这种实现当中他调用了WSAEventSelect,这是一个WIN
SOCKET的API,当然他也只适用于SOCKET句柄。至此,我放弃了Reactor引擎,转而考虑Proactor引擎来实现异步操作串口的功能。
Proactor引擎在WINDOWS上使用的是Completion Port,因此我们可以做一个合理的假设,Read/WriteFile这些函数可以用Completion Port来实现异步操作,而一个串口在WIN32 API当中用CreateFile打开然后用Read/WriteFile来进行读写操作,于是他应该能用Completion Port进行异步操作,并且也应该可以使用Proactor引擎来实现异步操作。经过查询相关文档和自己的一些试验,表明确实可以使用Proactor引擎来进行异步操作,但其中有几个要点:
1.使用ACE_DEV_Connector::connect来打开串口时,flag参数一定要加上FILE_FLAG_OVERLAPPED标志。
2.ACE_TTY_IO::Serial_Params当中的readtimeoutmsec字段对ACE_Handler最后的回调有一定的影响。如果设置一个大于等于零的值,那么无论有没有数据到达,ACE_Handler的相关read回调函数都会定时被回调一次,如果没有数据到达,那么result.bytes_transferred()为0;如果设置成-1,那么就没有超时,read回调也会只在有实际数据到达时才会被调用。
3.提交异步操作的两个Asynch_IO对象应该是ACE_Asynch_Read_File和ACE_Asynch_Write_File,用来提交的函数分别是read和write。
4.ACE_Handler当中用来表示操作完成的回调函数是handle_read_file和handle_write_file。
5.在handle_read_file被回调的时候特别要注意检查result.bytes_transferred()。可能会有接收到不完整的数据包的现象,这可能与你设置的ACE_TTY_IO::Serial_Params当中的readmincharacters字段有关。
6.其余部分与普通的proactor操作一致。
具体的步骤是:
1.初始化一个Proactor实例,并且运行Proactor事件循环。
2.使用ACE_Dev_Connector和ACE_Dev_Addr来打开一个串口,得到一个ACE_TTY_IO对象。
3.创建一个继承自ACE_Handler的对象,把2中的ACE_TTY_IO对象传给他。
4.ACE_Handler内部的ACE_Asynch_Read/Write_File对象使用ACE_TTY_IO::get_handle()以及3中的ACE_Handler对象初始化。
5.使用ACE_Asynch_Read/Write_File对象提交异步操作。
6.处理Proactor回调的handle_read_file和handle_write_file函数,并重新投递操作请求。
总结:
ACE库给了我们很多方便的类,但是要想真正很好地使用它,我们还是需要了解操作系统的一些API的限制以及ACE底层的各种实现所包装的系统API,这个可以通过多看ACE源码的方式来进行提高。本文所说的方法是针对Windows平台的,在Linux平台下由于select函数没有那些限制,因此我们可以使用默认实现的Reactor引擎来进行异步的串口操作。
环境:
OS:Windows XP Service Pack 3
ACE: 5.6.9
IDE:Visual Studio 2005
原文地址:/article/9376437.html
ACE当中可以使用的异步操作框架有Reactor和Proactor等。Reactor采用Bridge模式有多个实现,在Windows下面默认的实现是ACE_WFMO_Reactor,他内部使用WaitForMuiltiObject来等待OVERLAPPED当中的event句柄,LINUX下使用ACE_Select_Reacotr实现,内部使用select函数来分配操作。当然在WINDOWS平台下我们也可以手动来指定使用ACE_Select_Reactor作为Reactor引擎的实现。然而在WINDOWS下select函数只能对socket句柄进行分配,因此我们不能使用这个实现的Reactor引擎来进行异步的串口操作。于是,我们开始考虑默认的ACE_WFMO_Reactor实现来进行异步串口操作的开发,但是这种实现当中他调用了WSAEventSelect,这是一个WIN
SOCKET的API,当然他也只适用于SOCKET句柄。至此,我放弃了Reactor引擎,转而考虑Proactor引擎来实现异步操作串口的功能。
Proactor引擎在WINDOWS上使用的是Completion Port,因此我们可以做一个合理的假设,Read/WriteFile这些函数可以用Completion Port来实现异步操作,而一个串口在WIN32 API当中用CreateFile打开然后用Read/WriteFile来进行读写操作,于是他应该能用Completion Port进行异步操作,并且也应该可以使用Proactor引擎来实现异步操作。经过查询相关文档和自己的一些试验,表明确实可以使用Proactor引擎来进行异步操作,但其中有几个要点:
1.使用ACE_DEV_Connector::connect来打开串口时,flag参数一定要加上FILE_FLAG_OVERLAPPED标志。
2.ACE_TTY_IO::Serial_Params当中的readtimeoutmsec字段对ACE_Handler最后的回调有一定的影响。如果设置一个大于等于零的值,那么无论有没有数据到达,ACE_Handler的相关read回调函数都会定时被回调一次,如果没有数据到达,那么result.bytes_transferred()为0;如果设置成-1,那么就没有超时,read回调也会只在有实际数据到达时才会被调用。
3.提交异步操作的两个Asynch_IO对象应该是ACE_Asynch_Read_File和ACE_Asynch_Write_File,用来提交的函数分别是read和write。
4.ACE_Handler当中用来表示操作完成的回调函数是handle_read_file和handle_write_file。
5.在handle_read_file被回调的时候特别要注意检查result.bytes_transferred()。可能会有接收到不完整的数据包的现象,这可能与你设置的ACE_TTY_IO::Serial_Params当中的readmincharacters字段有关。
6.其余部分与普通的proactor操作一致。
具体的步骤是:
1.初始化一个Proactor实例,并且运行Proactor事件循环。
2.使用ACE_Dev_Connector和ACE_Dev_Addr来打开一个串口,得到一个ACE_TTY_IO对象。
3.创建一个继承自ACE_Handler的对象,把2中的ACE_TTY_IO对象传给他。
4.ACE_Handler内部的ACE_Asynch_Read/Write_File对象使用ACE_TTY_IO::get_handle()以及3中的ACE_Handler对象初始化。
5.使用ACE_Asynch_Read/Write_File对象提交异步操作。
6.处理Proactor回调的handle_read_file和handle_write_file函数,并重新投递操作请求。
总结:
ACE库给了我们很多方便的类,但是要想真正很好地使用它,我们还是需要了解操作系统的一些API的限制以及ACE底层的各种实现所包装的系统API,这个可以通过多看ACE源码的方式来进行提高。本文所说的方法是针对Windows平台的,在Linux平台下由于select函数没有那些限制,因此我们可以使用默认实现的Reactor引擎来进行异步的串口操作。
环境:
OS:Windows XP Service Pack 3
ACE: 5.6.9
IDE:Visual Studio 2005
原文地址:/article/9376437.html
相关文章推荐
- WINDOWS平台下使用ACE框架的异步串口操作
- 使用Win32API实现Windows下异步串口通讯、
- 使用Win32API实现Windows下异步串口通讯
- Maemo Linux手机平台系列分析:10 Maemo平台开发之 使用Glib/D-Bus做异步操作
- 随笔记:如何使用Python连接(/操作)Oracle数据库(Windows平台下)
- Windows关机函数ExitWindowsEx使用大全(适用Windows所有操作平台)
- windows c++使用hiredis异步操作
- 一种在windows平台下实现自动操作应用的方法,附带源码地址及使用方法
- 使用Win32API实现Windows下异步串口通讯
- Windows下使用Cordova跨平台框架开发的成功的第一个android项目
- VC------Windows关机函数,休眠函数使用大全(适用Windows所有操作平台)
- 在Windows平台上使用Codeblocks开发基于wxWidgets框架应用程序的开发环境准备
- 使用Win32API实现Windows下异步串口通讯
- Windows平台python操作串口示例,可以加工下,改写成方便的测试软件
- C#实现多级子目录Zip压缩解压实例 NET4.6下的UTC时间转换 [译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了 asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程 asp.net core异步进行新增操作并且需要判断某些字段是否重复的三种解决方案 .NET Core开发日志
- 【阿里云产品公测】在Laravel4框架中使用阿里云ACE的缓存服务
- 使用异步httpclient框架做get,post提交数据
- 在Windows平台使用Apache2.2和Mongrel运行Ruby on Rails
- 使用JAVA操作netty框架