嘿,我在Windows服务中做一些客户端/服务器的东西。这个东西真的很新。
我遇到的问题是,当我尝试通过Service Manager停止服务时,它会崩溃。我添加了一些MessageBoxes代码,以跟踪它们崩溃的位置,我发现当它关闭监听器套接字时它会崩溃!!!
我尝试将服务作为控制台应用程序运行,并且我自己调用了名为 SERVICE__CONTROL__STOP 事件的函数,以便我可以重现错误并轻松调试。但它工作正常。当我通过Service Manager
停止时,Windows服务才会崩溃这是一些代码
主要功能
int main(int argc, char* argv[])
{
// Create the service object
CTestService CustomServiceObject;
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
std::cerr << "MFC failed to initialize!" << std::endl;
return 1;
}
// Parse for standard arguments (install, uninstall, version etc.)
if (! CustomServiceObject.ParseStandardArgs(argc, argv))
{
// StartService() calls ::StartServiceCtrlDispatcher()
// with the ServiceMain func and stuff
CustomServiceObject.StartService();
}
// When we get here, the service has been stopped
return CustomServiceObject.m_Status.dwWin32ExitCode;
}
服务处理程序回调函数
// static member function (callback) to handle commands from the
// service control manager
void CNTService::Handler(DWORD dwOpcode)
{
// Get a pointer to the object
CNTService* pService = m_pThis;
pService->DebugMsg("CNTService::Handler(%lu)", dwOpcode);
switch (dwOpcode) {
case SERVICE_CONTROL_STOP: // 1
pService->SetStatus(SERVICE_STOP_PENDING);
pService->OnStop();
// ..
// ..
// other event handling
// ..
// ..
}
OnStop()函数
void CTestService::OnStop()
{
m_sListener.ShutDown(2);
m_sConnected.ShutDown(2);
MessageBox(NULL, "After Shutdown", NULL, IDOK);
m_sConnected.Close();
MessageBox(NULL, "Closed connected socket", NULL, IDOK);
// crashes here when I try to stop through service manager
// but if I run as console application works fine and terminates successfully
m_sListener.Close();
MessageBox(NULL, "Closed listener socket", NULL, IDOK);
::PostThreadMessage(m_dwThreadID, WM_QUIT, NULL, NULL);
MessageBox(NULL, "After PostThreadMessage", NULL, IDOK);
}
编辑:如果建立连接(客户端连接到服务器)并且客户端关闭连接,然后服务停止,则不会发生任何崩溃。如果套接字正在侦听并且没有接受连接或客户端没有关闭连接并且服务停止,它只会崩溃:)
我猜它很清楚!
答案 0 :(得分:1)
尝试添加: -
WSADATA data;
if(!AfxSocketInit(&data))
AfxMessageBox("Failed to Initialize Sockets",MB_OK| MB_ICONSTOP);
到您的主题或类初始化程序。
答案 1 :(得分:-1)
问题是您最有可能使用来自多个线程的套接字。多线程和CAsyncSocket不混合 - 实际上,如文档所述。
通常你会将套接字推入它自己的工作线程中,然后当你需要时它会发出信号关闭它。