在 win32 服务 (C++) 中生成 casablanca http_listener 的问题
Posted
技术标签:
【中文标题】在 win32 服务 (C++) 中生成 casablanca http_listener 的问题【英文标题】:Issues spawning a casablanca http_listener in a win32 service (C++) 【发布时间】:2020-05-13 11:55:04 【问题描述】:由于某种原因,我无法在我的 Windows 服务主线程中启动我的侦听器,代码编译时没有警告并且我没有收到任何链接错误,cpprestsdk DLL 由进程正确加载(使用 procmon 验证)但是,听众不是在“听”:-)。该服务作为 NT AUTHORITY\SYSTEM 运行。在 win32 服务(x64 架构)中运行它是否有任何限制:
DWORD WINAPI ServiceWorkerThread(LPVOID lpParam)
//
// Periodically check if the service has been requested to stop
while (WaitForSingleObject(g_ServiceStopEvent, 0) != WAIT_OBJECT_0)
/*
* Perform main service function here
*/
webserver();
return ERROR_SUCCESS;
这里是 webserver() 的实现:
#include <iostream>
#include <cpprest/http_listener.h>
#include <cpprest/json.h>
#include <map>
#include <set>
#include <string>
using namespace web;
using namespace web::http;
using namespace web::http::experimental::listener;
using namespace std;
void handle_GET(http_request message)
message.reply(status_codes::OK, "<html><body><h1>Hello World !</h1></body></html>", u8"text/html");
return;
void webserver()
http_listener listener(L"http://127.0.0.1/api");
listener.support(methods::GET, handle_GET);
listener.open().wait();
如果我简单地将它编译为普通的可执行文件并从 main() 运行它,这个函数就可以工作...
任何想法为什么我会出现这种奇怪的行为?
PS:即使监听器不工作,服务也能正确启动和停止。我正在使用这个框架 Windows 服务模板 (Windows Service Template)
我正在使用 Microsoft Visual Studio 2017 编译所有内容。
编辑:通过禁用防火墙并以管理员权限运行 netstat,该服务似乎正在侦听 127.0.0.1 地址上的端口 80,但是我仍然没有收到 HTTP 响应并且运行“netstat -an | findstr 80”时,监听端口似乎会打开和关闭:
Screenshot
【问题讨论】:
您在哪个服务帐户下运行?有些帐户没有网络访问权限。 嗨,它正在使用 SYSTEM 帐户运行。 阅读 - ***.com/questions/10942916/… 有趣,但在我的情况下,它不是防火墙,因为当我运行“netstat -a”并且我试图通过环回地址(127.0.0.1)连接时,端口甚至没有绑定像这样:“wget 127.0.0.1:80/api” 我的错误,如果我禁用防火墙和杀毒软件,端口正在监听...但是,http 请求没有得到任何响应。 【参考方案1】:好的,我最终这样做了,这似乎“解决”了这个问题:
#include <iostream>
#include <cpprest/http_listener.h>
#include <cpprest/json.h>
#include <map>
#include <set>
#include <string>
#include <Windows.h>
using namespace web;
using namespace web::http;
using namespace web::http::experimental::listener;
using namespace std;
void handle_GET(http_request message)
message.reply(status_codes::OK, "<html><body><h1>Hello World !</h1></body></html>", u8"text/html");
return;
void webserver()
http_listener listener(L"http://127.0.0.1/api");
listener.support(methods::GET, handle_GET);
listener.open().wait();
::Sleep(1000000000000000000);
但我认为这很讨厌,我怀疑它只是根据睡眠时间来回摆动...
#include "api.h"
#include <thread>
#include "ServiceWorkerThread.h"
DWORD WINAPI ServiceWorkerThread(LPVOID lpParam)
//
// Periodically check if the service has been requested to stop
while (WaitForSingleObject(g_ServiceStopEvent, 0) != WAIT_OBJECT_0)
/*
* Perform main service function here
*/
webserver();
return ERROR_SUCCESS;
关于如何做这个清洁剂的任何建议?
解决方案:我最终像这样更改代码:
#include <iostream>
#include <cpprest/http_listener.h>
#include <cpprest/json.h>
#include <map>
#include <set>
#include <string>
#include <Windows.h>
#include "ServiceWorkerThread.h"
using namespace web;
using namespace web::http;
using namespace web::http::experimental::listener;
using namespace std;
void handle_GET(http_request message)
message.reply(status_codes::OK, "<html><body><h1>Hello World !</h1></body></html>", u8"text/html");
return;
long webserver()
http_listener listener(L"http://127.0.0.1/api");
listener.support(methods::GET, handle_GET);
listener.open().wait();
//
// Periodically check if the service has been requested to stop
while (WaitForSingleObject(g_ServiceStopEvent, 0) != WAIT_OBJECT_0)
/*
* Perform main service function here
*/
return ERROR_SUCCESS;
#include "api.h"
#include <thread>
#include "ServiceWorkerThread.h"
DWORD WINAPI ServiceWorkerThread(LPVOID lpParam)
long ret = webserver();
return ret;
除了在 Windows 防火墙中例外...
【讨论】:
欢迎accept your own answer。以上是关于在 win32 服务 (C++) 中生成 casablanca http_listener 的问题的主要内容,如果未能解决你的问题,请参考以下文章