[Windows] 基于 Overlapped 的命名管道 Server 端示例

本文详细描述了一个使用Winsock2开发的高级命名管道服务器,它能同时处理5个管道实例,通过主应用线程使用Win32异步I/O进行数据接收和回显。服务器采用多路复用技术监控每个管道的I/O活动。
摘要由CSDN通过智能技术生成

ref: https://www.winsocketdotnetworkprogramming.com/winsock2programming/winsock2advancednamedpipe15c.html
原文排版比较乱, 整理一下放在这里以供大家参考:)

// Purpose:
//     This sample demonstrates how to develop an advanced named
//     pipe server that is capable of servicing 5 named pipe
//     instances. The application is an echo server where data is
//     received from a client and echoed back to the client. All
//     the pipe instances are serviced in the main application
//     thread using Win32 overlapped I/O.
//

#include <windows.h>
#include <stdio.h>

#define NUM_PIPES 5
#define BUFFER_SIZE 256

void main(void) {
	HANDLE PipeHandles[NUM_PIPES];
    DWORD BytesTransferred;
    CHAR Buffer[NUM_PIPES][BUFFER_SIZE];
    INT i;
    OVERLAPPED Ovlap[NUM_PIPES];
    HANDLE Event[NUM_PIPES];
    
    // For each pipe handle instance, the code must maintain the
    // pipes' current state, which determines if a ReadFile or
    // WriteFile is posted on the named pipe. This is done using
    // the DataRead variable array. By knowing each pipe's
    // current state, the code can determine what the next I/O operation should be.

    BOOL DataRead[NUM_PIPES];
    DWORD Ret;
    DWORD Pipe;

	for(i = 0; i < NUM_PIPES; i++) {
		// Create a named pipe instance
        if ((PipeHandles[i] = CreateNamedPipe(L"\\\\.\\Pipe\\jim",
		  		PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
            	PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, NUM_PIPES,
            	0, 0, 1000, NULL)) == INVALID_HANDLE_VALUE) {
			printf("CreateNamedPipe() for pipe %d failed with error %d\n", i, GetLastError());
			return;
		} else {
		  	printf("CreateNamedPipe() for pipe %d is OK!\n", i);
		}
		
        // Create an event handle for each pipe instance. This
        // will be used to monitor overlapped I/O activity on each pipe
        if ((Event[i] = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL) {
			printf("CreateEvent() for pipe %d failed with error %d\n",  i, GetLastError());
			continue;
		} else {
			printf("CreateEvent() for pipe %d is OK!\n", i);
		}
		
		// Maintain a state flag for each pipe to determine when data is to be read from or written to the pipe
		DataRead[i] = FALSE;
        ZeroMemory(&Ovlap[i], sizeof(OVERLAPPED));
        Ovlap[i].hEvent = Event[i];
        
        // Listen for client connections using ConnectNamedPipe()
        if (ConnectNamedPipe(PipeHandles[i], &Ovlap[i]) == 0) {
        	if (GetLastError() != ERROR_IO_PENDING) {
            	printf("ConnectNamedPipe() for pipe %d failed with error %d\n", i, GetLastError());
                printf("Closing handle...\n");
                CloseHandle(PipeHandles[i]);
                return;
             }
        } else {
        	printf("ConnectNamedPipe() for pipe %d is OK!\n", i);
		}
    }
    
	printf("Server is now running....\n");
    
    // Read and echo data back to Named Pipe clients forever
    while(1) {
    	if ((Ret = WaitForMultipleObjects(NUM_PIPES, Event, FALSE, INFINITE)) == WAIT_FAILED) {
			printf("WaitForMultipleObjects() failed with error %d\n", GetLastError());
            return;
        } else {
			printf("WaitForMultipleObjects() is OK!\n");
		} 
		               
        Pipe = Ret - WAIT_OBJECT_0;
        ResetEvent(Event[Pipe]);
        
        // Check overlapped results, and if they fail, reestablish
        // communication for a new client; otherwise, process read and write operations with the client
       	if (GetOverlappedResult(PipeHandles[Pipe], &Ovlap[Pipe], &BytesTransferred, TRUE) == 0) {
			printf("GetOverlapped() result failed %d start over...\n", GetLastError());
            if (DisconnectNamedPipe(PipeHandles[Pipe]) == 0) {
            	printf("DisconnectNamedPipe() failed with error %d\n", GetLastError());
                return;
            } else {
				printf("DisconnectNamedPipe() is OK!\n");
			}
			
            if (ConnectNamedPipe(PipeHandles[Pipe],  &Ovlap[Pipe]) == 0) {
            	if (GetLastError() != ERROR_IO_PENDING) {
                	// Severe error on pipe. Close this handle forever
                   	printf("ConnectNamedPipe() for pipe %d failed with error %d\n", i, GetLastError());
                   	printf("Closing handle...\n");
                   	CloseHandle(PipeHandles[Pipe]);
                } else {
					printf("ConnectNamedPipe() for pipe %d is OK!\n", i);
				}
            }
            DataRead[Pipe] = FALSE;
        } else {
        	// Check the state of the pipe. If DataRead equals
            // FALSE, post a read on the pipe for incoming data.
            // If DataRead equals TRUE, then prepare to echo data back to the client.
            if (DataRead[Pipe] == FALSE) {
            	// Prepare to read data from a client by posting a ReadFile operation
                ZeroMemory(&Ovlap[Pipe], sizeof(OVERLAPPED));
                Ovlap[Pipe].hEvent = Event[Pipe];
                if (ReadFile(PipeHandles[Pipe], Buffer[Pipe],  BUFFER_SIZE, NULL, &Ovlap[Pipe]) == 0) {
                	if (GetLastError() != ERROR_IO_PENDING) {
              			printf("ReadFile() failed with error %d\n",  GetLastError());
              		}
                } else {
					printf("ReadFile() should be fine!\n");
				}
				DataRead[Pipe] = TRUE;
            } else  {
            	// Write received data back to the client by posting a WriteFile operation.
                printf("Received %d bytes, echo bytes back\n",   BytesTransferred);
                ZeroMemory(&Ovlap[Pipe], sizeof(OVERLAPPED));
                Ovlap[Pipe].hEvent = Event[Pipe];
                if (WriteFile(PipeHandles[Pipe], Buffer[Pipe],  BytesTransferred, NULL, &Ovlap[Pipe]) == 0) {
                	if (GetLastError() != ERROR_IO_PENDING) { 
                 		printf("WriteFile() failed with error %d\n", GetLastError());
                    }
                } else {
					printf("WriteFile() should be OK!\n");
				}
                DataRead[Pipe] = FALSE;
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值