0

ねえ、私はWindowsサービスでクライアント/サーバーのことをやっています。このことについてはかなり新しい。

私が直面している問題は、Service Manager を使用してサービスを停止しようとすると、クラッシュすることです。MessageBoxes コードをいくつか追加して、クラッシュしている場所を追跡したところ、リスナー ソケットを閉じるとクラッシュすることがわかりました!!!

コンソールアプリケーションとしてサービスを実行しようとしたところ、自分でSERVICE__CONTROL__STOPイベントと呼ばれる関数を呼び出して、バグの再現とデバッグを簡単に行えるようにしました。しかし、それはうまく機能しています。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);
}

EDIT:接続が確立され(クライアントがサーバーに接続し)、クライアントが接続を閉じてからサービスが停止した場合、何もクラッシュしません。ソケットがリッスンしていて接続が受け入れられない場合、またはクライアントが接続を閉じずにサービスが停止した場合にのみクラッシュします:)

クリアだと思います!

4

2 に答える 2

1

追加してみてください:-

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

スレッドまたはクラスの初期化子に。

于 2011-01-27T12:24:25.673 に答える
-1

問題は、複数のスレッドからソケットを使用している可能性が高いことです。実際、ドキュメントに記載されているように、複数のスレッドと CAsyncSocket は混在しません。

通常、ソケットを独自のワーカー スレッドにプッシュし、必要なときに閉じるように信号を送ります。

于 2009-08-12T10:10:17.203 に答える