最近在做移动端与PC端的交互,主要是实现无线鼠标或远程控制等相关业务,其实核心就是通信和业务。在移动端和PC端按照指定的协议开发完成提测时发现无法通信的问题,现进行记录;
问题描述:局域网内部署的websocket服务,局域网内其它终端无法连接;
原因排查:承载websocket的电脑防火墙全部开启,websocket程序本身与外部通信的功能没有被放行,导致无法与外界通信;
问题处理:代码实现将程序添加到防火墙白名单;如下图所示:
核心代码:
1 #ifndef __PLUGIN_TEACH_STATIC_FirewallTools_H__ 2 #define __PLUGIN_TEACH_STATIC_FirewallTools_H__ 3 #pragma once 4 #include <windows.h> 5 #include <crtdbg.h> 6 #include <netfw.h> 7 #include <objbase.h> 8 #include <oleauto.h> 9 #include <stdio.h> 10 #include <atlstr.h> 11 #include "stdafx.h" 12 13 #pragma comment( lib, "ole32.lib" ) 14 #pragma comment( lib, "oleaut32.lib" ) 15 16 namespace plugin_assistant 17 { 18 //防火墙白名单工具类 19 class FirewallTools 20 { 21 22 HRESULT WindowsFirewallInitialize(OUT INetFwProfile** fwProfile) 23 { 24 HRESULT hr = S_OK; 25 INetFwMgr* fwMgr = NULL; 26 INetFwPolicy* fwPolicy = NULL; 27 28 _ASSERT(fwProfile != NULL); 29 30 *fwProfile = NULL; 31 32 // Create an instance of the firewall settings manager. 33 hr = CoCreateInstance( 34 __uuidof(NetFwMgr), 35 NULL, 36 CLSCTX_INPROC_SERVER, 37 __uuidof(INetFwMgr), 38 (void**)&fwMgr 39 ); 40 if (FAILED(hr)) 41 { 42 printf("CoCreateInstance failed: 0x%08lx\n", hr); 43 goto error; 44 } 45 46 // Retrieve the local firewall policy. 47 hr = fwMgr->get_LocalPolicy(&fwPolicy); 48 if (FAILED(hr)) 49 { 50 printf("get_LocalPolicy failed: 0x%08lx\n", hr); 51 goto error; 52 } 53 54 // Retrieve the firewall profile currently in effect. 55 hr = fwPolicy->get_CurrentProfile(fwProfile); 56 if (FAILED(hr)) 57 { 58 printf("get_CurrentProfile failed: 0x%08lx\n", hr); 59 goto error; 60 } 61 62 error: 63 64 // Release the local firewall policy. 65 if (fwPolicy != NULL) 66 { 67 fwPolicy->Release(); 68 } 69 70 // Release the firewall settings manager. 71 if (fwMgr != NULL) 72 { 73 fwMgr->Release(); 74 } 75 76 return hr; 77 } 78 79 void WindowsFirewallCleanup(IN INetFwProfile* fwProfile) 80 { 81 // Release the firewall profile. 82 if (fwProfile != NULL) 83 { 84 fwProfile->Release(); 85 } 86 } 87 88 HRESULT WindowsFirewallIsOn(IN INetFwProfile* fwProfile, OUT BOOL* fwOn) 89 { 90 HRESULT hr = S_OK; 91 VARIANT_BOOL fwEnabled; 92 93 _ASSERT(fwProfile != NULL); 94 _ASSERT(fwOn != NULL); 95 96 *fwOn = FALSE; 97 98 // Get the current state of the firewall. 99 hr = fwProfile->get_FirewallEnabled(&fwEnabled); 100 if (FAILED(hr)) 101 { 102 printf("get_FirewallEnabled failed: 0x%08lx\n", hr); 103 goto error; 104 } 105 106 // Check to see if the firewall is on. 107 if (fwEnabled != VARIANT_FALSE) 108 { 109 *fwOn = TRUE; 110 printf("The firewall is on.\n"); 111 } 112 else 113 { 114 printf("The firewall is off.\n"); 115 } 116 117 error: 118 119 return hr; 120 } 121 122 HRESULT WindowsFirewallTurnOn(IN INetFwProfile* fwProfile) 123 { 124 HRESULT hr = S_OK; 125 BOOL fwOn; 126 127 _ASSERT(fwProfile != NULL); 128 129 // Check to see if the firewall is off. 130 hr = WindowsFirewallIsOn(fwProfile, &fwOn); 131 if (FAILED(hr)) 132 { 133 printf("WindowsFirewallIsOn failed: 0x%08lx\n", hr); 134 goto error; 135 } 136 137 // If it is, turn it on. 138 if (!fwOn) 139 { 140 // Turn the firewall on. 141 hr = fwProfile->put_FirewallEnabled(VARIANT_TRUE); 142 if (FAILED(hr)) 143 { 144 printf("put_FirewallEnabled failed: 0x%08lx\n", hr); 145 goto error; 146 } 147 148 printf("The firewall is now on.\n"); 149 } 150 151 error: 152 153 return hr; 154 } 155 156 HRESULT WindowsFirewallTurnOff(IN INetFwProfile* fwProfile) 157 { 158 HRESULT hr = S_OK; 159 BOOL fwOn; 160 161 _ASSERT(fwProfile != NULL); 162 163 // Check to see if the firewall is on. 164 hr = WindowsFirewallIsOn(fwProfile, &fwOn); 165 if (FAILED(hr)) 166 { 167 printf("WindowsFirewallIsOn failed: 0x%08lx\n", hr); 168 goto error; 169 } 170 171 // If it is, turn it off. 172 if (fwOn) 173 { 174 // Turn the firewall off. 175 hr = fwProfile->put_FirewallEnabled(VARIANT_FALSE); 176 if (FAILED(hr)) 177 { 178 printf("put_FirewallEnabled failed: 0x%08lx\n", hr); 179 goto error; 180 } 181 182 printf("The firewall is now off.\n"); 183 } 184 185 error: 186 187 return hr; 188 } 189 190 HRESULT WindowsFirewallAppIsEnabled( 191 IN INetFwProfile* fwProfile, 192 IN const wchar_t* fwProcessImageFileName, 193 OUT BOOL* fwAppEnabled 194 ) 195 { 196 HRESULT hr = S_OK; 197 BSTR fwBstrProcessImageFileName = NULL; 198 VARIANT_BOOL fwEnabled; 199 INetFwAuthorizedApplication* fwApp = NULL; 200 INetFwAuthorizedApplications* fwApps = NULL; 201 202 _ASSERT(fwProfile != NULL); 203 _ASSERT(fwProcessImageFileName != NULL); 204 _ASSERT(fwAppEnabled != NULL); 205 206 *fwAppEnabled = FALSE; 207 208 // Retrieve the authorized application collection. 209 hr = fwProfile->get_AuthorizedApplications(&fwApps); 210 if (FAILED(hr)) 211 { 212 printf("get_AuthorizedApplications failed: 0x%08lx\n", hr); 213 goto error; 214 } 215 216 // Allocate a BSTR for the process image file name. 217 fwBstrProcessImageFileName = SysAllocString(fwProcessImageFileName); 218 if (fwBstrProcessImageFileName == NULL) 219 { 220 hr = E_OUTOFMEMORY; 221 printf("SysAllocString failed: 0x%08lx\n", hr); 222 goto error; 223 } 224 225 // Attempt to retrieve the authorized application. 226 hr = fwApps->Item(fwBstrProcessImageFileName, &fwApp); 227 if (SUCCEEDED(hr)) 228 { 229 // Find out if the authorized application is enabled. 230 hr = fwApp->get_Enabled(&fwEnabled); 231 if (FAILED(hr)) 232 { 233 printf("get_Enabled failed: 0x%08lx\n", hr); 234 goto error; 235 } 236 237 if (fwEnabled != VARIANT_FALSE) 238 { 239 // The authorized application is enabled. 240 *fwAppEnabled = TRUE; 241 242 printf( 243 "Authorized application %lS is enabled in the firewall.\n", 244 fwProcessImageFileName 245 ); 246 } 247 else 248 { 249 printf( 250 "Authorized application %lS is disabled in the firewall.\n", 251 fwProcessImageFileName 252 ); 253 } 254 } 255 else 256 { 257 // The authorized application was not in the collection. 258 hr = S_OK; 259 260 printf( 261 "Authorized application %lS is disabled in the firewall.\n", 262 fwProcessImageFileName 263 ); 264 } 265 266 error: 267 268 // Free the BSTR. 269 SysFreeString(fwBstrProcessImageFileName); 270 271 // Release the authorized application instance. 272 if (fwApp != NULL) 273 { 274 fwApp->Release(); 275 } 276 277 // Release the authorized application collection. 278 if (fwApps != NULL) 279 { 280 fwApps->Release(); 281 } 282 283 return hr; 284 } 285 286 287 HRESULT WindowsFirewallAddApp( 288 IN INetFwProfile* fwProfile, 289 IN const wchar_t* fwProcessImageFileName, 290 IN const wchar_t* fwName 291 ) 292 { 293 HRESULT hr = S_OK; 294 BOOL fwAppEnabled; 295 BSTR fwBstrName = NULL; 296 BSTR fwBstrProcessImageFileName = NULL; 297 INetFwAuthorizedApplication* fwApp = NULL; 298 INetFwAuthorizedApplications* fwApps = NULL; 299 300 _ASSERT(fwProfile != NULL); 301 _ASSERT(fwProcessImageFileName != NULL); 302 _ASSERT(fwName != NULL); 303 304 // First check to see if the application is already authorized. 305 hr = WindowsFirewallAppIsEnabled( 306 fwProfile, 307 fwProcessImageFileName, 308 &fwAppEnabled 309 ); 310 if (FAILED(hr)) 311 { 312 printf("WindowsFirewallAppIsEnabled failed: 0x%08lx\n", hr); 313 goto error; 314 } 315 316 // Only add the application if it isn‘t already authorized. 317 if (!fwAppEnabled) 318 { 319 // Retrieve the authorized application collection. 320 hr = fwProfile->get_AuthorizedApplications(&fwApps); 321 if (FAILED(hr)) 322 { 323 printf("get_AuthorizedApplications failed: 0x%08lx\n", hr); 324 goto error; 325 } 326 327 // Create an instance of an authorized application. 328 hr = CoCreateInstance( 329 __uuidof(NetFwAuthorizedApplication), 330 NULL, 331 CLSCTX_INPROC_SERVER, 332 __uuidof(INetFwAuthorizedApplication), 333 (void**)&fwApp 334 ); 335 if (FAILED(hr)) 336 { 337 printf("CoCreateInstance failed: 0x%08lx\n", hr); 338 goto error; 339 } 340 341 // Allocate a BSTR for the process image file name. 342 fwBstrProcessImageFileName = SysAllocString(fwProcessImageFileName); 343 if (fwBstrProcessImageFileName == NULL) 344 { 345 hr = E_OUTOFMEMORY; 346 printf("SysAllocString failed: 0x%08lx\n", hr); 347 goto error; 348 } 349 350 // Set the process image file name. 351 hr = fwApp->put_ProcessImageFileName(fwBstrProcessImageFileName); 352 if (FAILED(hr)) 353 { 354 printf("put_ProcessImageFileName failed: 0x%08lx\n", hr); 355 goto error; 356 } 357 358 // Allocate a BSTR for the application friendly name. 359 fwBstrName = SysAllocString(fwName); 360 if (SysStringLen(fwBstrName) == 0) 361 { 362 hr = E_OUTOFMEMORY; 363 printf("SysAllocString failed: 0x%08lx\n", hr); 364 goto error; 365 } 366 367 // Set the application friendly name. 368 hr = fwApp->put_Name(fwBstrName); 369 if (FAILED(hr)) 370 { 371 printf("put_Name failed: 0x%08lx\n", hr); 372 goto error; 373 } 374 375 // Add the application to the collection. 376 hr = fwApps->Add(fwApp); 377 if (FAILED(hr)) 378 { 379 printf("Add failed: 0x%08lx\n", hr); 380 goto error; 381 } 382 383 printf( 384 "Authorized application %lS is now enabled in the firewall.\n", 385 fwProcessImageFileName 386 ); 387 } 388 389 error: 390 391 // Free the BSTRs. 392 SysFreeString(fwBstrName); 393 SysFreeString(fwBstrProcessImageFileName); 394 395 // Release the authorized application instance. 396 if (fwApp != NULL) 397 { 398 fwApp->Release(); 399 } 400 401 // Release the authorized application collection. 402 if (fwApps != NULL) 403 { 404 fwApps->Release(); 405 } 406 407 return hr; 408 } 409 410 HRESULT WindowsFirewallPortIsEnabled( 411 IN INetFwProfile* fwProfile, 412 IN LONG portNumber, 413 IN NET_FW_IP_PROTOCOL ipProtocol, 414 OUT BOOL* fwPortEnabled 415 ) 416 { 417 HRESULT hr = S_OK; 418 VARIANT_BOOL fwEnabled; 419 INetFwOpenPort* fwOpenPort = NULL; 420 INetFwOpenPorts* fwOpenPorts = NULL; 421 422 _ASSERT(fwProfile != NULL); 423 _ASSERT(fwPortEnabled != NULL); 424 425 *fwPortEnabled = FALSE; 426 427 // Retrieve the globally open ports collection. 428 hr = fwProfile->get_GloballyOpenPorts(&fwOpenPorts); 429 if (FAILED(hr)) 430 { 431 printf("get_GloballyOpenPorts failed: 0x%08lx\n", hr); 432 goto error; 433 } 434 435 // Attempt to retrieve the globally open port. 436 hr = fwOpenPorts->Item(portNumber, ipProtocol, &fwOpenPort); 437 if (SUCCEEDED(hr)) 438 { 439 // Find out if the globally open port is enabled. 440 hr = fwOpenPort->get_Enabled(&fwEnabled); 441 if (FAILED(hr)) 442 { 443 printf("get_Enabled failed: 0x%08lx\n", hr); 444 goto error; 445 } 446 447 if (fwEnabled != VARIANT_FALSE) 448 { 449 // The globally open port is enabled. 450 *fwPortEnabled = TRUE; 451 452 printf("Port %ld is open in the firewall.\n", portNumber); 453 } 454 else 455 { 456 printf("Port %ld is not open in the firewall.\n", portNumber); 457 } 458 } 459 else 460 { 461 // The globally open port was not in the collection. 462 hr = S_OK; 463 464 printf("Port %ld is not open in the firewall.\n", portNumber); 465 } 466 467 error: 468 469 // Release the globally open port. 470 if (fwOpenPort != NULL) 471 { 472 fwOpenPort->Release(); 473 } 474 475 // Release the globally open ports collection. 476 if (fwOpenPorts != NULL) 477 { 478 fwOpenPorts->Release(); 479 } 480 481 return hr; 482 } 483 484 485 HRESULT WindowsFirewallPortAdd( 486 IN INetFwProfile* fwProfile, 487 IN LONG portNumber, 488 IN NET_FW_IP_PROTOCOL ipProtocol, 489 IN const wchar_t* name 490 ) 491 { 492 HRESULT hr = S_OK; 493 BOOL fwPortEnabled; 494 BSTR fwBstrName = NULL; 495 INetFwOpenPort* fwOpenPort = NULL; 496 INetFwOpenPorts* fwOpenPorts = NULL; 497 498 _ASSERT(fwProfile != NULL); 499 _ASSERT(name != NULL); 500 501 // First check to see if the port is already added. 502 hr = WindowsFirewallPortIsEnabled( 503 fwProfile, 504 portNumber, 505 ipProtocol, 506 &fwPortEnabled 507 ); 508 if (FAILED(hr)) 509 { 510 printf("WindowsFirewallPortIsEnabled failed: 0x%08lx\n", hr); 511 goto error; 512 } 513 514 // Only add the port if it isn‘t already added. 515 if (!fwPortEnabled) 516 { 517 // Retrieve the collection of globally open ports. 518 hr = fwProfile->get_GloballyOpenPorts(&fwOpenPorts); 519 if (FAILED(hr)) 520 { 521 printf("get_GloballyOpenPorts failed: 0x%08lx\n", hr); 522 goto error; 523 } 524 525 // Create an instance of an open port. 526 hr = CoCreateInstance( 527 __uuidof(NetFwOpenPort), 528 NULL, 529 CLSCTX_INPROC_SERVER, 530 __uuidof(INetFwOpenPort), 531 (void**)&fwOpenPort 532 ); 533 if (FAILED(hr)) 534 { 535 printf("CoCreateInstance failed: 0x%08lx\n", hr); 536 goto error; 537 } 538 539 // Set the port number. 540 hr = fwOpenPort->put_Port(portNumber); 541 if (FAILED(hr)) 542 { 543 printf("put_Port failed: 0x%08lx\n", hr); 544 goto error; 545 } 546 547 // Set the IP protocol. 548 hr = fwOpenPort->put_Protocol(ipProtocol); 549 if (FAILED(hr)) 550 { 551 printf("put_Protocol failed: 0x%08lx\n", hr); 552 goto error; 553 } 554 555 // Allocate a BSTR for the friendly name of the port. 556 fwBstrName = SysAllocString(name); 557 if (SysStringLen(fwBstrName) == 0) 558 { 559 hr = E_OUTOFMEMORY; 560 printf("SysAllocString failed: 0x%08lx\n", hr); 561 goto error; 562 } 563 564 // Set the friendly name of the port. 565 hr = fwOpenPort->put_Name(fwBstrName); 566 if (FAILED(hr)) 567 { 568 printf("put_Name failed: 0x%08lx\n", hr); 569 goto error; 570 } 571 572 // Opens the port and adds it to the collection. 573 hr = fwOpenPorts->Add(fwOpenPort); 574 if (FAILED(hr)) 575 { 576 printf("Add failed: 0x%08lx\n", hr); 577 goto error; 578 } 579 580 printf("Port %ld is now open in the firewall.\n", portNumber); 581 } 582 583 error: 584 585 // Free the BSTR. 586 SysFreeString(fwBstrName); 587 588 // Release the open port instance. 589 if (fwOpenPort != NULL) 590 { 591 fwOpenPort->Release(); 592 } 593 594 // Release the globally open ports collection. 595 if (fwOpenPorts != NULL) 596 { 597 fwOpenPorts->Release(); 598 } 599 600 return hr; 601 } 602 603 public: 604 //将指定程序添加到防火墙 605 void AddProgramWindowsFirewall(std::string filepath,string filename) 606 { 607 HRESULT hr = S_OK; 608 HRESULT comInit = E_FAIL; 609 INetFwProfile* fwProfile = NULL; 610 611 // Initialize COM. 612 comInit = CoInitializeEx(0,COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); 613 614 // Ignore RPC_E_CHANGED_MODE; this just means that COM has already been 615 // initialized with a different mode. Since we don‘t care what the mode is, 616 // we‘ll just use the existing mode. 617 if (comInit != RPC_E_CHANGED_MODE) 618 { 619 hr = comInit; 620 if (FAILED(hr)) 621 { 622 printf("CoInitializeEx failed: 0x%08lx\n", hr); 623 goto error; 624 } 625 } 626 627 // Retrieve the firewall profile currently in effect. 628 hr = WindowsFirewallInitialize(&fwProfile); 629 if (FAILED(hr)) 630 { 631 printf("WindowsFirewallInitialize failed: 0x%08lx\n", hr); 632 goto error; 633 } 634 635 //// Turn off the firewall. 636 //hr = WindowsFirewallTurnOff(fwProfile); 637 //if (FAILED(hr)) 638 //{ 639 // printf("WindowsFirewallTurnOff failed: 0x%08lx\n", hr); 640 // goto error; 641 //} 642 643 //// Turn on the firewall. 644 //hr = WindowsFirewallTurnOn(fwProfile); 645 //if (FAILED(hr)) 646 //{ 647 // printf("WindowsFirewallTurnOn failed: 0x%08lx\n", hr); 648 // goto error; 649 //} 650 651 // Add Windows Messenger to the authorized application collection. 652 hr = WindowsFirewallAddApp(fwProfile, CA2T(filepath.c_str()), CA2T(filename.c_str())); 653 if (FAILED(hr)) 654 { 655 printf("WindowsFirewallAddApp failed: 0x%08lx\n", hr); 656 goto error; 657 } 658 659 //// Add TCP::80 to list of globally open ports. 660 //hr = WindowsFirewallPortAdd(fwProfile, 80, NET_FW_IP_PROTOCOL_TCP, L"WWW"); 661 //if (FAILED(hr)) 662 //{ 663 // printf("WindowsFirewallPortAdd failed: 0x%08lx\n", hr); 664 // goto error; 665 //} 666 667 error: 668 669 // Release the firewall profile. 670 WindowsFirewallCleanup(fwProfile); 671 672 // Uninitialize COM. 673 if (SUCCEEDED(comInit)) 674 { 675 CoUninitialize(); 676 } 677 } 678 }; 679 } // namespace wnd_teach 680 #endif //__PLUGIN_TEACH_STATIC_FirewallTools_H__
具体使用:
1 //把websocket服务加入到网络防火墙白名单 2 char szFullPath[MAX_PATH]; 3 ZeroMemory(szFullPath, MAX_PATH); 4 ::GetModuleFileNameA(NULL, szFullPath, MAX_PATH); 5 (strrchr(szFullPath, ‘\\‘))[0] = 0; // 删除文件名,只获得路径字串 6 strcat(szFullPath, "\\plugins\\plugin_websocket.exe"); 7 if (TRUE == FileObjectExists(CA2T(szFullPath))) 8 { 9 FirewallTools* winfirewall = new FirewallTools(); 10 //添加到防火墙白名单 11 winfirewall->AddProgramWindowsFirewall(szFullPath, "websocket服务插件"); 12 }
C++ win32本地运行的websocket服务 客户端无法连接的问题
原文:https://www.cnblogs.com/A1AA/p/12199666.html