linux下面,可以通过什么函数获取当前网络连接的状态(比如连接、断开等)

linux下面,可以通过什么函数获取当前网络连接的状态(比如连接、断开等),第1张

[root@localhost ~]# ethtool eth0

Settings for eth0:

Supported ports: [ TP ]

Supported link modes: 10baseT/Half 10baseT/Full

100baseT/Half 100baseT/Full

1000baseT/Full

Supports auto-negotiation: Yes

Advertised link modes: 10baseT/Half 10baseT/Full

100baseT/Half 100baseT/Full

1000baseT/Full

Advertised auto-negotiation: Yes

Speed: 100Mb/s

Duplex: Full

Port: Twisted Pair

PHYAD: 1

Transceiver: internal

Auto-negotiation: on

Supports Wake-on: g

Wake-on: d

Link detected: yes

[root@localhost ~]#

最后一行 Link detected: yes 说明网线插着。

别用ifconfig命令看,这个命令只对已经配置好的网卡管用,对插上网线但是尚未配置的网卡不一定灵。

当我们把网线插到计算机上时,WINDOWS任务栏的托盘图标都会更改相应的网络图标,拔掉也会有相应的处理。一直都对这个机制感兴趣,却不知道如何做,而且公司的某个产品也需要这么一个功能。昨天在家测试某个程序的时候,发现了其中一个线程的栈中有一个叫wininet!CheckForNetworkChange的函数,IDA分析了WINNETDLL后,有了本文。

微软在WINDOWS VISTA之后提供了一个叫NLA(Network List Manager API)的接口,用于获取网络状态变化通知的一个接口。以COM技术实现。

主要导出的COM接口如下:

IEnumNetworkConnections

IEnumNetworks

INetwork

INetworkConnection

INetworkConnectionEvents

INetworkEvents

INetworkListManager

INetworkListManagerEvents

其中INetworkListManager是一个根对象,可以获取计算机是否连接到因特网(INetworkListManager->get_IsConnectedToInternet)。还可以查询有哪些可用的网络和连接更关键的是INetworkListManagerEvents和INetworkEvents两个类。这两个类在MSDN文档里的描述如下:

is a message sink interface that a client implements to get overall machine state related events

也就是说我们要自己实现这两个类。而回调的方式是通过COM技术中特有的机制IConnectionPoint来搞定。实现方式如下:

001 class CNetworkListManagerEvent : public INetworkListManagerEvents

002 {

003 public:

004 CNetworkListManagerEvent() : m_ref(1)

005 {

006

007 }

008

009 ~CNetworkListManagerEvent()

010 {

011

012 }

013

014 HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void ppvObject)

015 {

016 HRESULT Result = S_OK;

017 if (IsEqualIID(riid, IID_IUnknown))

018 {

019 ppvObject = (IUnknown )this;

020 }

021 else if (IsEqualIID(riid ,IID_INetworkListManagerEvents))

022 {

023 ppvObject = (INetworkListManagerEvents )this;

024 }

025 else

026 {

027 Result = E_NOINTERFACE;

028 }

029

030 return Result;

031 }

032

033 ULONG STDMETHODCALLTYPE AddRef()

034 {

035 return (ULONG)InterlockedIncrement(&m_ref);

036 }

037

038 ULONG STDMETHODCALLTYPE Release()

039 {

040 LONG Result = InterlockedDecrement(&m_ref);

041 if (Result == 0)

042 delete this;

043 return (ULONG)Result;

044 }

045

046 virtual HRESULT STDMETHODCALLTYPE ConnectivityChanged(

047 / [in] / NLM_CONNECTIVITY newConnectivity)

048 {

049 return S_OK;

050 }

051

052 private:

053

054 LONG m_ref;

055 };

056

057 int _tmain(int argc, TCHAR argv, TCHAR Env)

058 {

059 CoInitialize(NULL);

060

061 //

062 // 通过NLA接口获取网络状态

063 //

064 IUnknown pUnknown = NULL;

065

066 HRESULT Result = CoCreateInstance(CLSID_NetworkListManager, NULL, CLSCTX_ALL, IID_IUnknown, (void )&pUnknown);

067 if (SUCCEEDED(Result))

068 {

069 INetworkListManager pNetworkListManager = NULL;

070 Result = pUnknown->QueryInterface(IID_INetworkListManager, (void )&pNetworkListManager);

071 if (SUCCEEDED(Result))

072 {

073 VARIANT_BOOL IsConnect = VARIANT_FALSE;

074 Result = pNetworkListManager->get_IsConnectedToInternet(&IsConnect);

075 if (SUCCEEDED(Result))

076 {

077 printf("IsConnect Result %s\n", IsConnect == VARIANT_TRUE "TRUE" : "FALSE");

078 }

079

080 IConnectionPointContainer pCPContainer = NULL;

081 Result = pNetworkListManager->QueryInterface(IID_IConnectionPointContainer, (void )&pCPContainer);

082 if (SUCCEEDED(Result))

083 {

084 IConnectionPoint pConnectPoint = NULL;

085 Result = pCPContainer->FindConnectionPoint(IID_INetworkListManagerEvents, &pConnectPoint);

086 if(SUCCEEDED(Result))

087 {

088 DWORD Cookie = NULL;

089 CNetworkListManagerEvent NetEvent = new CNetworkListManagerEvent;

090 Result = pConnectPoint->Advise((IUnknown )NetEvent, &Cookie);

091 if (SUCCEEDED(Result))

092 {

093 printf("Loop Message\n");

094 MSG msg;

095 while(GetMessage(&msg, NULL, 0, 0))

096 {

097 TranslateMessage(&msg);

098 DispatchMessage(&msg);

099

100 if (msgmessage == WM_QUIT)

101 {

102 break;

103 }

104 }

105

106 pConnectPoint->Unadvise(Cookie);

107

108 pConnectPoint->Release();

109 }

110 }

111

112 pCPContainer->Release();

113 }

114

115 pNetworkListManager->Release();

116 }

117

118 pUnknown->Release();

119 }

120

121 CoUninitialize();

122 return 1;

123 }

因为NLA API是WINDOWS VISTA之后才有的,对于WINDOWS XP是不兼容的,但是WINDOWS XP下有一个方法可以达到同样的效果,可以参考文章Network Awareness in Windows XP,这个文章里的代码是C#的,其中关键的代码转换成C++

01 void WaitForNetworkChnages()

02 {

03 WSAQUERYSET querySet = {0};

04 querySetdwSize = sizeof(WSAQUERYSET);

05 querySetdwNameSpace = NS_NLA;

06

07 HANDLE LookupHandle = NULL;

08 WSALookupServiceBegin(&querySet, LUP_RETURN_ALL, &LookupHandle);

09 DWORD BytesReturned = 0;

10 WSANSPIoctl(LookupHandle, SIO_NSP_NOTIFY_CHANGE, NULL, 0, NULL, 0, &BytesReturned, NULL);

11 WSALookupServiceEnd(LookupHandle);

12 }

13

14 void Test()

15 {

16 WSAData data = {0};

17 WSAStartup(MAKEWORD(2, 0), &data);

18 int i = 0;

19 while(1)

20 {

21 printf("BeginWait %d\n", i++);

22 WaitForNetworkChnages();

23 printf("EndWait\n");

24 }

25

26 WSACleanup();

27 }

第一种:网卡驱动程序异常导致一直显示“正在获取网络地址”。

查看网卡是否正常:win(键盘上的旗标键)+R(键盘R键),打开运行,然后输入cmd,打开命令提示符。

在打开的命令提示符中,输入:ping 127001(回环地址),以检测网卡是否正常,若出现如图所示的界面,则证明网卡正常。

第二种:可能是DHCP Client服务未启动、网络IP地址配置异常、局域网网关服务器地址设置异常、DNS解析错误等。

DHCP Client后台服务未启动:键盘上win+R ,输入“servicesmsc”,点击确定打开“服务(本地)”窗口——>在右边窗口中找到“DHCP Client”服务——>双击打开该服务——>将“启动类型”设置为“自动”——>在“服务状态”下方点击“启动(S)”——> 点击“确定”——>重新启动计算机

第三种:病毒木马、恶意插件感染、以及未知冲突,下载安装360安全卫士、金山毒霸等杀毒软件,以360安全卫士96beta为例——>打开360安全卫士窗口——>单击“更多”——>选择“断网急救箱”或者“LSP修复”,建议在断网急救箱无法解决的情况下选择LSP修复(PS:建议使用这种方式来解决问题,一键式解决)

以上就是关于linux下面,可以通过什么函数获取当前网络连接的状态(比如连接、断开等)全部的内容,包括:linux下面,可以通过什么函数获取当前网络连接的状态(比如连接、断开等)、如何自动获取网络变化通知、笔记本电脑连接无线网络一直提示正在获取网络地址等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9499387.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-29
下一篇 2023-04-29

发表评论

登录后才能评论

评论列表(0条)

保存