厦门莫格电气自动化有限公司销售
Honeywell霍尼韦尔620-0039
您迈开询价的一小步,我还您成功的一大步。
620-0039
620-0039
620-0039
在实际应用中,复杂的网络状况可能让设备网络产生异常(比如IP冲突),从而无法正常网络通信。通过重启设备可以***网络,本文介绍另外一个方法,在应用层不断电的情况下快速重置网络,***网络通信。
手动重置网络
进入板子控制面板->网络和拨号连接,可以看到板子现有网口的网络连接图标,下图以E***287为例,E***287有两个网口,分别为ENET1和ENET2。
右键点击需要重置的网口图标,先选择禁用,可以看到图标显示X,同时板子网络灯停止闪烁。
再次右键点击该图标,选择启用,图标***连接显示,可以观察到板子网络灯重新亮起。
代码重置网络
引用pw.h头文件,添加定义板子DEVICEIOCONTROL的相关宏定义。
#define DD_NDIS_DEVICE_NAME TEXT("NDS0:")
#define NDISPWR_DEVICE_NAME TEXT("NPW1:")
#define _NDIS_CONTROL_CODE(request,method) \
CTL_CODE(FILE_DEVICE_PHYSICAL_NETCARD, request, method, FILE_ANY_ACCESS)
#define WINCE_IOCTL_START 8
#define IOCTL_NDIS_BIND_ADAPTER _NDIS_CONTROL_CODE( WINCE_IOCTL_START+4, METHOD_OUT_DIRECT )
#define IOCTL_NDIS_UNBIND_ADAPTER _NDIS_CONTROL_CODE( WINCE_IOCTL_START+5, METHOD_OUT_DIRECT )
#define IOCTL_NDIS_GET_ADAPTER_BINDINGS _NDIS_CONTROL_CODE( WINCE_IOCTL_START+8, METHOD_OUT_DIRECT )
#define FSCTL_NDISPWR_BASE FILE_DEVICE_NETWORK
#define _NDISPWR_CTL_CODE(_Function, _Method, _Access) \
CTL_CODE(FSCTL_NDISPWR_BASE, _Function, _Method, _Access)
#define IOCTL_NPW_S***E_POWER_STATE \
_NDISPWR_CTL_CODE(0x200, METHOD_BUFFERED, FILE_ANY_ACCESS)
首先调用电源管理设备NPW,通知它关闭网口电源(这里以ENET1为例)
hNdisPwr = CreateFile(NDISPWR_DEVICE_NAME, 0, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, INVALID_HANDLE_VALUE);
S***ePowerState.CePowerState = D4;
cAdapterName = L”ENET1”;
bRet = DeviceIoControl(
hNdisPwr,
IOCTL_NPW_S***E_POWER_STATE,
&S***ePowerState,
sizeof(NDISPWR_S***EPOWERSTATE),
NULL,
0x00,
NULL,
NULL);
CloseHandle(hNdisPwr);
如果网口有自己的电源管理,那么那么还应该调用以下代码。还是以ENET1为例,这里的字符串一定得是{98C5250D-C29A-4985-AE5F-AFE5367E5006}\ENET1这样的,并且需要两个\0结尾!
TCHAR szName[MAX_PATH]=L”ENET1”;
int nChars;
nChars = _sntprintf(
szName,
MAX_PATH-1,
_T("%s\\%s"),
PMCLASS_NDIS_MINIPORT,
wcName);
szName[MAX_PATH-1]=0;
DWORD dwRet;
dwRet = Se***vicePower(szName, POWER_NAME, D4);
通知系统UNBIND网口
BOOL DoNdisIOControl(DWORD dwCommand, LPVOID pInBuffer,
DWORD cbInBuffer, LPVOID pOutBuffer,
DWORD * pcbOutBuffer)
{
HANDLE hNdis;
BOOL fResult = FALSE;
hNdis = ::CreateFile(DD_NDIS_DEVICE_NAME, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS,
0, NULL);
if (INVALID_HANDLE_VALUE != hNdis)
{
fResult = DeviceIoControl(hNdis, dwCommand, pInBuffer, cbInBuffer,
pOutBuffer, (pcbOutBuffer ? *pcbOutBuffer : 0),
pcbOutBuffer, NULL);
CloseHandle(hNdis);
}
return fResult;
}
…
bRet = DoNdisIOControl(
IOCTL_NDIS_UNBIND_ADAPTER,
wcName,
(_tcslen(wcName)+2) * sizeof(TCHAR),
NULL,
NULL);
查询网络,确认一下禁用网络是否成功
bRet = DoNdisIOControl(
IOCTL_NDIS_GET_ADAPTER_BINDINGS,
wcName,
(_tcslen(wcName)+1) * sizeof(TCHAR),
multiSz,
&cbBuffer);
return (multiSz[0] != L'\0');
让板子网口重新上电,这里上电不能直接使用D0,只能使用默认值PwrDeviceUnspecified
hNdisPwr = CreateFile(NDISPWR_DEVICE_NAME, 0, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, INVALID_HANDLE_VALUE);
S***ePowerState.CePowerState = PwrDeviceUnspecified;
cAdapterName = L”ENET1”;
bRet = DeviceIoControl(
hNdisPwr,
IOCTL_NPW_S***E_POWER_STATE,
&S***ePowerState,
sizeof(NDISPWR_S***EPOWERSTATE),
NULL,
0x00,
NULL,
NULL);
CloseHandle(hNdisPwr);
TCHAR szName[MAX_PATH]=L”ENET1”;
int nChars;
nChars = _sntprintf(
szName,
MAX_PATH-1,
_T("%s\\%s"),
PMCLASS_NDIS_MINIPORT,
wcName);
szName[MAX_PATH-1]=0;
DWORD dwRet;
dwRet = Se***vicePower(szName, POWER_NAME, PwrDeviceUnspecified);
通知系统BIND网口
bRet = DoNdisIOControl(
IOCTL_NDIS_BIND_ADAPTER,
wcName,
(_tcslen(wcName)+2) * sizeof(TCHAR),
NULL,
NULL);
查询网络,确认一下网络启动是否成功
bRet = DoNdisIOControl(
IOCTL_NDIS_GET_ADAPTER_BINDINGS,
wcName,
(_tcslen(wcName)+1) * sizeof(TCHAR),
multiSz,
&cbBuffer);
return (multiSz[0] != L'\0');
例程里已经将以上代码封装到enet.h,使用以下代码可以简单重置网络
#include "enet.h"
Void ResetENET()
{
EnableENET(FALSE);
EnableENET(TRUE);
}
在重置网络前,建议先关闭该网口现有的socket连接