Beenden Multithreaded Pipe Server



  • Hallo,

    Ich habe folgendes Beispiel von der MSDN Seite. Dieses Beispiel funktioniert einwandfrei.

    http://msdn.microsoft.com/en-us/library/aa365588(VS.85).aspx

    #include <windows.h> 
    #include <stdio.h> 
    #include <tchar.h>
    #include <strsafe.h>
    
    #define BUFSIZE 4096
    
    DWORD WINAPI InstanceThread(LPVOID); 
    VOID GetAnswerToRequest(LPTSTR, LPTSTR, LPDWORD); 
    
    int _tmain(VOID) 
    { 
       BOOL fConnected; 
       DWORD dwThreadId; 
       HANDLE hPipe, hThread; 
       LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe"); 
    
    // The main loop creates an instance of the named pipe and 
    // then waits for a client to connect to it. When the client 
    // connects, a thread is created to handle communications 
    // with that client, and the loop is repeated. 
    
       for (;;) 
       { 
          hPipe = CreateNamedPipe( 
              lpszPipename,             // pipe name 
              PIPE_ACCESS_DUPLEX,       // read/write access 
              PIPE_TYPE_MESSAGE |       // message type pipe 
              PIPE_READMODE_MESSAGE |   // message-read mode 
              PIPE_WAIT,                // blocking mode 
              PIPE_UNLIMITED_INSTANCES, // max. instances  
              BUFSIZE,                  // output buffer size 
              BUFSIZE,                  // input buffer size 
              0,                        // client time-out 
              NULL);                    // default security attribute 
    
          if (hPipe == INVALID_HANDLE_VALUE) 
          {
              printf("CreatePipe failed"); 
              return 0;
          }
    
          // Wait for the client to connect; if it succeeds, 
          // the function returns a nonzero value. If the function
          // returns zero, GetLastError returns ERROR_PIPE_CONNECTED. 
    
          fConnected = ConnectNamedPipe(hPipe, NULL) ? 
             TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); 
    
          if (fConnected) 
          { 
          // Create a thread for this client. 
             hThread = CreateThread( 
                NULL,              // no security attribute 
                0,                 // default stack size 
                InstanceThread,    // thread proc
                (LPVOID) hPipe,    // thread parameter 
                0,                 // not suspended 
                &dwThreadId);      // returns thread ID 
    
             if (hThread == NULL) 
             {
                printf("CreateThread failed"); 
                return 0;
             }
             else CloseHandle(hThread); 
           } 
          else 
            // The client could not connect, so close the pipe. 
             CloseHandle(hPipe); 
       } 
       return 1; 
    } 
    
    DWORD WINAPI InstanceThread(LPVOID lpvParam) 
    { 
       TCHAR chRequest[BUFSIZE]; 
       TCHAR chReply[BUFSIZE]; 
       DWORD cbBytesRead, cbReplyBytes, cbWritten; 
       BOOL fSuccess; 
       HANDLE hPipe; 
    
    // The thread's parameter is a handle to a pipe instance. 
    
       hPipe = (HANDLE) lpvParam; 
    
       while (1) 
       { 
       // Read client requests from the pipe. 
          fSuccess = ReadFile( 
             hPipe,        // handle to pipe 
             chRequest,    // buffer to receive data 
             BUFSIZE*sizeof(TCHAR), // size of buffer 
             &cbBytesRead, // number of bytes read 
             NULL);        // not overlapped I/O 
    
          if (! fSuccess || cbBytesRead == 0) 
             break; 
          GetAnswerToRequest(chRequest, chReply, &cbReplyBytes); 
    
       // Write the reply to the pipe. 
          fSuccess = WriteFile( 
             hPipe,        // handle to pipe 
             chReply,      // buffer to write from 
             cbReplyBytes, // number of bytes to write 
             &cbWritten,   // number of bytes written 
             NULL);        // not overlapped I/O 
    
          if (! fSuccess || cbReplyBytes != cbWritten) break; 
      } 
    
    // Flush the pipe to allow the client to read the pipe's contents 
    // before disconnecting. Then disconnect the pipe, and close the 
    // handle to this pipe instance. 
    
       FlushFileBuffers(hPipe); 
       DisconnectNamedPipe(hPipe); 
       CloseHandle(hPipe); 
    
       return 1;
    }
    
    VOID GetAnswerToRequest(LPTSTR chRequest, 
       LPTSTR chReply, LPDWORD pchBytes)
    {
       _tprintf( TEXT("%s\n"), chRequest );
       StringCchCopy( chReply, BUFSIZE, TEXT("Default answer from server") );
       *pchBytes = (lstrlen(chReply)+1)*sizeof(TCHAR);
    }
    

    Die Frage ist, was passiert beim Beenden des Programms? Das Programm wartet bei ConnectNamedPipe auf weitere Client-Verbindungen. Wenn ich jetzt das Programm schliesse wird es "abgewürgt". Beim Beenden möchte ich jedoch noch einiges "Erledigen".
    Wie kann dieses Beispiel sauber programmiert werden, so dass das main auch einen Wert zurückgibt und das Programm korrekt beendet wird?

    Danke und Gruss


  • Mod

    Seze einen eigenen Controlhandler der z.B. Ctrl+C behandelt.
    Seze ein Flag für den Abbruch
    Prüfe dieses Abbruchsflag in der Schleife.

    http://msdn.microsoft.com/en-us/library/ms686016(VS.85).aspx



  • Hallo,

    Vielen Dank, bin auch gerade darauf gestossen. Unter dem folgendem Link ist auch noch ein Beispiel:
    http://www.codeproject.com/KB/winsdk/console_event_handling.aspx

    Gruss


Anmelden zum Antworten