windows中手工调整活动路由表的简单方法 您所在的位置:网站首页 windows永久路由不生效 windows中手工调整活动路由表的简单方法

windows中手工调整活动路由表的简单方法

2024-07-16 10:38| 来源: 网络整理| 查看: 265

前言

我司有个小程序,用UDP通讯读写设备参数,用来改IP这些出厂参数。 在我所有同事和现场计算机上运行都好使。唯独在我开发本上不好使。 我运维同事让我重装win10, 这哪能听他的…, 这么暴力的主意.

这事是一定要解决的,问题在哪呢?

那个程序有源码, VB6的,写的早了。 前段时间,装了个VB6, 将广播地址改了,当时可以在我开发本上能搜索到设备并改参数。就以为以前同事写的广播地址不大对呗。

前天,给我新做的4G短信猫写插件。 这套软件中,需要连一个我们的带IP的设备,需要先改设备IP. 用原版的UDP程序搜不到设备。 用我改过广播地址的UDP程序也搜不到设备。

用wireshark抓包,发现只有本本用的WLAN网卡上有UDP发包。 USB转网卡那个网卡(设备接在这块临时网卡上)没有收到UDP广播包。

当时的想法:以前同事咋不指定网卡发广播包啊?那自己动手写一个简版的实现吧。

用了1天写完界面和基础代码。今天开始写指定网卡发广播包。 突然发现,windows下的socket不支持发包时指定网卡(setsockopt 选项中就没有 SO_BINDTODEVICE),只有linux才行。。。

那咋弄? 看看能不能调整路由表顺序,将接设备的那块网卡顶到活动路由表的顶部。 试试好使,记录一下。

以前同事跟我说过,将无线网卡禁用,再试试UDP程序好使不? 我现在才明白,他们不是研发,计算机上装的软件少,计算机上可能就只有内置物理网卡和USB转网卡2块网卡。

而我计算机上网卡在系统中的网卡列表处(控制面板\网络和 Internet\网络连接)有5块。 在这里插入图片描述 经过试验,不用禁掉其他网卡,只留USB转网卡,那样上网啥的就不行了。 正确姿势是:

将全部网卡都禁掉。再按照自己想使用的网卡优先级,一个一个启动。那样在活动路由表中,先开启的网卡,就在活动路由表最上面,包优先发向那块网卡。 试验 我接设备的网卡是网卡转USB转出来的。IP是 192.168.2.x 主网卡是内置wifi接我家里的路由器。IP是 192.168.1.x 进入系统中的网卡列表处(控制面板\网络和 Internet\网络连接) 将能看到的网卡都禁用了。 查看路由表中的活动路由(网卡全禁用) C:\Users\chenx>route print =========================================================================== 接口列表 1...........................Software Loopback Interface 1 =========================================================================== IPv4 路由表 =========================================================================== 活动路由: 网络目标 网络掩码 网关 接口 跃点数 127.0.0.0 255.0.0.0 在链路上 127.0.0.1 331 127.0.0.1 255.255.255.255 在链路上 127.0.0.1 331 127.255.255.255 255.255.255.255 在链路上 127.0.0.1 331 224.0.0.0 240.0.0.0 在链路上 127.0.0.1 331 255.255.255.255 255.255.255.255 在链路上 127.0.0.1 331 =========================================================================== 可以看到活动路由只剩下回环。 将接设备的副网卡(192.168.2x)启用,设备接在这个网卡上面,这块网卡要在后动路由表的最上面才优先 查看路由表中的活动路由(网卡全禁用) C:\Users\chenx>route print =========================================================================== 接口列表 7...00 0e c6 ca 3a 6d ......ASIX AX88179 USB 3.0 to Gigabit Ethernet Adapter 1...........................Software Loopback Interface 1 =========================================================================== IPv4 路由表 =========================================================================== 活动路由: 网络目标 网络掩码 网关 接口 跃点数 0.0.0.0 0.0.0.0 192.168.2.1 192.168.2.100 291 127.0.0.0 255.0.0.0 在链路上 127.0.0.1 331 127.0.0.1 255.255.255.255 在链路上 127.0.0.1 331 127.255.255.255 255.255.255.255 在链路上 127.0.0.1 331 192.168.2.0 255.255.255.0 在链路上 192.168.2.100 291 192.168.2.100 255.255.255.255 在链路上 192.168.2.100 291 192.168.2.255 255.255.255.255 在链路上 192.168.2.100 291 224.0.0.0 240.0.0.0 在链路上 127.0.0.1 331 224.0.0.0 240.0.0.0 在链路上 192.168.2.100 291 255.255.255.255 255.255.255.255 在链路上 127.0.0.1 331 255.255.255.255 255.255.255.255 在链路上 192.168.2.100 291 =========================================================================== 可以看到USB转网卡在活动路由表的第一位置了。 将蓝牙连接的网卡启用,再看一下活动路由表 C:\Users\chenx>route print =========================================================================== 接口列表 7...00 0e c6 ca 3a 6d ......ASIX AX88179 USB 3.0 to Gigabit Ethernet Adapter 9...a0 a4 c5 41 5f f9 ......Bluetooth Device (Personal Area Network) 1...........................Software Loopback Interface 1 =========================================================================== IPv4 路由表 =========================================================================== 活动路由: 网络目标 网络掩码 网关 接口 跃点数 0.0.0.0 0.0.0.0 192.168.2.1 192.168.2.100 291 127.0.0.0 255.0.0.0 在链路上 127.0.0.1 331 127.0.0.1 255.255.255.255 在链路上 127.0.0.1 331 127.255.255.255 255.255.255.255 在链路上 127.0.0.1 331 192.168.2.0 255.255.255.0 在链路上 192.168.2.100 291 192.168.2.100 255.255.255.255 在链路上 192.168.2.100 291 192.168.2.255 255.255.255.255 在链路上 192.168.2.100 291 224.0.0.0 240.0.0.0 在链路上 127.0.0.1 331 224.0.0.0 240.0.0.0 在链路上 192.168.2.100 291 255.255.255.255 255.255.255.255 在链路上 127.0.0.1 331 255.255.255.255 255.255.255.255 在链路上 192.168.2.100 291 =========================================================================== 因为蓝牙网络没连接,网卡接口排在USB转网卡的后面,但是在回环前面。 活动路由没变化。 将VmWare1的网卡启用,再看一下活动路由表。 C:\Users\chenx>route print =========================================================================== 接口列表 23...00 50 56 c0 00 01 ......VMware Virtual Ethernet Adapter for VMnet1 7...00 0e c6 ca 3a 6d ......ASIX AX88179 USB 3.0 to Gigabit Ethernet Adapter 9...a0 a4 c5 41 5f f9 ......Bluetooth Device (Personal Area Network) 1...........................Software Loopback Interface 1 =========================================================================== IPv4 路由表 =========================================================================== 活动路由: 网络目标 网络掩码 网关 接口 跃点数 0.0.0.0 0.0.0.0 192.168.2.1 192.168.2.100 291 127.0.0.0 255.0.0.0 在链路上 127.0.0.1 331 127.0.0.1 255.255.255.255 在链路上 127.0.0.1 331 127.255.255.255 255.255.255.255 在链路上 127.0.0.1 331 192.168.2.0 255.255.255.0 在链路上 192.168.2.100 291 192.168.2.100 255.255.255.255 在链路上 192.168.2.100 291 192.168.2.255 255.255.255.255 在链路上 192.168.2.100 291 192.168.68.0 255.255.255.0 在链路上 192.168.68.1 291 192.168.68.1 255.255.255.255 在链路上 192.168.68.1 291 192.168.68.255 255.255.255.255 在链路上 192.168.68.1 291 224.0.0.0 240.0.0.0 在链路上 127.0.0.1 331 224.0.0.0 240.0.0.0 在链路上 192.168.2.100 291 224.0.0.0 240.0.0.0 在链路上 192.168.68.1 291 255.255.255.255 255.255.255.255 在链路上 127.0.0.1 331 255.255.255.255 255.255.255.255 在链路上 192.168.2.100 291 255.255.255.255 255.255.255.255 在链路上 192.168.68.1 291 =========================================================================== 可以看到接口列表中,Vmware1网卡排在USB转网卡前面。 但是活动路由中,VMware1网卡排在最后面。 将VmWare2的网卡启用,再看一下活动路由表。 C:\Users\chenx>route print =========================================================================== 接口列表 23...00 50 56 c0 00 01 ......VMware Virtual Ethernet Adapter for VMnet1 5...00 50 56 c0 00 08 ......VMware Virtual Ethernet Adapter for VMnet8 7...00 0e c6 ca 3a 6d ......ASIX AX88179 USB 3.0 to Gigabit Ethernet Adapter 9...a0 a4 c5 41 5f f9 ......Bluetooth Device (Personal Area Network) 1...........................Software Loopback Interface 1 =========================================================================== IPv4 路由表 =========================================================================== 活动路由: 网络目标 网络掩码 网关 接口 跃点数 0.0.0.0 0.0.0.0 192.168.2.1 192.168.2.100 291 127.0.0.0 255.0.0.0 在链路上 127.0.0.1 331 127.0.0.1 255.255.255.255 在链路上 127.0.0.1 331 127.255.255.255 255.255.255.255 在链路上 127.0.0.1 331 192.168.2.0 255.255.255.0 在链路上 192.168.2.100 291 192.168.2.100 255.255.255.255 在链路上 192.168.2.100 291 192.168.2.255 255.255.255.255 在链路上 192.168.2.100 291 192.168.68.0 255.255.255.0 在链路上 192.168.68.1 291 192.168.68.1 255.255.255.255 在链路上 192.168.68.1 291 192.168.68.255 255.255.255.255 在链路上 192.168.68.1 291 192.168.198.0 255.255.255.0 在链路上 192.168.198.1 291 192.168.198.1 255.255.255.255 在链路上 192.168.198.1 291 192.168.198.255 255.255.255.255 在链路上 192.168.198.1 291 224.0.0.0 240.0.0.0 在链路上 127.0.0.1 331 224.0.0.0 240.0.0.0 在链路上 192.168.2.100 291 224.0.0.0 240.0.0.0 在链路上 192.168.68.1 291 224.0.0.0 240.0.0.0 在链路上 192.168.198.1 291 255.255.255.255 255.255.255.255 在链路上 127.0.0.1 331 255.255.255.255 255.255.255.255 在链路上 192.168.2.100 291 255.255.255.255 255.255.255.255 在链路上 192.168.68.1 291 255.255.255.255 255.255.255.255 在链路上 192.168.198.1 291 =========================================================================== 可以看到VMware2的网卡排在最后,排在vmware1网卡的后面。 将WLAN的网卡启用,再看一下活动路由表。 C:\Users\chenx>route print =========================================================================== 接口列表 14...a0 a4 c5 41 5f f6 ......Microsoft Wi-Fi Direct Virtual Adapter #3 23...00 50 56 c0 00 01 ......VMware Virtual Ethernet Adapter for VMnet1 5...00 50 56 c0 00 08 ......VMware Virtual Ethernet Adapter for VMnet8 7...00 0e c6 ca 3a 6d ......ASIX AX88179 USB 3.0 to Gigabit Ethernet Adapter 15...a0 a4 c5 41 5f f5 ......Intel(R) Dual Band Wireless-AC 8265 9...a0 a4 c5 41 5f f9 ......Bluetooth Device (Personal Area Network) 1...........................Software Loopback Interface 1 =========================================================================== IPv4 路由表 =========================================================================== 活动路由: 网络目标 网络掩码 网关 接口 跃点数 0.0.0.0 0.0.0.0 192.168.2.1 192.168.2.100 291 0.0.0.0 0.0.0.0 192.168.1.1 192.168.1.102 35 127.0.0.0 255.0.0.0 在链路上 127.0.0.1 331 127.0.0.1 255.255.255.255 在链路上 127.0.0.1 331 127.255.255.255 255.255.255.255 在链路上 127.0.0.1 331 192.168.1.0 255.255.255.0 在链路上 192.168.1.102 291 192.168.1.102 255.255.255.255 在链路上 192.168.1.102 291 192.168.1.255 255.255.255.255 在链路上 192.168.1.102 291 192.168.2.0 255.255.255.0 在链路上 192.168.2.100 291 192.168.2.100 255.255.255.255 在链路上 192.168.2.100 291 192.168.2.255 255.255.255.255 在链路上 192.168.2.100 291 192.168.68.0 255.255.255.0 在链路上 192.168.68.1 291 192.168.68.1 255.255.255.255 在链路上 192.168.68.1 291 192.168.68.255 255.255.255.255 在链路上 192.168.68.1 291 192.168.198.0 255.255.255.0 在链路上 192.168.198.1 291 192.168.198.1 255.255.255.255 在链路上 192.168.198.1 291 192.168.198.255 255.255.255.255 在链路上 192.168.198.1 291 224.0.0.0 240.0.0.0 在链路上 127.0.0.1 331 224.0.0.0 240.0.0.0 在链路上 192.168.2.100 291 224.0.0.0 240.0.0.0 在链路上 192.168.68.1 291 224.0.0.0 240.0.0.0 在链路上 192.168.198.1 291 224.0.0.0 240.0.0.0 在链路上 192.168.1.102 291 255.255.255.255 255.255.255.255 在链路上 127.0.0.1 331 255.255.255.255 255.255.255.255 在链路上 192.168.2.100 291 255.255.255.255 255.255.255.255 在链路上 192.168.68.1 291 255.255.255.255 255.255.255.255 在链路上 192.168.198.1 291 255.255.255.255 255.255.255.255 在链路上 192.168.1.102 291 =========================================================================== 可以看到 WLAN网卡在活动路由中,也排在USB转网卡后面。 这时再运行UDP程序,可以看到有回包了。 用wireshark抓包也能证明这点(在USB转网卡那块网卡上,能看到UDP程序发出的指定UDP包和设备回包)。 试验结论: 如果是做临时试验,想让哪块网卡的活动路由优先,只需要先启动那块网卡即可。 不过这么做,将临时网卡顶到最上面,能明显感觉到网页访问最开始会慢很多,应该和主网卡不在活动路由表最上面有关系。等做完试验,将主网卡顶到活动路由表最上面好些。要不访问网页时,等的有点心慌。 试验结束

为了这个试验,开始想写的UDP简版程序已经写到一半了,对于这个试验来说没大用了。已经弄清为啥UDP程序在我计算机上不好使。

可是自己点的菜,即使吃撑了,也要强忍着眼泪继续吃完。 如果不是自己点的菜,真不想继续弄。

写UDP简版程序去了:)

UDP简版程序

将测试程序写完了,以后能用上,贴在这。 程序里面加上了搜索网卡的功能,因为windows无法指定网卡发包,实现先留着。 编程环境 :vs2017 + MFC dlg 中间遇到的问题:

sendto, recvfrom后会有错误码,是socket建立,sendto, recvfrom函数参数写的不规矩引起的。找msdn和大家写好的UDP代码对一对,能看出区别。 // rz_searchDlg.h: 头文件 // #pragma once #include #include #include using namespace std; #include #pragma comment(lib, "Rpcrt4.lib") #include #pragma comment(lib, "IPHLPAPI.lib") #pragma comment(lib, "Ws2_32.lib") #define WORKING_BUFFER_SIZE 15000 #define MAX_TRIES 3 #include "CMyWrokerThread.h" #include "C_my_row_set.h" #define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x)) #define FREE(x) HeapFree(GetProcessHeap(), 0, (x)) #define LINE_FOR_PRINT _T("------------------------------------------------------------") typedef enum enum_my_user_msg { msg = 0, add_net_card_list, recv_device_content, } ENUM_MY_USER_MSG; // CRzSearchDlg 对话框 class CRzSearchDlg : public CDialog { // 构造 public: CRzSearchDlg(CWnd* pParent = nullptr); // 标准构造函数 // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_RZ_SEARCH_DIALOG }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现 protected: HICON m_hIcon; // 生成的消息映射函数 virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg LRESULT OnUserMsg1(WPARAM wp, LPARAM lp); afx_msg void OnBnClickedButtonEnumNetCard(); afx_msg void OnBnClickedButtonClearMsg(); afx_msg void OnBnClickedButtonCopyMsg(); afx_msg void OnBnClickedButtonSearchDevice(); DECLARE_MESSAGE_MAP() public: // 线程 - 搜索网卡 private: CMyWrokerThread m_Thread_query_net_card; // 查询网卡的线程 CMyWrokerThread::TAG_REGISTERTHREADPROC m_Thread_query_net_card_param; public: static UINT ThreadProc_query_net_card(void* pParam); UINT ThreadProc_query_net_card(CMyWrokerThread::TAG_REGISTERTHREADPROC* pParam); bool query_net_card(CMyWrokerThread::TAG_REGISTERTHREADPROC* pParam); SOCKET m_SendSocket = INVALID_SOCKET; // 线程 - 搜索设备 private: CMyWrokerThread m_Thread_search_device; CMyWrokerThread::TAG_REGISTERTHREADPROC m_Thread_search_device_param; public: static UINT ThreadProc_search_device(void* pParam); UINT ThreadProc_search_device(CMyWrokerThread::TAG_REGISTERTHREADPROC* pParam); bool search_device(CMyWrokerThread::TAG_REGISTERTHREADPROC* pParam); public: static const UINT USER_MSG1; static CString GUIDgen(); void add_tip(CString csMsg); void add_device_recv_content(CString csMsg); void add_net_card_list(C_my_row_set* p_row_set); CEdit m_ctrl_Edit_msg; std::wstring UTF8ToUnicode(const std::string& str); std::string UnicodeToUTF8(const std::wstring& wstr); std::string my_W2A(std::wstring str); std::wstring my_A2W(std::string str); CListCtrl m_ctrl_list_net_card; CString m_str_net_card_name; CString m_str_net_card_IP; CString m_str_net_card_mac_addr; CString m_str_net_card_ID; CString m_cs_cmd_to_send; CString m_cs_device_content; CString m_cs_UDP_port; }; // rz_searchDlg.cpp: 实现文件 // #include "pch.h" #include "framework.h" #include "rz_search.h" #include "rz_searchDlg.h" #include "afxdialogex.h" #include "C_my_row_set.h" #ifdef _DEBUG #define new DEBUG_NEW #endif #pragma comment(linker, "/SECTION:.shareData,RWS") #pragma data_seg(".shareData") HWND hInstanceWnd = NULL; #pragma data_seg() // 用于应用程序“关于”菜单项的 CAboutDlg 对话框 class CAboutDlg : public CDialogEx { public: CAboutDlg(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_ABOUTBOX }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现 protected: DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) END_MESSAGE_MAP() // CRzSearchDlg 对话框 const UINT CRzSearchDlg::USER_MSG1 = ::RegisterWindowMessage(GUIDgen()); CString CRzSearchDlg::GUIDgen() { GUID guid; HRESULT hRc = CoCreateGuid(&guid); if (S_OK != hRc) { AfxMessageBox(_T("Error: CoCreateGuid")); } RPC_WSTR str = NULL; UuidToString((UUID*)&guid, &str); // CString unique = ((LPTSTR)str); CString unique = ((LPTSTR)str); RpcStringFree(&str); //unique.Replace(_T("-"), _T("_")); CString csMyUUID; csMyUUID.Format(_T("%s-{%s}"), _T("USER_MSG1"), unique); csMyUUID.MakeUpper(); return csMyUUID; } CRzSearchDlg::CRzSearchDlg(CWnd* pParent /*=nullptr*/) : CDialog(IDD_RZ_SEARCH_DIALOG, pParent) , m_cs_cmd_to_send(_T("")) , m_cs_device_content(_T("")) , m_cs_UDP_port(_T("")) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CRzSearchDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_EDIT_MSG, m_ctrl_Edit_msg); DDX_Control(pDX, IDC_LIST_NET_CARD, m_ctrl_list_net_card); DDX_Text(pDX, IDC_EDIT_UDP_CMD_TO_SEND, m_cs_cmd_to_send); DDX_Text(pDX, IDC_EDIT_DEVICE_CONTENT, m_cs_device_content); DDX_Text(pDX, IDC_EDIT_UDP_PORT, m_cs_UDP_port); } BEGIN_MESSAGE_MAP(CRzSearchDlg, CDialog) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON_ENUM_NET_CARD, &CRzSearchDlg::OnBnClickedButtonEnumNetCard) ON_REGISTERED_MESSAGE(USER_MSG1, OnUserMsg1) ON_BN_CLICKED(IDC_BUTTON_CLEAR_MSG, &CRzSearchDlg::OnBnClickedButtonClearMsg) ON_BN_CLICKED(IDC_BUTTON_COPY_MSG, &CRzSearchDlg::OnBnClickedButtonCopyMsg) ON_BN_CLICKED(IDC_BUTTON_SEARCH_DEVICE, &CRzSearchDlg::OnBnClickedButtonSearchDevice) END_MESSAGE_MAP() void CRzSearchDlg::add_tip(CString csMsg) { CString* pcsMsg = new CString; *pcsMsg = csMsg; ::PostMessage(this->m_hWnd, USER_MSG1, ENUM_MY_USER_MSG::msg, (LPARAM)(pcsMsg)); } void CRzSearchDlg::add_device_recv_content(CString csMsg) { CString* pcsMsg = new CString; *pcsMsg = csMsg; ::PostMessage(this->m_hWnd, USER_MSG1, ENUM_MY_USER_MSG::recv_device_content, (LPARAM)(pcsMsg)); } void CRzSearchDlg::add_net_card_list(C_my_row_set* p_row_set) { ::PostMessage(this->m_hWnd, USER_MSG1, ENUM_MY_USER_MSG::add_net_card_list, (LPARAM)(p_row_set)); } // CRzSearchDlg 消息处理程序 LRESULT CRzSearchDlg::OnUserMsg1(WPARAM wp, LPARAM lp) { LRESULT lRc = S_OK; CString csMsg_src; CString csMsg_dst; CTime time; CString str_time; int len = 0; int i_type = (INT)wp; int i = 0; int i_cnt = 0; int j = 0; int j_cnt = 0; C_my_row row; C_my_row_set* p_rowset = NULL; C_my_key_val key_val; int nRow = 0; if (lp) { if (ENUM_MY_USER_MSG::msg == i_type) { CString* pMsg = (CString*)lp; csMsg_src = *pMsg; delete (pMsg); pMsg = NULL; m_ctrl_Edit_msg.GetWindowText(csMsg_dst); len = m_ctrl_Edit_msg.GetWindowTextLength(); if (len >= (1024 * 63)) { csMsg_dst.Empty(); m_ctrl_Edit_msg.GetWindowText(csMsg_dst); } time = CTime::GetCurrentTime(); str_time = time.Format(_T("%Y/%m/%d %H:%M:%S")); csMsg_dst.Empty(); csMsg_dst += str_time; csMsg_dst += " "; csMsg_dst += csMsg_src; csMsg_dst += _T("\r\n"); m_ctrl_Edit_msg.SetSel(len, len); // 将插入光标放在最后 m_ctrl_Edit_msg.ReplaceSel(csMsg_dst); } else if (ENUM_MY_USER_MSG::add_net_card_list == i_type) { p_rowset = (C_my_row_set*)lp; if (NULL != p_rowset) { i_cnt = (int)p_rowset->m_list.GetCount(); for (i = 0; i CString* pMsg = (CString*)lp; csMsg_src = *pMsg; delete (pMsg); pMsg = NULL; this->UpdateData(TRUE); m_cs_device_content = csMsg_src; this->UpdateData(FALSE); } } return lRc; } BOOL CRzSearchDlg::OnInitDialog() { CDialog::OnInitDialog(); hInstanceWnd = m_hWnd; // 将“关于...”菜单项添加到系统菜单中。 // IDM_ABOUTBOX 必须在系统命令范围内。 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动 // 执行此操作 SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此添加额外的初始化代码 LONG lStyle; lStyle = GetWindowLong(m_ctrl_list_net_card.m_hWnd, GWL_STYLE);//获取当前窗口style lStyle &= ~LVS_TYPEMASK; //清除显示方式位 lStyle |= LVS_REPORT; //设置style SetWindowLong(m_ctrl_list_net_card.m_hWnd, GWL_STYLE, lStyle);//设置style DWORD dwStyle = m_ctrl_list_net_card.GetExtendedStyle(); dwStyle |= LVS_EX_FULLROWSELECT;//选中某行使整行高亮(只适用与report风格的listctrl) dwStyle |= LVS_SHOWSELALWAYS; dwStyle |= LVS_EX_GRIDLINES;//网格线(只适用与report风格的listctrl) m_ctrl_list_net_card.SetExtendedStyle(dwStyle); //设置扩展风格 m_ctrl_list_net_card.InsertColumn(0, _T("网卡名称"), LVCFMT_CENTER, 200/*列宽*/, 0); m_ctrl_list_net_card.InsertColumn(1, _T("网卡IP"), LVCFMT_CENTER, 200, 1); m_ctrl_list_net_card.InsertColumn(2, _T("网卡MAC地址"), LVCFMT_CENTER, 200, 1); m_ctrl_list_net_card.InsertColumn(3, _T("网卡实际名称"), LVCFMT_CENTER, 400, 2); this->UpdateData(TRUE); m_cs_UDP_port = _T("12345"); // defualt UDP port m_cs_cmd_to_send = _T("cmd_query"); // default cmd to device this->UpdateData(FALSE); return TRUE; // 除非将焦点设置到控件,否则返回 TRUE } void CRzSearchDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // 如果向对话框添加最小化按钮,则需要下面的代码 // 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序, // 这将由框架自动完成。 void CRzSearchDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); // 使图标在工作区矩形中居中 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // 绘制图标 dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } //当用户拖动最小化窗口时系统调用此函数取得光标 //显示。 HCURSOR CRzSearchDlg::OnQueryDragIcon() { return static_cast(m_hIcon); } void CRzSearchDlg::OnBnClickedButtonEnumNetCard() { // TODO: 在此添加控件通知处理程序代码 add_tip(_T("按钮被点击 - 枚举网卡列表")); do { if (m_Thread_query_net_card.is_running()) { add_tip(_T("任务(枚举网卡列表)进行中..., 请稍候")); break; } m_ctrl_list_net_card.DeleteAllItems(); // 任务执行要放到线程中去做,否则UI卡住 m_Thread_query_net_card_param.pOwner = this; m_Thread_query_net_card_param.pUserData = &m_Thread_query_net_card_param; m_Thread_query_net_card_param.pfnThreadProc = ThreadProc_query_net_card; m_Thread_query_net_card.RegisterThreadProc(&m_Thread_query_net_card_param); // 启动线程 m_Thread_query_net_card.Start(); } while (0); } UINT CRzSearchDlg::ThreadProc_query_net_card(void* pParam) { CMyWrokerThread::TAG_REGISTERTHREADPROC* pThreadInfo = NULL; CRzSearchDlg* pMe = NULL; if (NULL == pParam) { return -1; } pThreadInfo = (CMyWrokerThread::TAG_REGISTERTHREADPROC*)pParam; if (NULL == pThreadInfo->pOwner) { return -1; } pMe = (CRzSearchDlg*)pThreadInfo->pOwner; return pMe->ThreadProc_query_net_card((CMyWrokerThread::TAG_REGISTERTHREADPROC*)pParam); } UINT CRzSearchDlg::ThreadProc_query_net_card(CMyWrokerThread::TAG_REGISTERTHREADPROC* pParam) { add_tip(_T("枚举网卡 - 开始")); add_tip(_T("枚举网卡 ...")); query_net_card(pParam); add_tip(_T("枚举网卡 - 结束")); return 0; } bool CRzSearchDlg::query_net_card(CMyWrokerThread::TAG_REGISTERTHREADPROC* pParam) { // https://docs.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getadaptersaddresses // https://blog.csdn.net/gaiazhang/article/details/9037139 CHAR szIP[130] = { _T('\0') }; CString csMsg; CString csTmp1; CString csTmp2; C_my_row_set* p_row_set = new C_my_row_set; C_my_row row_set; C_my_key_val key_val; /* Declare and initialize variables */ DWORD dwSize = 0; DWORD dwRetVal = 0; unsigned int i = 0; // Set the flags to pass to GetAdaptersAddresses ULONG flags = GAA_FLAG_INCLUDE_PREFIX; // default to unspecified address family (both) ULONG family = AF_UNSPEC; LPVOID lpMsgBuf = NULL; PIP_ADAPTER_ADDRESSES pAddresses = NULL; ULONG outBufLen = 0; ULONG Iterations = 0; PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL; PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL; PIP_ADAPTER_ANYCAST_ADDRESS pAnycast = NULL; PIP_ADAPTER_MULTICAST_ADDRESS pMulticast = NULL; IP_ADAPTER_DNS_SERVER_ADDRESS* pDnServer = NULL; IP_ADAPTER_PREFIX* pPrefix = NULL; family = AF_INET; add_tip(_T("get IPV4 net card info")); outBufLen = /*WORKING_BUFFER_SIZE*/ sizeof(IP_ADAPTER_ADDRESSES) * 100; bool b_rc = false; do { do { pAddresses = (IP_ADAPTER_ADDRESSES*)MALLOC(outBufLen); if (pAddresses == NULL) { add_tip(_T("Memory allocation failed for IP_ADAPTER_ADDRESSES struct")); break; } dwRetVal = GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen); if (dwRetVal == ERROR_BUFFER_OVERFLOW) { add_tip(_T("retry get net card info")); FREE(pAddresses); pAddresses = NULL; } else { break; } Iterations++; } while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations // If successful, output some information from the data we received pCurrAddresses = pAddresses; while (pCurrAddresses) { add_tip(LINE_FOR_PRINT); row_set.clear(); csMsg.Format(_T("\tLength of the IP_ADAPTER_ADDRESS struct: %ld"), pCurrAddresses->Length); add_tip(csMsg); csMsg.Format(_T("\tIfIndex (IPv4 interface): %u"), pCurrAddresses->IfIndex); add_tip(csMsg); csMsg.Format(_T("\tAdapter name: %s"), this->my_A2W(pCurrAddresses->AdapterName).c_str()); add_tip(csMsg); key_val.m_cs_key = _T("Adapter_name"); key_val.m_cs_val = this->my_A2W(pCurrAddresses->AdapterName).c_str(); row_set.m_list.AddTail(key_val); pUnicast = pCurrAddresses->FirstUnicastAddress; if (pUnicast != NULL) { for (i = 0; pUnicast != NULL; i++) { // 只找第一个IP if (0 == i) { csTmp2.Empty(); szIP[0] = '\0'; if (AF_INET == pUnicast->Address.lpSockaddr->sa_family) { // IPV4 地址,使用 IPV4 转换 inet_ntop(PF_INET, &((sockaddr_in*)pUnicast->Address.lpSockaddr)->sin_addr, szIP, sizeof(szIP)); csTmp2 = my_A2W(string(szIP)).c_str(); } else if (AF_INET6 == pUnicast->Address.lpSockaddr->sa_family) { // IPV6 地址,使用 IPV6 转换 inet_ntop(PF_INET6, &((sockaddr_in6*)pUnicast->Address.lpSockaddr)->sin6_addr, szIP, sizeof(szIP)); csTmp2 = my_A2W(string(szIP)).c_str(); } key_val.m_cs_key = _T("First_IP"); key_val.m_cs_val = csTmp2; row_set.m_list.AddTail(key_val); } pUnicast = pUnicast->Next; } csMsg.Format(_T("\tNumber of Unicast Addresses: %d"), i); add_tip(csMsg); } else { csMsg.Format(_T("\tNo Unicast Addresses")); add_tip(csMsg); } pAnycast = pCurrAddresses->FirstAnycastAddress; if (pAnycast) { for (i = 0; pAnycast != NULL; i++) { pAnycast = pAnycast->Next; } csMsg.Format(_T("\tNumber of Anycast Addresses: %d"), i); add_tip(csMsg); } else { csMsg.Format(_T("\tNo Anycast Addresses")); add_tip(csMsg); } pMulticast = pCurrAddresses->FirstMulticastAddress; if (pMulticast) { for (i = 0; pMulticast != NULL; i++) { pMulticast = pMulticast->Next; } csMsg.Format(_T("\tNumber of Multicast Addresses: %d"), i); add_tip(csMsg); } else { csMsg.Format(_T("\tNo Multicast Addresses")); add_tip(csMsg); } pDnServer = pCurrAddresses->FirstDnsServerAddress; if (pDnServer) { for (i = 0; pDnServer != NULL; i++) { pDnServer = pDnServer->Next; } csMsg.Format(_T("\tNumber of DNS Server Addresses: %d"), i); add_tip(csMsg); } else { csMsg.Format(_T("\tNo DNS Server Addresses")); add_tip(csMsg); } csMsg.Format(_T("\tDNS Suffix: %wS"), pCurrAddresses->DnsSuffix); add_tip(csMsg); csMsg.Format(_T("\tDescription: %wS"), pCurrAddresses->Description); add_tip(csMsg); csMsg.Format(_T("\tFriendly name: %wS"), pCurrAddresses->FriendlyName); add_tip(csMsg); key_val.m_cs_key = _T("Friendly_name"); key_val.m_cs_val = pCurrAddresses->FriendlyName; row_set.m_list.AddTail(key_val); if (pCurrAddresses->PhysicalAddressLength != 0) { csTmp2.Empty(); csMsg.Format(_T("\tPhysical address: ")); for (i = 0; i PhysicalAddressLength; i++) { if (i == (pCurrAddresses->PhysicalAddressLength - 1)) { csTmp1.Format(_T("%.2X"), (int)pCurrAddresses->PhysicalAddress[i]); } else { csTmp1.Format(_T("%.2X-"), (int)pCurrAddresses->PhysicalAddress[i]); } csMsg += csTmp1; csTmp2 += csTmp1; } key_val.m_cs_key = _T("Physical_address"); key_val.m_cs_val = csTmp2; row_set.m_list.AddTail(key_val); add_tip(csMsg); } else { key_val.m_cs_key = _T("Physical_address"); key_val.m_cs_val = _T(""); row_set.m_list.AddTail(key_val); } csMsg.Format(_T("\tFlags: %ld"), pCurrAddresses->Flags); add_tip(csMsg); csMsg.Format(_T("\tMtu: %lu"), pCurrAddresses->Mtu); add_tip(csMsg); csMsg.Format(_T("\tIfType: %ld"), pCurrAddresses->IfType); add_tip(csMsg); csMsg.Format(_T("\tOperStatus: %ld"), pCurrAddresses->OperStatus); add_tip(csMsg); csMsg.Format(_T("\tIpv6IfIndex (IPv6 interface): %u"), pCurrAddresses->Ipv6IfIndex); add_tip(csMsg); csMsg.Format(_T("\tZoneIndices (hex): ")); for (i = 0; i csTmp1 += _T(" "); } csMsg += csTmp1; } add_tip(csMsg); csMsg.Format(_T("\tTransmit link speed: %I64u"), pCurrAddresses->TransmitLinkSpeed); add_tip(csMsg); csMsg.Format(_T("\tReceive link speed: %I64u"), pCurrAddresses->ReceiveLinkSpeed); add_tip(csMsg); pPrefix = pCurrAddresses->FirstPrefix; if (pPrefix) { for (i = 0; pPrefix != NULL; i++) { pPrefix = pPrefix->Next; } csMsg.Format(_T("\tNumber of IP Adapter Prefix entries: %d"), i); add_tip(csMsg); } else { csMsg.Format(_T("\tNumber of IP Adapter Prefix entries: 0")); add_tip(csMsg); } p_row_set->m_list.AddTail(row_set); pCurrAddresses = pCurrAddresses->Next; } } else { if (dwRetVal == ERROR_NO_DATA) { } else { if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwRetVal, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR)& lpMsgBuf, 0, NULL)) { add_tip((LPTSTR)lpMsgBuf); LocalFree(lpMsgBuf); } } } b_rc = true; } while (0); if (b_rc) { add_net_card_list(p_row_set); } else { p_row_set->clear(); delete p_row_set; p_row_set = NULL; } if (pAddresses) { FREE(pAddresses); pAddresses = NULL; } return b_rc; } // https://blog.csdn.net/FlushHip/article/details/82836867 std::wstring CRzSearchDlg::UTF8ToUnicode(const std::string& str) { std::wstring ret; try { std::wstring_convert wcv; ret = wcv.from_bytes(str); } catch (const std::exception& e) { // std::cerr std::wstring_convert wcv; ret = wcv.to_bytes(wstr); } catch (const std::exception& e) { // std::cerr USES_CONVERSION; std::wstring str_rc = A2W(str.c_str()); return str_rc; } void CRzSearchDlg::OnBnClickedButtonClearMsg() { // TODO: 在此添加控件通知处理程序代码 this->m_ctrl_Edit_msg.SetWindowTextW(_T("")); } void CRzSearchDlg::OnBnClickedButtonCopyMsg() { // TODO: 在此添加控件通知处理程序代码 int i_text_cb_len = 0; CString csMsg; if (OpenClipboard()) { HGLOBAL clipbuffer; char* buffer; EmptyClipboard(); i_text_cb_len = m_ctrl_Edit_msg.GetWindowTextLengthW() * sizeof(TCHAR); m_ctrl_Edit_msg.GetWindowTextW(csMsg); clipbuffer = GlobalAlloc(GMEM_DDESHARE, i_text_cb_len + 1); buffer = (char*)GlobalLock(clipbuffer); strcpy(buffer, my_W2A(csMsg.GetString()).c_str()); GlobalUnlock(clipbuffer); SetClipboardData(CF_TEXT, clipbuffer); CloseClipboard(); } } void CRzSearchDlg::OnBnClickedButtonSearchDevice() { // TODO: 在此添加控件通知处理程序代码 POSITION pos = NULL; int iRow_index = 0; CString csMsg; do { if (m_Thread_search_device.is_running()) { add_tip(_T("任务(枚举网卡列表)进行中..., 请稍候")); break; } this->UpdateData(TRUE); if (m_cs_cmd_to_send.GetLength() csMsg.Format(_T("请填写要发给设备的UDP端口!")); add_tip(csMsg); break; } this->m_cs_device_content.Empty(); this->UpdateData(FALSE); pos = m_ctrl_list_net_card.GetFirstSelectedItemPosition(); if (NULL != pos) { iRow_index = m_ctrl_list_net_card.GetNextSelectedItem(pos); m_str_net_card_name = m_ctrl_list_net_card.GetItemText(iRow_index, 0); m_str_net_card_IP = m_ctrl_list_net_card.GetItemText(iRow_index, 1); m_str_net_card_mac_addr = m_ctrl_list_net_card.GetItemText(iRow_index, 2); m_str_net_card_ID = m_ctrl_list_net_card.GetItemText(iRow_index, 3); csMsg.Format(_T("目标网卡 - 名称 = [%s]"), m_str_net_card_name); add_tip(csMsg); csMsg.Format(_T("目标网卡 - IP = [%s]"), m_str_net_card_IP); add_tip(csMsg); csMsg.Format(_T("目标网卡 - MAC地址 = [%s]"), m_str_net_card_mac_addr); add_tip(csMsg); csMsg.Format(_T("目标网卡 - UID = [%s]"), m_str_net_card_ID); add_tip(csMsg); csMsg.Format(_T("目标网卡 - 命令 = [%s]"), m_cs_cmd_to_send); add_tip(csMsg); // 任务执行要放到线程中去做,否则UI卡住 m_Thread_search_device_param.pOwner = this; m_Thread_search_device_param.pUserData = &m_Thread_search_device_param; m_Thread_search_device_param.pfnThreadProc = ThreadProc_search_device; m_Thread_search_device.RegisterThreadProc(&m_Thread_search_device_param); // 启动线程 m_Thread_search_device.Start(); } else { add_tip(_T("请先选择要广播的网卡")); } } while (0); } UINT CRzSearchDlg::ThreadProc_search_device(void* pParam) { CMyWrokerThread::TAG_REGISTERTHREADPROC* pThreadInfo = NULL; CRzSearchDlg* pMe = NULL; if (NULL == pParam) { return -1; } pThreadInfo = (CMyWrokerThread::TAG_REGISTERTHREADPROC*)pParam; if (NULL == pThreadInfo->pOwner) { return -1; } pMe = (CRzSearchDlg*)pThreadInfo->pOwner; return pMe->ThreadProc_search_device((CMyWrokerThread::TAG_REGISTERTHREADPROC*)pParam); } UINT CRzSearchDlg::ThreadProc_search_device(CMyWrokerThread::TAG_REGISTERTHREADPROC* pParam) { add_tip(_T("搜索设备 - 开始")); add_tip(_T("搜索设备 ...")); search_device(pParam); add_tip(_T("搜索设备 - 结束")); return 0; } bool CRzSearchDlg::search_device(CMyWrokerThread::TAG_REGISTERTHREADPROC* pParam) { // https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-sendto // https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recvfrom bool b_socket_init_ok = false; bool b_rc = false; int iResult; WSADATA wsaData; sockaddr_in RecvAddr; unsigned short Port = _wtoi(m_cs_UDP_port.GetString())/*65011*/; char SendBuf[1024 * 4]; int BufLen = sizeof(SendBuf); CString csMsg; CString csTmp1; std::string strTmp; int i_rc = 0; char RecvBuf[1024 * 4]; int RecvLen = sizeof(RecvBuf); int ilen_SOCKADDR = 0; do { //---------------------- // Initialize Winsock iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iResult != NO_ERROR) { csMsg.Format(_T("WSAStartup failed with error: %d"), iResult); add_tip(csMsg); break; } b_socket_init_ok = true; //--------------------------------------------- // Create a socket for sending data m_SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (INVALID_SOCKET == m_SendSocket) { csMsg.Format(_T("socket failed with error: %ld"), WSAGetLastError()); add_tip(csMsg); break; } if (true) { const char opt = 1; // char or int all ok //设置该套接字为广播类型, int cb = 0; cb = setsockopt(m_SendSocket, SOL_SOCKET, SO_BROADCAST, (const char*)&opt, sizeof(opt)); if (cb strTmp = my_W2A(m_cs_cmd_to_send.GetString()); BufLen = (int)strTmp.length(); memcpy(SendBuf, strTmp.data(), BufLen); iResult = sendto(m_SendSocket, SendBuf, BufLen, 0, (SOCKADDR*)& RecvAddr, sizeof(RecvAddr)); if (iResult == SOCKET_ERROR) { csMsg.Format(_T("sendto failed with error: %d"), WSAGetLastError()); add_tip(csMsg); break; } memset(RecvBuf, 0, sizeof(RecvBuf)); RecvLen = 512; // ok ilen_SOCKADDR = sizeof(RecvAddr); // ok Sleep(10); iResult = recvfrom(m_SendSocket, RecvBuf, RecvLen, 0, (SOCKADDR*)&RecvAddr, &ilen_SOCKADDR); if (iResult == SOCKET_ERROR) { csMsg.Format(_T("recvfrom failed with error: %d"), WSAGetLastError()); add_tip(csMsg); break; } csMsg.Format(_T("%s"), my_A2W(RecvBuf).c_str()); this->add_device_recv_content(csMsg); } while (0); b_rc = true; } while (0); //--------------------------------------------- // Clean up and quit. csMsg.Format(_T("Exit search")); add_tip(csMsg); //--------------------------------------------- // When the application is finished sending, close the socket. csMsg.Format(_T("Finished sending. Closing socket.")); add_tip(csMsg); if (INVALID_SOCKET != m_SendSocket) { closesocket(m_SendSocket); m_SendSocket = INVALID_SOCKET; } if (b_socket_init_ok) { b_socket_init_ok = false; WSACleanup(); } return b_rc; }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有