- 浏览: 973071 次
- 性别:
- 来自: 珠海
文章分类
最新评论
-
Yunjey:
Yunjey 写道这样子的话、grid中的editable如何 ...
Flex创建可编辑以及分页的DataGrid -
Yunjey:
这样子的话、grid中的editable如何设置啊?!
Flex创建可编辑以及分页的DataGrid -
di1984HIT:
写的很好~~
JCalendar组件 -
sanny81:
此文真棒!感谢一路风尘的奉献!
但我有一疑 ...
Filter发送自定义数据详解 -
umgsai:
求完整demo umgsai@126.com
Flex和Jsp创建用户登入系统
作 者: sislcb
时 间: 2008-01-28,11:13:28
链 接: http://bbs.pediy.com/showthread.php?t=59015
这里来简单的讲解下驱动和应用层的异步通信,上次我写了驱动和应用层的三种基本通信方法,但是那三种方法都是通过同步的方法来实现的,就是说,在应用层向驱动层发送消息后,就堵死在那里等待驱动层的返回了,而异步的概念就是,应用层向驱动发送消息后,就马上返回了,而在驱动层的消息触发后,再将该消息反馈给应用层。
给个网上的例子:
同步就是你叫我去吃饭,我听到了就和你去吃饭;如果没有听到,你就不停的叫,直到我告诉你听到了,才一起去吃饭。
异步就是你叫我,然后自己去吃饭,我得到消息后可能立即走,也可能等到下班才去吃饭。
其实在明白了三种通信方式后,很容易使用异步方式来通信。
在调用DeviceIoControl时,不指定FILE_FLAG_OVERLAPPED标志,表示以同步方式调用,调用线程将被阻塞直到控制操作完成.
当指定FILE_FLAG_OVERLAPPED标志调用DeviceIoControl,表示以异步方式调用,调用线程不立即阻塞,直到调用线程需要结果时,调用者调用事件等待函数,等待驱动发出事件.
在异步调用时,得使用事件(event)来通信.
下面看应用层的代码:
// 初始化时创建设备 procedure TfrmMain.FormCreate(Sender: TObject); begin //创建设备 try m_hCommDevice := CreateFile('\\.\Overlapp', GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED, 0); //执行异步I/O的设备必须用FILE_FLAG_OVERLAPPED标志打开 hEvent := CreateEvent( nil, False, False, nil); //创建自动重置的事件 except MessageBox(Handle, '创建设备失败', '驱动应用层通信', MB_OK + MB_ICONWARNING); end; end; //异步通信按钮,创建线程和驱动通信 procedure TfrmMain.btnBufferdClick(Sender: TObject); var hThread:THandle; dwThreadID:DWORD; begin hThread := CreateThread(nil, 0, @WaitForNotify, self, 0, dwThreadID); CloseHandle(hThread); end; //线程的处理代码 //初始化一个OVERLAPPED 结构,然后用DeviceIoControl来通信 //在WaitForSingleObject等待返回 procedure WaitForNotify; var dwReturn: DWORD; inData:array[0..1023] of char; outData:array[0..1023] of char; ol:OVERLAPPED ; begin StrPCopy(inData, Trim(frmMain.edtBufferd_in.Text)); //OVERLAPPED结构的Offset,OffsetHigh和hEvent成员必须被初始化。在这里初始化为0 FillMemory(@ol, sizeof(OVERLAPPED), 0); ol.hEvent := frmMain.hEvent; if frmMain.m_hCommDevice <> 0 then DeviceIoControl(frmMain.m_hCommDevice, IOCTL_OVERLAP_BUFFERED_IO, @inData, Length(inData), @outData, Length(outData), dwReturn, @ol); //调用WaitForSingleObject并传递设备内核对象的句柄。WaitForSingleObject会挂起调用线程直至内核对象变成有信号态。 //设备驱动在它完成I/O后使内核对象有信号。在WaitForSingleObject返回后,I/O被完成 . while WaitForSingleObject(frmMain.hEvent, 100) = WAIT_TIMEOUT do begin end; GetOverlappedResult(frmMain.m_hCommDevice, ol, dwReturn, TRUE); frmMain.edtBufferd_out.Text := outData; end; //这里触发驱动将数据传输回来,异步消息得以完成 procedure TfrmMain.btnNotifyClick(Sender: TObject); var dwReturn:DWORD; begin if m_hCommDevice <> 0 then DeviceIoControl(m_hCommDevice, IOCL_OVERLAP_NOTIFY, nil, 0, nil, 0, dwReturn, nil); end; //退出时,关闭句柄,这时候如果irp还未处理,即btnNotifyClick这个函数没有触发 //则驱动中会触发取消irp的请求。 procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction); begin if(m_hCommDevice <> 0) then CloseHandle(m_hCommDevice); if (hEvent <> 0) then CloseHandle(hEvent); end;
驱动层代码
//接受到消息的处理函数 NTSTATUS Overlap_IoControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS status = STATUS_NOT_SUPPORTED; PIO_STACK_LOCATION irpStack = NULL; UINT sizeofWrite = 0; DbgPrint("Overlap_IoControl\r\n"); irpStack = IoGetCurrentIrpStackLocation(Irp); if(irpStack) { switch(irpStack->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_OVERLAP_BUFFERED_IO: //异步通信消息 status = Irp->IoStatus.Status = STATUS_PENDING; Irp->IoStatus.Information = 0; IoMarkIrpPending(Irp); gUserMessageIrp = Irp;//保存请求的irp IoSetCancelRoutine(Irp, DriverCancelIrp); //设置irp取消例程,在应用程序退出时,触发 return status; case IOCL_OVERLAP_NOTIFY: //获取数据事件 COMM_BufferedIo(gUserMessageIrp, irpStack); //处理原来的irp,将传进来的数据传输出去 return status; default: return status; } } return status; } //当通知要获取数据时,获得异步的irp,然后传输数据 NTSTATUS COMM_BufferedIo(PIRP Irp, PIO_STACK_LOCATION pIoStackIrp) { NTSTATUS status = STATUS_UNSUCCESSFUL; PVOID pInputBuffer, pOutputBuffer; ULONG outputLength, inputLength; DbgPrint("COMM_BufferedIo\r\n"); outputLength = pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength; inputLength = pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength; pOutputBuffer = Irp->AssociatedIrp.SystemBuffer; //输出缓冲区 pInputBuffer = Irp->AssociatedIrp.SystemBuffer; //输入缓冲区 if(pInputBuffer && pOutputBuffer) { DbgPrint("COMM_BufferedIo UserModeMessage = '%s'", pInputBuffer); RtlCopyMemory(pOutputBuffer, pInputBuffer, outputLength); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof(pOutputBuffer); IoCompleteRequest(Irp,IO_NO_INCREMENT); //设置该irp已经完成 status = STATUS_SUCCESS; } return status; } //取消irp的例程 VOID DriverCancelIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { //UNREFERENCED_PARAMETER这个宏用于去掉一个函数的参数未用或函数中定义了一个局部变量却从未用过的编译警告 UNREFERENCED_PARAMETER(DeviceObject); KdPrint(("UserMessageCancelIrp....\n")); if ( Irp == gUserMessageIrp) gUserMessageIrp = NULL; Irp->IoStatus.Status = STATUS_CANCELLED; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp,IO_NO_INCREMENT); }
流程如下:
1、
应用层:
通知异步消息
等待返回
驱动层:
收到消息
设置irp取消例程
保存该irp
2、
应用层:
通知获取数据,即完成异步消息
驱动层:
拷贝数据到输出缓冲区,完成该irp
在这里我是通过手动的方式来触发异步消息的完成,而不是由系统的消息触发的。主要是为了演示的方便
发表评论
-
Filter驱动:过滤(修改)接受数据包
2010-04-20 16:18 9340Filter驱动可以实现简单的防火墙功能。它可以过滤所有接收到 ... -
Ndis过滤驱动:拷贝NetBufferList数据
2010-04-19 22:40 9569今天我们来看看如何拷贝NBL中的数据。有时候需要更改数据包中的 ... -
在Filter驱动内核中获取IP地址
2010-04-18 01:48 3900项目开发中有时候需要在Filter驱动中获取有效地Unic ... -
如何在内核中获得当前系统时间
2010-04-16 15:08 2734在 Windows NT 内核中你是无法使用 tim ... -
Filter发送自定义数据详解
2010-04-16 10:30 5767... -
DebugPrint 格式说明符
2010-04-13 19:46 17691) 直接打印字符串。 DbgPrint(“Hello ... -
WDK+Visual Studio 2008配置编译驱动
2010-04-12 23:36 5571Introduction As it is known, ... -
疑问:关于内存释放
2010-04-12 21:33 1460今天碰到一个比较棘手的内存处理问题。 首先来看一个数据结构: ... -
Windows NT 驱动程序开发人员提示 -- 应注意避免的事项
2010-04-10 11:32 2330原讨论链接: http://community.cs ... -
关于DeviceIoControl实现异步的笔记【2】
2010-04-09 23:17 5112前面我们谈到了关于异步I/O的实现:关于DeviceIoCon ... -
关于DeviceIoControl实现异步的笔记【1】
2010-04-08 22:26 11760一直所做的都是同步实现的。当然很多情况这并不是很好的解决问题。 ... -
Windows系统编程之异步I/O和完成端口
2010-04-08 19:40 2335一、 同步I/O和异步I/O ... -
纵横捭阖C++之从异步谈起
2010-04-08 19:31 3232一般来说,简单的异步(Asynchronous)调用是这样一种 ... -
使用DeviceIoControl通信
2010-04-04 22:53 7926在很多时候,某些用户需要与底层驱动有一个交互式的操作,所 ... -
在驱动中使用链表
2010-04-03 14:06 3296文章作者:grayfox 作 ... -
疑问:数据包Length增大的原因
2010-04-01 14:35 1373现象: 自己定义一个仅含有Ethernet Header的数 ... -
疑问:为何无线网卡无法发送数据?
2010-03-30 22:42 4571所有的测试流程表明,程序已经成功的创建新的数据包,然后调用Nd ... -
InsertHeadList和CONTAINING_RECORD
2010-03-29 16:36 3760LIST_ENTRY定义一个双向链表的数据结构: typed ... -
如何区分不同的Filter Module Instance
2010-03-29 14:50 1547前文 说到如何区分不同Filter Module Inst ... -
大数据是否需要封装在多个MDL中发送
2010-03-27 21:40 2525前段时间,我们已经解决如何发送自定义的网络数据。那么接下来要做 ...
相关推荐
其次,消息队列是一种异步通信机制,它允许驱动程序和应用层之间传递结构化的数据包。应用层将消息放入队列,驱动程序则在需要时从队列中取出并处理。这种方式特别适合于那些不需立即响应或者处理时间不确定的通信...
在IT领域,尤其是在系统开发和硬件交互中,事件应用程序和驱动通信同步是至关重要的技术环节。事件是操作系统中用于进程间通信(IPC)的一种机制,它允许一个或多个线程等待特定条件的发生,如文件完成写入、网络...
本文介绍了基于事件驱动和异步通信体系结构的Web服务器设计思想,并详细讨论了其关键技术——适配子层aSocket的设计与实现。通过实验证明,这种设计能够显著提高服务器的并发处理能力和性能。未来的研究方向可以...
异步通信通常涉及事件驱动编程,其中最常用的是回调函数和I/O复用技术,如多路复用I/O(select、poll、epoll等)。当一个socket上的事件发生时,如数据到达或连接请求,操作系统会通知应用程序,而不是让程序阻塞...
异步通信通常基于事件驱动或回调机制。当网络事件发生时,比如数据到达,系统会通知应用程序,而不是让应用程序一直等待。这种方式使得程序能够在多任务间快速切换,提高了整体性能,特别适合于高并发场景,如服务器...
2. **事件驱动编程**:异步通信通常与事件驱动编程模型相结合。在这种模型中,程序会注册对特定事件(如数据到达或连接建立)的监听,当这些事件发生时,程序通过回调函数来响应。 3. **IOCP(I/O完成端口)**:在...
综上所述,C#的Socket异步通信不仅涉及到基础的网络编程概念,还包括了高级的异步编程技术,如事件驱动、委托和async/await。通过理解和熟练掌握这些知识点,开发者能够构建出高效、健壮的网络应用程序。FastSocket...
学习这个程序集,不仅可以了解TCP和UDP的基础知识,还能深入理解MFC在网络编程中的应用,掌握同步与异步通信的区别和实现方式。这对于提升网络编程技能,尤其是开发涉及网络通信的应用程序,是非常有价值的。
总结,Linux下的UART串口通信涉及硬件驱动、应用层接口和C语言编程。理解和掌握这些知识点,对于开发需要串口通信的项目至关重要。通过实际编写和调试应用层代码,你可以深入理解UART通信的工作原理及其在Linux环境...
这种方式提供了可靠的异步通信,适用于大量数据交换。 4. **文件系统流**:通过在特定文件中写入数据,Minifilter驱动程序可以在读取文件时获取信息。这种方式需要确保数据格式的一致性和安全性。 5. **设备驱动...
在实验中,QP框架的QF部分充当软件总线,通过事件分发机制处理来自按键的事件,实现了活动对象的异步通信。这种设计使得事件可以在系统中松散耦合的组件间高效传播,增强了系统的灵活性。 综上所述,基于STM32的...
同时,过滤驱动中也需要掌握如何分配和管理NetBufferListPool,以及如何通过DeviceIoControl进行驱动程序与应用层的异步通信。 在遇到驱动程序中的bug和错误时,例如DRIVER_CORRUPTED_EXPOOL错误,需要有能力对内核...
在TCP/IP模型中,Socket位于传输层和应用层之间,它为应用程序提供了一种标准的方式来创建网络连接。 服务器端的Socket编程通常包括以下步骤: 1. 创建Socket:通过调用`socket()`函数创建一个Socket对象。 2. 绑定...
本篇文章将深入探讨基于Java的进程间异步通信系统的设计与实现,特别关注其在Android环境中的应用。 首先,我们需要理解什么是进程间通信。进程是操作系统分配资源的基本单位,而进程间的通信则是不同进程之间交换...
同步通信和异步通信是单片机通信的两种主要类型,它们各有特点和适用场景。 1. **同步通信**: 同步通信是一种严格的时序通信方式,两个通信节点必须遵循相同的时钟信号进行数据交换。这意味着发送端和接收端都必须...
Mina的核心特性是其异步通信模型,它允许应用程序在不阻塞线程的情况下处理大量并发连接,从而提高了系统的吞吐量和响应速度。 1. **异步通信**:在Mina中,I/O操作是非阻塞的,这意味着当一个I/O请求被发起时,...
总结来说,Android上层应用与驱动的交互是一个涉及Apk、JNI、HAL和DRV的多层通信过程。Apk通过JNI调用HAL接口,HAL封装硬件操作并调用相应的驱动,驱动则直接控制硬件设备。这种层次化的架构使得Android系统能够灵活...
3. **驱动层与应用层交互**:在基于驱动层的串口通信中,应用层通过系统调用或者API与驱动层交互。例如,应用可以调用`write()`函数发送数据,`read()`函数接收数据,而驱动层则负责实际的数据传输操作。 4. **电信...
NDIS(Network Driver Interface Specification)协议层中间层驱动程序是网络驱动程序模型中的一个重要组成部分,它位于网络适配器驱动程序(称为NDIS微型端口驱动程序)和上层协议驱动程序之间,如TCP/IP协议栈。...
- **示例**:在客户端,可以通过在不同的线程中处理连接、接收和发送数据等操作来实现高效的异步通信。 ##### 5. 实现细节 - **客户端示例**: - 创建一个新类`ClientSocket`继承自CAsyncSocket。 - 在类中声明...