您的位置:首页 > 其它

使用完成例程的命名管道服务器

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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: