2009-08-12 104 views
0

嘿,即時通訊在Windows服務中做一些客戶端/服務器的東西。這個東西非常新。CAsyncSocket ::關閉崩潰

我遇到的問題是,當我嘗試通過服務管理器停止服務時,它崩潰。我添加了一些MessageBoxes代碼,以追蹤它們在哪裏崩潰,並且我發現當它關閉偵聽器套接字時,它會崩潰!

我想作爲控制檯應用程序運行服務,並通過自己的所謂被稱爲SERVICE__CONTROL__STOP收到事件,讓我可以重現bug和調試容易的功能。但它工作正常。 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

在發行版或調試版中重現崩潰? – zabulus 2010-03-17 11:45:09

回答

-1

問題是,你很可能使用來自多個線程的套接字。多線程和CAsyncSocket不會混合 - 事實上,正如文檔所述。

通常你會將套接字插入到它自己的工作線程中,然後當你需要時它會發出信號。

+0

我的服務是單線程的。我不知道如果MFC內部或Windows服務內部創建另一個線程的操作 – akif 2009-08-12 10:24:49

+0

一個簡單的方法來檢查肯定會使用GetCurrentThreadId()。只需將結果記錄在創建/初始化套接字的位置,然後再次關閉套接字(OnStop例程)即可。然後運行你的服務,看看結果是什麼。如果值不同,則有多個線程觸及該代碼。 – TheUndeadFish 2009-08-12 22:26:25

+0

好的,只是試過了,但沒有線程ID是相同的,所以只有一個線程在運行。 – akif 2009-08-13 06:45:35

1

嘗試增加: -

WSADATA data; 
if(!AfxSocketInit(&data)) 
    AfxMessageBox("Failed to Initialize Sockets",MB_OK| MB_ICONSTOP); 

到你的線程或類初始化器。