问题

在一次实验中,我需要程序可以自动检测到网络变化,例如:

1) 某一个或某几个网卡被禁用

2) 某一个或某几个网卡的地址变化

NotifyAddrChange可以帮我做到这些。今天来讲一讲这个函数的用法及程序功能在架构阶段需要注意的地方。

如何使用NotifyAddrChange

NotifyAddrChange函数主要的功能是用来通知应用程序IPv4地址的变化。注意这个函数仅仅支持IPv4地址的变化,如果需要得到IPv6地址的变化,请使用NotifyIpInterfaceChange。但这个函数,不在今天的内容范围。

我们先来看函数原型:

DWORD NotifyAddrChange(

PHANDLE Handle,

LPOVERLAPPED overlapped

);

参数:

Handle: 这里需要提供一个指向HANDLE的指针,当函数成功执行后,此指针将指向一个文件句柄,我们可以使用这个句柄来调用GetOverlappedResult来获取重叠I/O操作的详细信息。

overlapped:一个指向OVERLAPPED结构体的指针,此结构体主要包含了重叠I/O的信息。

从以上两个参数可以看出,NotifyAddrChange这个函数支持异步操作,也即重叠I/O操作。

重叠I/O

在Win32 API层面,某些涉及I/O的函数的执行模式可以是同步的,也可以是异步的,比如WriteFile,ReadFile, DeviceIoControl。

当一个函数以同步的方式执行时,它会一直等待I/O操作执行完成,也即,调用这个函数的线程会阻塞。

当一个函数以重叠I/O的方式执行时,这个函数会立即返回,不管I/O操作是否完成。这个执行模式可以使得较为耗时的I/O操作在后台执行,调用线程可以继续执行其他任务。

那么,如何知道I/O操作是否执行完成呢?

有以下两种方法

1) 通过使用GetOverlappedResult来等待I/O操作是否完成。GetOverlappedResult的升级版GetOverlappedResultEx还可以指定一个等待超时时间。在这种情况下,我们需要将 GetOverlappedResult的最后一个bWait参数设置成TRUE。

2) 在初始化OVERLAPPED结构体时,我们指定一个手动重置的事件对象句柄,然后执行I/O函数调用,此时I/O函数因为执行重叠I/O会立即返回,如果想知道操作什么时候完成,可以使用WaitForSingleObject来等待这个事件句柄,等待成功后,继续使用GetOverlappedResult来获取I/O操作的更详细的操作结果,例如,本次I/O操作实际传输的多少个字节。

如果需要取消重叠I/O,我们可以使用CancelIoEx并传递一个OVERLAPPED结构体,此结构体包含待取消的目标句柄,此函数将尝试取消正在进行的I/O操作。

返回值

NotifyAddrChange的返回值分以下两种情况

1) 同步模式下返回

当我们给Handle和overlapped这两个参数都设置为NULL时,这个函数将以同步的方式执行。如果函数执行成功,则返回NO_ERROR,否则返回以下错误代码:

ERROR_CANCELLED

ERROR_INVALID_PARAMETER

ERROR_NOT_ENOUGH_MEMORY

ERROR_NOT_SUPPORTED

2) 异步模式下返回

如果我们给Handle和overlapped这两个参数都设置为非NULL时,这个函数将以异步方式执行。如果这个函数执行成功,则返回ERROR_IO_PENDING,否则返回其他错误代码(见上)。

通过以上对参数和返回值的理解,我们应该可以知道,NotifyAddrChange执行同步和异步两种工作模式。

1) 同步模式

在此模式下,也即我们将它的两个参数都设置成NULL。调用函数后,函数将阻塞,直到系统侦测到IP地址发生变化。如果该函数返回后,继续调用它,则它继续阻塞,直到下一个IP地址变化事件发生。

2) 异步模式

如果我们给它传入一个OVERLAPPED结构时,此函数将以异步模式执行。也即上面已经描述过的,NotifyAddrChange调用将立即完成并返回WSA_IO_PENDING(执行成功的情况下)。我们可以利用OVERLAPPED这个结构来调用GetOverlappedResult来接收IP地址变化这一事件通知。

如何取消

使用CancelIPChangeNotify这一函数可以取消对IP地址变化的侦测,这种情况一般发生在:

1) 用户显式取消侦测功能

用户可能会通过GUI来表达此需求,此时,NotifyAddrChange已经处于阻塞(同步)或其他工作线程已经在WaitForSingleObject(异步)了,使用CancelIPChangeNotify这一调用,可以立即触发NotifyAddrChange返回(同步)或WaitForSingleObject(异步)返回。

2) 应用程序退出

当整个应用程序退出时,系统会帮我们自动取消,但最好还是由我们显式取消比较好。这样做的好处是可以避免工作线程被强制终止而造成资源泄漏。

侦测到IP地址变化后应该怎么做

NotifyAddrChange只是简单的告诉我们系统的IP地址发生了变化,但是具体是怎样变化,我们无法从此函数调用中得到。这个时候,我们可以使用GetAdaptersAddresses这一函数来得到当前最新的IP地址来判断。

好了,我们来看看具体的示例代码,此代码来自MSDN。

程序架构注意点

对于一个图形界面程序来说,如果将NotifyAddrChange放置到主线程,则会导致主线程阻塞界面卡死。那么我们在程序架构阶段,将NotifyAddrChange安排到一个工作线程中,当系统侦测到IP地址变化,工作线程会得到此通知,进而通过窗口句柄来通知主线程。

示例流程图如下

总结

应用程序自我感知是一个非常有用的用户体验,让我们的用户随时知道系统当前的状态,可以极大的提升用户的好感。

用户会觉得:不错!我不是在跟一个”木头程序”在交互。

delphi 通过句柄获取exe文本框内容_实战经验:通过NotifyAddrChange侦测网络变化相关推荐

  1. swing获取文本框内容_营销管理培训课件,大客服销售策略和技巧,全内容PPT拿来就用...

    Hello大家好,我是帮帮.今天跟大家分享一张营销管理培训课件,大客服销售策略和技巧,全内容PPT拿来就用. 为了让大家能更稳定的下载模板,我们又开通了全新下载方式(见文章末尾),以便大家可以轻松获得 ...

  2. python获取网页文本框内容_python识别html主要文本框

    在抓取网页的时候只想抓取主要的文本框,例如 csdn 中的主要文本框为下图红色框: 抓取的思想是,利用 bs4 查找所有的 div,用正则筛选出每个 div 里面的中文,找到中文字数最多的 div 就 ...

  3. php获取html中文本框内容_小猿圈Python入门之批量获取html内body内容的方法

    对于人工智能你了解有多少?你知道Python的使用吗?这个对于大部分初学者来说都是很难的,小猿圈Python讲师会每天为大家选择分享一个知识点,希望对你学习Python有所帮助,今天分享的就是批量获取 ...

  4. python 获取文本框内容_如何在python中单击按钮时获取文本框中的文本?

    我可以让您的代码在单击按钮时显示文本框中的文本: 这就是你要达到的目的吗?您没有提到是否出现错误,但我确实发现您的代码存在两个问题:Button.py脚本中似乎存在一些缩进问题.在 对于changeT ...

  5. python获取html文本框内容_Python3处理HTML获取所需内容

    处理HTML页面,经常使用的便是使用beautifulsoup库 pip install beautifulsoup4 执行上述语句下载bs4库 一般请求下来的所需数据都位于tbody的tr标签里,下 ...

  6. python获取文本框内容_jquery获取文本框的内容

    使用jquery获取文本框的内容有以下几种: 1.根据ID取值(id属性): // javascript function getUserName(){ var username= $("# ...

  7. html js文本框文字列出,js实现文本框中输入文字页面中div层同步获取文本框内容的方法...

    这篇文章主要介绍了js实现文本框中输入文字页面中div层同步获取文本框内容的方法,实例分析了javascript操作dom元素的技巧,需要的朋友可以参考下 本文实例讲述了js实现文本框中输入文字页面中 ...

  8. python tkinter输入框_python TKinter获取文本框内容的方法

    python TKinter获取文本框内容的方法 更新时间:2018年10月11日 11:36:08 作者:biubiuzzz 今天小编就为大家分享一篇python TKinter获取文本框内容的方法 ...

  9. php 修改input内容,JS简单获取并修改input文本框内容的方法示例

    这篇文章主要介绍了JS简单获取并修改input文本框内容的方法,结合实例形式分析了JavaScript针对页面元素的获取.赋值等相关操作技巧,需要的朋友可以参考下 本文实例讲述了JS简单获取并修改in ...

最新文章

  1. 武汉python培训哪一家好一些-武汉Python培训机构哪家好?要怎么选才靠谱?
  2. PHP之factory
  3. CodeForces - 224C. Bracket Sequence (栈模拟)简单做法
  4. flash调用摄像头弹出设置框监听
  5. Python:Sklearn概述
  6. sqlserver 建表指定主键_3-自增字段;主键约束
  7. java的poi技术读取Excel[2003-2007,2010]
  8. php开发面试题---面试常用英语(你能介绍你自己吗?)
  9. mapper mysl实现批量插入 更新
  10. 向日葵远程调用Visual studio2019时白屏透明黑屏解决方案
  11. UE4入门序列06(Unreal源码编译及打包专用服务器)
  12. CleanMyMac最新破解安装版
  13. 是真的吗?蚂蚁的LDC架构,到底是干嘛的,真的那么牛吗
  14. 学电子信息工程,出路在哪里?
  15. Python基础,day2
  16. 一文弄懂责任链设计模式
  17. Python 视频转换为图片 与 图片转换为视频
  18. C语言源代码系列-管理系统之单项选择题标准化考试系统设计
  19. 京东双十一养红包自动脚本
  20. 中天视听王 未来软件园

热门文章

  1. C#LeetCode刷题之#657-机器人能否返回原点(Robot Return to Origin)
  2. 应对–简单的Intro组件无法渲染?
  3. azure服务器_如何使用Blazor WebAssembly实施Azure无服务器
  4. 函数式编程 模式_函数式编程模式:食谱
  5. 把svg图标制作成字体图标_让我们用SVG符号和CSS变量制作彩色图标
  6. SAS在金融中的应用七
  7. 手机usb无法被电脑识别_6种方法解决电脑无法识别移动硬盘
  8. 关于simulink中参数传递到工作空间
  9. Linux——vi编辑器
  10. ASP.NET @Page指令属性