如何一拔掉网线我的程序就可以马上得到通知?用没有相应的事件、通知、或者CALLBACK函数。是不是跟IP Helper API有关?我就想做到像托盘区里的网络连接图标一样的效果,拔掉网线它马上就有提示。请高人指教,分不够可以再加

解决方案 »

  1.   

    在socket层是得不到这个事件的,只能等待超时了。
      

  2.   

    在API中没有吗?可能用API吧!
      

  3.   

    这种东西一般都是直接和设备驱动打交道的,如果自己要做,又不会弄设备驱动,那么可以用socket的超时~~我是这样想的
      

  4.   

    我记得以前看过一篇贴子好像说是和 IP Helper API 有关。没有人知道吗?
      

  5.   

    试一试iphlpapi中的NotifyAddrChange,它可以侦测到ip地址的改变,但是能不能实现你的功能就不一定了
      

  6.   

    NotifyAddrChange 有没有什么例子可以参考的?
      

  7.   

    如果客户端和服务器端都是你开发的话好办。用异步模式,网线拔掉的时候可以得到一个错误事件。使用WSAGETSELECTERROR 取得错误代码,好像是WSAENETDOWN吧。
      

  8.   

    Windows系统本身应该对网络的连接情况定时进行检测,如果检测到Downline,就发系统消息(我的猜测)与系统底层和硬件有关我是一无所知
      

  9.   

    如果是在Win2K下(网线一不连接然后ping自己都ping不通,不像WIN98),开发一个本机上自己连自己的网络程序也可以的,但不要使用127.0.0.1,直接使用网卡地址。
    然后还是:
    如果客户端和服务器端都是你开发的话好办。用异步模式,网线拔掉的时候可以得到一个错误事件。使用WSAGETSELECTERROR 取得错误代码,好像是WSAENETDOWN吧。虽然笨了点,但可行。
      

  10.   

    用同步模式只编写一个server程序估计也行。accept应该会返回错误。
      

  11.   

    感谢 smch(Ashes Of Time) 出的主意,感谢大家的支持。我的程序只广播UDP包,没有server端。因此无法靠和server连接中断判断网络的连接是否正常。但我的程序又得知道网络连接是否正常,以此来决定是否要断开重新连接后重起服务。
      

  12.   

    真的没有人知道么?我今天翻遍了MSDN也没有找到答案
      

  13.   

    回复人: lemonasia(哪吒) ( ) 信誉:100  2003-7-27 11:23:04  得分:0 
     
     
      
    感谢 smch(Ashes Of Time) 出的主意,感谢大家的支持。我的程序只广播UDP包,没有server端。因此无法靠和server连接中断判断网络的连接是否正常。但我的程序又得知道网络连接是否正常,以此来决定是否要断开重新连接后重起服务。------------------------------------------- 
    老大,你可以简单的加一个线程来检测呀,为什么你为了实现这个功能就不能多加一点东西呢?在WIN2K中网线拔掉的话肯定有一个事件给你。发生错误之后你就可以发一个消息给你的主线程。
      

  14.   

    在WIN2K中accept就可以了。就一个服务端就可以了。但SOCKET需要指定网卡地址而不是127.0.0.1
      

  15.   

    老大,你可以简单的加一个线程来检测呀,为什么你为了实现这个功能就不能多加一点东西呢?在WIN2K中网线拔掉的话肯定有一个事件给你。发生错误之后你就可以发一个消息给你的主线程。
    ---------------------------------------------------------------------------------
    我就是想知道是哪个事件响应
      

  16.   

    NotifyAddrChange的使用方法:  
    在主线程中:
       OVERLAPPED      overLapped;
         DWORD   dwError;
         //HANDLE  handle;
         HANDLE  h2;
         handle=CreateEvent(NULL, // SD
                            false,   // reset type
                            false, // initial state
                            "IPChang.data"    // object name
                            );
         overLapped.hEvent=handle;
         NotifyAddrChange(&h2,&overLapped);     //创建一个子进程来等待消息
         LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL;
         SIZE_T dwStackSize = 0;
         //LPTHREAD_START_ROUTINE lpStartAddress;
         LPVOID lpParameter = (LPVOID)&handle;
         DWORD dwCreationFlags = 0 ;
         DWORD lpThreadId;
         HANDLE  THandle = CreateThread(lpThreadAttributes,               // SD
                                       dwStackSize,                    // initial stack size
                                       WaitForEvent,   //lpStartAddress,thread function
                                       lpParameter,           // thread argument
                                       dwCreationFlags,              // creation option
                                       &lpThreadId                      // thread identifier
                                       );子线程:
    DWORD  WINAPI  WaitForEvent(LPVOID data){
         HANDLE handle;
         DWORD  dwError;
         handle=*(HANDLE*)data;
         int OriDhcpNum,CurDhcpNum;     while(1){           dwError=WaitForSingleObject(handle,1000);
               if( dwError == WAIT_OBJECT_0)
               {
                   //A需要判断是否有新的网络设备启用
                   unsigned long    OutBufLenN;
                   PIP_ADAPTER_INFO  AdaptersInfo;
                   int AdaptersNum;
                   DWORD dret;
                   OutBufLenN=1;
                   AdaptersInfo=(PIP_ADAPTER_INFO)malloc(OutBufLenN);
                   dret=GetAdaptersInfo(AdaptersInfo,&OutBufLenN);
                   AdaptersInfo=(PIP_ADAPTER_INFO)malloc(OutBufLenN);
                   dret=GetAdaptersInfo(AdaptersInfo,&OutBufLenN);
                   。以上程序在win2000/xp下测试可以检测到是否有新的网卡启用或者网卡的IP地址发生变化。没有试验过是否能监测到网线
      

  17.   

    异步模式下监控FD_CLOSE,如果出现WSAECONNABORTED错误,说明你的网络断了。一般立刻可以发觉。
    不过这种方式对于无线上网的机器无效。
      

  18.   

    我找到了一个判断的方式,但只适用于Windows 2000/XP/2003,就是当网线被断开时,Ping本机IP是Ping不到的,不是127.0.0.1。因此可以在自身的程序里通过ICMP实现Ping的功能,定时Ping本身IP,如果Ping不到了就说明网络断开了。比如每1秒Ping一次,基本可以实现实时。但这个方法在Windows 98里不行,网线断开后,在98里无论是Ping 127.0.0.1还是Ping本身IP都可以Ping到。
      

  19.   

    局域网内好像也不行吧,怎么ping都能ping通
      

  20.   

    网线的物理通断是根据物理的电平信号来判断的,所以必须做到 底层驱动部分才能从根本上得到通知。建议研究一下SetupDiCallClassInstaller等函数。
      

  21.   

    IP help API应该做不到这个功能
    可以从设备驱动去考虑,或者有别的方法
      

  22.   

    Windows的提供了一套使用COM+接口的机制SENS(System Event Notification Services)用来让用户获得一系列的事件(见MSDN),不过我没有做过。请看MSDN中的这篇文章:
    SENS Architecture
    The System Event Notification Service works with the COM+ Event System. SENS is an event publisher for the classes of events that it monitors: network, logon, and power/battery events. The application receiving a notification is called an event subscriber.When an application subscribes to receive notifications, it can also specify filters associated with the subscribed events. SENS and COM+ Events use the filters to further determine when the application should be notified.Notifications are asynchronous, so the application receiving the notification does not have to be active when the notification is sent. When an application subscribes to receive notifications, it can specify whether it should be activated when the event occurs or notified later when it is active.The subscription can be transient and valid only until the application stops running, or it can be persistent and valid until the application is removed from the system.A COM+ Events data store contains information about the event publisher (SENS), event subscribers, and filters. During setup when you install or upgrade to Microsoft® Windows® 2000, SENS adds itself to the COM+ Events data store and provides information on the classes of events that it monitors using a GUID for each class of events. SENS also predefines an outgoing interface for each event class in a type library.Event class GUID Interface 
    Network events SENSGUID_EVENTCLASS_NETWORK ISensNetwork 
    Logon events SENSGUID_EVENTCLASS_LOGON ISensLogon 
    Power events SENSGUID_EVENTCLASS_ONNOW ISensOnNow 
    To receive notifications for any of these events, your application must do two things: Subscribe to the SENS events that interest you. To subscribe to an event, use the IEventSubscription and IEventSystem interfaces in COM+ Events. You need to supply an identifier for the event classes and the SENS publisher identifier, SENSGUID_PUBLISHER. Subscriptions are on a per event level so the subscribing application must also specify which events within the class are of interest. Each event corresponds to a method in the interface corresponding to its event class.
     
    Note  Programmers using SENS on the Internet Explorer 5 platform should use only the IEventSubscription and IEventSystem COM+ Events interfaces. Create a sink object with an implementation for each interface that you handle. See ISensNetwork, ISensLogon, and ISensOnNow for more information about these interfaces and the events supported in each one. 
    When one of the monitored events occurs, SENS processes each subscription with any associated filters and notifies the subscribers through the COM+ Event system.
      

  23.   

    其实MSDN中讲得非常详细,参见Platform SDK Document=》Networking and Directory Services=》Network Management=》Synchronization Manager=》System Event Notification Service。里面有详细的讲解!
      

  24.   

    可惜SENS只在Windows Me以上的操作系统支持。
      

  25.   

    SENS里的ISensNetwork接口里的ConnectLost是如何建立事件的,应该怎么用这个接口啊?
      

  26.   

    真是奇怪,WM_DEVICECHANGE 这个消息我第一次试的时候还行,能收到网线拔掉的消息,可是后来试就不行了,怎么回事啊?我用的是WinXp,VC6
      

  27.   

    好啦。结贴吧:其实有很多方法的(WIN98以下可能不能正常工作)。
    制作一个SOCKET程序,自己连接自己,但需要指定网卡IP地址。
    m_ServerAddr.sin_addr.s_addr = inet_addr("192.168.101.21");//这里指定网卡IP地址
    -----------------------------
    如果是异步模式。那么网线拔掉之后将会接收到WSAECONNABORTED错误信息。
    bool CChatServerDlg::OnClientEvent(WPARAM wParam,LPARAM lParam)
    {
    (WSAGETSELECTERROR(lParam)==WSAECONNABORTED)
    ...
    }在WIN2K下通过了测试。
      

  28.   

    如果是同步SOCKET,可以让其中的服务器端或者客户端(这里都放在一个程序里面,当然也可以分开,只不过是运行在同一电脑上。)调用recv。网线拔掉肯定会接收到错误信息。不过没有测试过。
      

  29.   

    smch(Ashes Of Time) 我指的是单台机器的网络环境,不存在服务器和客户端。只是本机的一个程序发广播包
      

  30.   

    这个方法我想到过,的确可以实现,但在98下不行。如果是其他操作系统的话比如2000/xp,那么用sens实现更标准.
      

  31.   

    去哪可以得到Sensapi.h呢???
      

  32.   

    拔掉网线后,windows会有WM_DEVICECHANGE触发,而且现在我可以进一步的知道这个通知是DBT_DEVNODES_CHANGED。但是有可能很多的硬件改变时都会发DBT_DEVNODES_CHANGED这个通知!怎么把网卡发的和其他的区分开呢?
      

  33.   

    很简单的呀,别用底层SOCKET来做,直接用MFC的CAsyncSocket来做,连接突然中断时,它会产生一个回调来响应连接中断
      

  34.   

    这个问题我已经解决了,用iphelper包里的函数就可以了!sdk里有,我忙,没空详细回答,抱歉
      

  35.   

    也没有这么复杂啦!最简单的也是最有效的办法:
    客户端和服务器端定义一组验证机制。
    客户端定时发送验证测试包,
    服务器会测试响应包。这验证<->响应二者之间设置一个超时值,如5S,
    如果这个时间内没有收到响应包,则为网络故障!