windows中手工调整活动路由表的简单方法 | 您所在的位置:网站首页 › windows永久路由不生效 › windows中手工调整活动路由表的简单方法 |
前言
我司有个小程序,用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块。 为了这个试验,开始想写的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 实验室设备网 版权所有 |