NMPIPE.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:9k
源码类别:
Windows编程
开发平台:
Visual C++
- /******************************************************************************
- * This is a part of the Microsoft Source Code Samples.
- * Copyright (C) 1993-1997 Microsoft Corporation.
- * All rights reserved.
- * This source code is only intended as a supplement to
- * Microsoft Development Tools and/or WinHelp documentation.
- * See these sources for detailed information regarding the
- * Microsoft samples programs.
- ******************************************************************************/
- #include <stdio.h>
- #include <windows.h>
- #include <stdlib.h>
- #include <process.h>
- /* Error checking macro. If bSuccess == TRUE, print error info */
- #define PERR(bSuccess, szApi) {if (!(bSuccess)) printf("%s: Error %d from %s
- on line %dn", __FILE__, GetLastError(), szApi, __LINE__);}
- #define DEFNAME "\\.\pipe\nmpipe" /* Default pipe name */
- /* Define OVERLAPPED_IO to TRUE to use Overlapped IO. Otherwise define as
- FALSE */
- //#define OVERLAPPED_IO TRUE
- #define OVERLAPPED_IO FALSE
- /* structure to pass into the writer thread */
- typedef struct {
- HANDLE hPipe; /* pipe write handle */
- char *szData; /* data to repeatedly write */
- int iDataSize; /* size of buffer pointed to by szData */
- } WRITER_PARAMS;
- /*
- ** BOOL pipeCheck(HANDLE h)
- *
- * PARAMETERS: HANDLE hPipe: pipe handle to close if an error condition exists
- *
- * DESCRIPTION: if GetLastError() returns a common error generated by a
- * broken pipe, close the pipe handle. Call this right after a
- * pipe operation.
- *
- * RETURNS: FALSE if the pipe is broken, TRUE if not.
- *
- */
- BOOL pipeCheck(HANDLE hPipe)
- {
- DWORD dwLastError = GetLastError();
- if (dwLastError == ERROR_BROKEN_PIPE || dwLastError == ERROR_NO_DATA)
- {
- puts("n* pipe broken, closing...");
- CloseHandle(hPipe);
- return(FALSE);
- }
- if (dwLastError == ERROR_INVALID_HANDLE) /* is handle already closed? */
- return(FALSE);
- return(TRUE);
- } /* pipeCheck() */
- /*
- ** void reader(HANDLE hPipe)
- *
- * PARAMETERS: HANDLE hPipe: pipe handle to read from
- *
- * DESCRIPTION: read from the handle and dump data to the console.
- *
- * RETURNS: none
- *
- */
- void reader(HANDLE hPipe)
- {
- char buf[64];
- DWORD dwRead;
- BOOL bSuccess;
- OVERLAPPED ol;
- if (OVERLAPPED_IO) /* if overlapped, prepare OVERLAPPED structure */
- {
- memset(&ol, 0, sizeof(ol));
- ol.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
- PERR(ol.hEvent, "CreateEvent");
- }
- while (1)
- {
- bSuccess = ReadFile(hPipe, buf, sizeof(buf), &dwRead,
- OVERLAPPED_IO ? &ol : NULL);
- if (!bSuccess && GetLastError() == ERROR_IO_PENDING)
- bSuccess = GetOverlappedResult(hPipe, &ol, &dwRead, TRUE);
- /* If ReadFile or GetOverlappedResult fails, check pipe. If pipe is
- broken, fall out of loop */
- if (!bSuccess && !pipeCheck(hPipe))
- break;
- /* else check for any other kinds of errors that may have occurred */
- PERR(bSuccess, "ReadFile");
- printf("%.*s", dwRead, buf); /* print only number of chars read */
- } /* while */
- CloseHandle(ol.hEvent);
- _endthread();
- } /* reader() */
- /*
- ** void writer(WRITER_PARAMS *writer_params)
- *
- * PARAMETERS: WRITER_PARAMS *writer_params: misc info needed for writing to
- * the pipe
- *
- * DESCRIPTION: write data from WRITER_PARAMS to the pipe
- *
- * RETURNS: none
- *
- */
- void writer(WRITER_PARAMS *writer_params)
- {
- DWORD dwWritten;
- BOOL bSuccess;
- OVERLAPPED ol;
- if (OVERLAPPED_IO)
- {
- memset(&ol, 0, sizeof(ol));
- ol.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
- PERR(ol.hEvent, "CreateEvent");
- }
- while(1)
- {
- bSuccess = WriteFile(writer_params->hPipe, writer_params->szData,
- writer_params->iDataSize, &dwWritten, OVERLAPPED_IO ? &ol : NULL);
- if (!bSuccess && GetLastError() == ERROR_IO_PENDING)
- bSuccess = GetOverlappedResult(writer_params->hPipe, &ol, &dwWritten,
- TRUE);
- /* If ReadFile or GetOverlappedResult fails, check pipe. If pipe is
- broken, fall out of loop */
- if (!bSuccess && !pipeCheck(writer_params->hPipe))
- break;
- /* else check for any other kinds of errors that may have occurred */
- PERR(bSuccess, "WriteFile");
- } /* while */
- free(writer_params);
- CloseHandle(ol.hEvent);
- _endthread();
- } /* writer() */
- /*
- ** main()
- *
- * DESCRIPTION: Connect pipe instances to clients. Start a reader thread for
- * each client. If OVERLAPPED_IO is defined, also start a
- * writer thread for full duplex pipe I/O testing. If this is
- * a client, connect to the server pipe and start a writer
- * thread. If OVERLAPPED_IO, also start a reader thread.
- *
- */
- void main(int argc, char *argv[])
- {
- HANDLE hPipe;
- BOOL bSuccess;
- BOOL bNotConnected;
- char *szPname;
- WRITER_PARAMS *writer_params;
- DWORD dwClients;
- SECURITY_ATTRIBUTES saPipe;
- OVERLAPPED ol;
- DWORD dwRead;
- if (argc < 3)
- {
- puts("nmpipe [/s|/c] <string> <pipename>");
- puts("'/s' to start as server, '/c' to start as client");
- puts("<string>: string to write to the pipe");
- puts("<pipename>: full UNC name of pipe (optional)");
- puts("example: nmpipe /s "hello from server " \\.\pipe\pipetst");
- return;
- }
- szPname = (argc > 3) ? argv[3] : DEFNAME;
- if (tolower(argv[1][1]) == 's')
- {
- if (OVERLAPPED_IO)
- {
- memset(&ol, 0, sizeof(ol));
- ol.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
- PERR(ol.hEvent, "CreateEvent");
- }
- SetConsoleTitle("SERVER: nmpipe sample");
- /* set up a NULL DACL in our pipe security descriptor to allow anyone to
- connect to the pipe server */
- saPipe.lpSecurityDescriptor =
- (PSECURITY_DESCRIPTOR) malloc(SECURITY_DESCRIPTOR_MIN_LENGTH);
- InitializeSecurityDescriptor(saPipe.lpSecurityDescriptor,
- SECURITY_DESCRIPTOR_REVISION);
- SetSecurityDescriptorDacl(saPipe.lpSecurityDescriptor, TRUE, (PACL) NULL,
- FALSE);
- saPipe.nLength = sizeof(saPipe);
- saPipe.bInheritHandle = TRUE;
- while(1)
- {
- /* Create a named pipe: duplex, type byte, readmode byte, unlimited
- instances, default timeout of 60s */
- hPipe = CreateNamedPipe(szPname, PIPE_ACCESS_DUPLEX |
- (OVERLAPPED_IO ? FILE_FLAG_OVERLAPPED : 0), PIPE_TYPE_BYTE |
- PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 0, 0,
- 60000, &saPipe);
- PERR(hPipe != INVALID_HANDLE_VALUE, "CreateNamedPipe");
- puts("n* pipe created, waiting for connection...");
- bSuccess = ConnectNamedPipe(hPipe, OVERLAPPED_IO ? &ol : NULL);
- if (!bSuccess && GetLastError() == ERROR_IO_PENDING)
- bSuccess = GetOverlappedResult(hPipe, &ol, &dwRead, TRUE);
- /* check return from either ConnectNamedPipe or GetOverlappedResult.
- If a client managed to connect between the CreateNamedPipe and
- ConnectNamedPipe calls, ERROR_PIPE_CONNECTED will result */
- if (!bSuccess && GetLastError() != ERROR_PIPE_CONNECTED)
- {
- /* something went wrong, report error, close instance and try again */
- PERR(bSuccess, "ConnectNamedPipe");
- CloseHandle(hPipe);
- continue;
- }
- /* find out how many pipe instances there currently are */
- bSuccess = GetNamedPipeHandleState(hPipe, NULL, &dwClients, NULL, NULL,
- NULL, 0);
- PERR(bSuccess, "GetNamedPipeHandleState");
- printf("n* %d clients connected", dwClients);
- _beginthread(reader, 0, hPipe);
- writer_params = malloc(sizeof(WRITER_PARAMS));
- writer_params->hPipe = hPipe;
- writer_params->szData = argv[2];
- writer_params->iDataSize = strlen(argv[2]);
- /* WARNING! reading and writing at the same time to a non-overlapped
- pipe is a no-no! If not overlapped, server only reads and client
- only writes */
- if (OVERLAPPED_IO)
- _beginthread(writer, 0, writer_params);
- } /* while */
- CloseHandle(ol.hEvent);
- CloseHandle(hPipe);
- }
- else /* no '/s', assume it's a client */
- {
- char szTemp[64];
- sprintf(szTemp, "Client %s", argv[2]);
- SetConsoleTitle(szTemp);
- bNotConnected = TRUE;
- while (bNotConnected)
- {
- /* attempt to connect to pipe instance */
- hPipe = CreateFile(szPname, GENERIC_READ | GENERIC_WRITE, 0, NULL,
- OPEN_EXISTING, OVERLAPPED_IO ? FILE_FLAG_OVERLAPPED : 0, NULL);
- if (GetLastError() == ERROR_PIPE_BUSY)
- {
- puts("Pipe busy, waiting for a pipe instance...");
- bSuccess = WaitNamedPipe(szPname, NMPWAIT_USE_DEFAULT_WAIT);
- PERR(bSuccess, "WaitNamedPipe");
- }
- else
- {
- PERR(hPipe != INVALID_HANDLE_VALUE, "CreateFile");
- bNotConnected = (hPipe == INVALID_HANDLE_VALUE);
- }
- } /* while */
- puts("Connected to pipe...");
- if (OVERLAPPED_IO) /* if overlapped, start reader thread */
- _beginthread(reader, 0, hPipe);
- writer_params = malloc(sizeof(WRITER_PARAMS));
- writer_params->hPipe = hPipe;
- writer_params->szData = argv[2];
- writer_params->iDataSize = strlen(argv[2]);
- writer(writer_params);
- } /* else */
- free(saPipe.lpSecurityDescriptor);
- CloseHandle(hPipe);
- CloseHandle(ol.hEvent);
- return;
- }