C++ win32本地运行的websocket服务 客户端无法连接的问题

最近在做移动端与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     }
posted @ 2020-01-16 09:32  A1A  阅读(1421)  评论(0编辑  收藏  举报