使用完成例程的命名管道服务器
2013-01-09 20:26
204 查看
ms-help://MS.MSDNQTR.v90.chs/ipc/base/named_pipe_server_using_completion_routines.htm
#include<windows.h> #include<stdio.h> #include<tchar.h> #include<strsafe.h> #definePIPE_TIMEOUT5000 #defineBUFSIZE4096 typedefstruct { OVERLAPPEDoOverlap; HANDLEhPipeInst; TCHARchRequest[BUFSIZE]; DWORDcbRead; TCHARchReply[BUFSIZE]; DWORDcbToWrite; }PIPEINST,*LPPIPEINST; VOIDDisconnectAndClose(LPPIPEINST); BOOLCreateAndConnectInstance(LPOVERLAPPED); BOOLConnectToNewClient(HANDLE,LPOVERLAPPED); VOIDGetAnswerToRequest(LPPIPEINST); VOIDWINAPICompletedWriteRoutine(DWORD,DWORD,LPOVERLAPPED); VOIDWINAPICompletedReadRoutine(DWORD,DWORD,LPOVERLAPPED); HANDLEhPipe; int_tmain(VOID) { HANDLEhConnectEvent; OVERLAPPEDoConnect; LPPIPEINSTlpPipeInst; DWORDdwWait,cbRet; BOOLfSuccess,fPendingIO; //Createoneeventobjectfortheconnectoperation. hConnectEvent=CreateEvent( NULL,//defaultsecurityattribute TRUE,//manualresetevent TRUE,//initialstate=signaled NULL);//unnamedeventobject if(hConnectEvent==NULL) { printf("CreateEventfailedwith%d.\n",GetLastError()); return0; } oConnect.hEvent=hConnectEvent; //Callasubroutinetocreateoneinstance,andwaitfor //theclienttoconnect. fPendingIO=CreateAndConnectInstance(&oConnect); while(1) { //Waitforaclienttoconnect,orforareadorwrite //operationtobecompleted,whichcausesacompletion //routinetobequeuedforexecution. dwWait=WaitForSingleObjectEx( hConnectEvent,//eventobjecttowaitfor INFINITE,//waitsindefinitely TRUE);//alertablewaitenabled switch(dwWait) { //Thewaitconditionsaresatisfiedbyacompletedconnect //operation. case0: //Ifanoperationispending,gettheresultofthe //connectoperation. if(fPendingIO) { fSuccess=GetOverlappedResult( hPipe,//pipehandle &oConnect,//OVERLAPPEDstructure &cbRet,//bytestransferred FALSE);//doesnotwait if(!fSuccess) { printf("ConnectNamedPipe(%d)\n",GetLastError()); return0; } } //Allocatestorageforthisinstance. lpPipeInst=(LPPIPEINST)GlobalAlloc(GPTR,sizeof(PIPEINST)); if(lpPipeInst==NULL) { printf("GlobalAllocfailed(%d)\n",GetLastError()); return0; } lpPipeInst->hPipeInst=hPipe; //Startthereadoperationforthisclient. //Notethatthissameroutineislaterusedasa //completionroutineafterawriteoperation. lpPipeInst->cbToWrite=0; CompletedWriteRoutine(0,0,(LPOVERLAPPED)lpPipeInst); //Createnewpipeinstanceforthenextclient. fPendingIO=CreateAndConnectInstance(&oConnect); break; //Thewaitissatisfiedbyacompletedreadorwrite //operation.Thisallowsthesystemtoexecutethe //completionroutine. caseWAIT_IO_COMPLETION: break; //Anerroroccurredinthewaitfunction. default: { printf("WaitForSingleObjectEx(%d)\n",GetLastError()); return0; } } } return0; }
//CompletedWriteRoutine(DWORD,DWORD,LPOVERLAPPED)
//Thisroutineiscalledasacompletionroutineafterwritingto
//thepipe,orwhenanewclienthasconnectedtoapipeinstance.
//Itstartsanotherreadoperation.
VOIDWINAPICompletedWriteRoutine(DWORDdwErr,DWORDcbWritten,
LPOVERLAPPEDlpOverLap)
{
LPPIPEINSTlpPipeInst;
BOOLfRead=FALSE;
//lpOverlappointstostorageforthisinstance.
lpPipeInst=(LPPIPEINST)lpOverLap;
//Thewriteoperationhasfinished,soreadthenextrequest(if
//thereisnoerror).
if((dwErr==0)&&(cbWritten==lpPipeInst->cbToWrite))
fRead=ReadFileEx(lpPipeInst->hPipeInst,
lpPipeInst->chRequest,
BUFSIZE*sizeof(TCHAR),
(LPOVERLAPPED)lpPipeInst,
(LPOVERLAPPED_COMPLETION_ROUTINE)CompletedReadRoutine);
//Disconnectifanerroroccurred.
if(!fRead)
DisconnectAndClose(lpPipeInst);
}
//CompletedReadRoutine(DWORD,DWORD,LPOVERLAPPED)
//ThisroutineiscalledasanI/Ocompletionroutineafterreading
//arequestfromtheclient.Itgetsdataandwritesittothepipe.
VOIDWINAPICompletedReadRoutine(DWORDdwErr,DWORDcbBytesRead,
LPOVERLAPPEDlpOverLap)
{
LPPIPEINSTlpPipeInst;
BOOLfWrite=FALSE;
//lpOverlappointstostorageforthisinstance.
lpPipeInst=(LPPIPEINST)lpOverLap;
//Thereadoperationhasfinished,sowritearesponse(ifno
//erroroccurred).
if((dwErr==0)&&(cbBytesRead!=0))
{
GetAnswerToRequest(lpPipeInst);
fWrite=WriteFileEx(lpPipeInst->hPipeInst,
lpPipeInst->chReply,
lpPipeInst->cbToWrite,
(LPOVERLAPPED)lpPipeInst,
(LPOVERLAPPED_COMPLETION_ROUTINE)CompletedWriteRoutine);
}
//Disconnectifanerroroccurred.
if(!fWrite)
DisconnectAndClose(lpPipeInst);
}
//DisconnectAndClose(LPPIPEINST)
//Thisroutineiscalledwhenanerroroccursortheclientcloses
//itshandletothepipe.
VOIDDisconnectAndClose(LPPIPEINSTlpPipeInst)
{
//Disconnectthepipeinstance.
if(!DisconnectNamedPipe(lpPipeInst->hPipeInst))
{
printf("DisconnectNamedPipefailedwith%d.\n",GetLastError());
}
//Closethehandletothepipeinstance.
CloseHandle(lpPipeInst->hPipeInst);
//Releasethestorageforthepipeinstance.
if(lpPipeInst!=NULL)
GlobalFree(lpPipeInst);
}
//CreateAndConnectInstance(LPOVERLAPPED)
//Thisfunctioncreatesapipeinstanceandconnectstotheclient.
//ItreturnsTRUEiftheconnectoperationispending,andFALSEif
//theconnectionhasbeencompleted.
BOOLCreateAndConnectInstance(LPOVERLAPPEDlpoOverlap)
{
LPTSTRlpszPipename=TEXT("\\\\.\\pipe\\mynamedpipe");
hPipe=CreateNamedPipe(
lpszPipename,//pipename
PIPE_ACCESS_DUPLEX|//read/writeaccess
FILE_FLAG_OVERLAPPED,//overlappedmode
PIPE_TYPE_MESSAGE|//message-typepipe
PIPE_READMODE_MESSAGE|//messagereadmode
PIPE_WAIT,//blockingmode
PIPE_UNLIMITED_INSTANCES,//unlimitedinstances
BUFSIZE*sizeof(TCHAR),//outputbuffersize
BUFSIZE*sizeof(TCHAR),//inputbuffersize
PIPE_TIMEOUT,//clienttime-out
NULL);//defaultsecurityattributes
if(hPipe==INVALID_HANDLE_VALUE)
{
printf("CreateNamedPipefailedwith%d.\n",GetLastError());
return0;
}
//Callasubroutinetoconnecttothenewclient.
returnConnectToNewClient(hPipe,lpoOverlap);
}
BOOLConnectToNewClient(HANDLEhPipe,LPOVERLAPPEDlpo)
{
BOOLfConnected,fPendingIO=FALSE;
//Startanoverlappedconnectionforthispipeinstance.
fConnected=ConnectNamedPipe(hPipe,lpo);
//OverlappedConnectNamedPipeshouldreturnzero.
if(fConnected)
{
printf("ConnectNamedPipefailedwith%d.\n",GetLastError());
return0;
}
switch(GetLastError())
{
//Theoverlappedconnectioninprogress.
caseERROR_IO_PENDING:
fPendingIO=TRUE;
break;
//Clientisalreadyconnected,sosignalanevent.
caseERROR_PIPE_CONNECTED:
if(SetEvent(lpo->hEvent))
break;
//Ifanerroroccursduringtheconnectoperation...
default:
{
printf("ConnectNamedPipefailedwith%d.\n",GetLastError());
return0;
}
}
returnfPendingIO;
}
VOIDGetAnswerToRequest(LPPIPEINSTpipe)
{
_tprintf(TEXT("[%d]%s\n"),pipe->hPipeInst,pipe->chRequest);
StringCchCopy(pipe->chReply,BUFSIZE,TEXT("Defaultanswerfromserver"));
pipe->cbToWrite=(lstrlen(pipe->chReply)+1)*sizeof(TCHAR);
}
相关文章推荐
- 在.NET中使用命名管道完成进程间通信(转自网络)
- 【LINUX/UNIX网络编程】之使用消息队列,信号量和命名管道实现的多进程服务器(多人群聊系统)
- (转)在.NET中使用命名管道完成进程间通信
- (转)在.NET中使用命名管道完成进程间通信
- 配置远程客户机使用命名管道协议访问SQL服务器
- 配置远程客户机使用命名管道协议访问SQL服务器
- 使用重叠IO的命名管道服务器
- [使用重叠IO的命名管道服务器示例]Named Pipe Server Using Overlapped I/O
- 在.NET中使用命名管道完成进程间通信[转]
- 在.NET中使用命名管道完成进程间通信[转]
- 配置远程客户机使用命名管道协议访问SQL服务器
- [ZZ]在.NET中使用命名管道完成进程间通信
- 在.NET中使用命名管道完成进程间通信
- 在.NET中使用命名管道完成进程间通信
- 在.NET中使用命名管道完成进程间通信
- Linux进程间通信——使用命名管道
- 使用命名管道通过网络在进程之间进行通信(C#)
- 使用命名管道在winform程序中输出windows service运行状态
- Linux进程间通信——使用命名管道
- 使用数据集时错误:超时时间已到。在操作完成之前超时时间已过或服务器未响应。