您的位置:首页 > 其它

使用重叠IO的命名管道服务器

2013-01-08 21:16 387 查看
ms-help://MS.MSDNQTR.v90.chs/ipc/base/named_pipe_server_using_overlapped_i_o.htm


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

#defineCONNECTING_STATE0
#defineREADING_STATE1
#defineWRITING_STATE2
#defineINSTANCES4
#definePIPE_TIMEOUT5000
#defineBUFSIZE4096



typedefstruct
{
OVERLAPPEDoOverlap;
HANDLEhPipeInst;
TCHARchRequest[BUFSIZE];
DWORDcbRead;
TCHARchReply[BUFSIZE];
DWORDcbToWrite;
DWORDdwState;
BOOLfPendingIO;
}PIPEINST,*LPPIPEINST;




VOIDDisconnectAndReconnect(DWORD);
BOOLConnectToNewClient(HANDLE,LPOVERLAPPED);
VOIDGetAnswerToRequest(LPPIPEINST);

PIPEINSTPipe[INSTANCES];
HANDLEhEvents[INSTANCES];




int_tmain(VOID)
{
DWORDi,dwWait,cbRet,dwErr;
BOOLfSuccess;
LPTSTRlpszPipename=TEXT("\\\\.\\pipe\\mynamedpipe");

//Theinitialloopcreatesseveralinstancesofanamedpipe
//alongwithaneventobjectforeachinstance.An
//overlappedConnectNamedPipeoperationisstartedfor
//eachinstance.

for(i=0;i<INSTANCES;i++)
{

//Createaneventobjectforthisinstance.

hEvents[i]=CreateEvent(NULL,//defaultsecurityattribute
TRUE,//manual-resetevent
TRUE,//initialstate=signaled
NULL);//unnamedeventobject

if(hEvents[i]==NULL)
{
printf("CreateEventfailedwith%d.\n",GetLastError());
return0;
}

Pipe[i].oOverlap.hEvent=hEvents[i];

Pipe[i].hPipeInst=CreateNamedPipe(

				lpszPipename,		//pipename
PIPE_ACCESS_DUPLEX|//read/writeaccess
FILE_FLAG_OVERLAPPED,//overlappedmode
PIPE_TYPE_MESSAGE|//message-typepipe
PIPE_READMODE_MESSAGE|//message-readmode
PIPE_WAIT,//blockingmode
INSTANCES,//numberofinstances
BUFSIZE*sizeof(TCHAR),//outputbuffersize
BUFSIZE*sizeof(TCHAR),//inputbuffersize
PIPE_TIMEOUT,//clienttime-out
NULL);//defaultsecurityattributes

if(Pipe[i].hPipeInst==INVALID_HANDLE_VALUE)
{
printf("CreateNamedPipefailedwith%d.\n",GetLastError());
return0;
}

//Callthesubroutinetoconnecttothenewclient

Pipe[i].fPendingIO=ConnectToNewClient(Pipe[i].hPipeInst,
&Pipe[i].oOverlap);

Pipe[i].dwState=Pipe[i].fPendingIO?
CONNECTING_STATE://stillconnecting
READING_STATE;//readytoread
}



while(1)
{
//Waitfortheeventobjecttobesignaled,indicating
//completionofanoverlappedread,write,or
//connectoperation.

dwWait=WaitForMultipleObjects(INSTANCES,//numberofeventobjects
hEvents,//arrayofeventobjects
FALSE,//doesnotwaitforall
INFINITE);//waitsindefinitely


//dwWaitshowswhichpipecompletedtheoperation.

i=dwWait-WAIT_OBJECT_0;//determineswhichpipe
if(i<0||i>(INSTANCES-1))
{
printf("Indexoutofrange.\n");
return0;
}


//Gettheresultiftheoperationwaspending.

if(Pipe[i].fPendingIO)
{
fSuccess=GetOverlappedResult(Pipe[i].hPipeInst,//handletopipe
&Pipe[i].oOverlap,//OVERLAPPEDstructure
&cbRet,//bytestransferred
FALSE);//donotwait

switch(Pipe[i].dwState)
{
//Pendingconnectoperation
caseCONNECTING_STATE:
if(!fSuccess)
{
printf("Error%d.\n",GetLastError());
return0;
}
Pipe[i].dwState=READING_STATE;
break;

//Pendingreadoperation
caseREADING_STATE:
if(!fSuccess||cbRet==0)
{
DisconnectAndReconnect(i);
continue;
}
Pipe[i].dwState=WRITING_STATE;
break;

//Pendingwriteoperation
caseWRITING_STATE:
if(!fSuccess||cbRet!=Pipe[i].cbToWrite)
{
DisconnectAndReconnect(i);
continue;
}
Pipe[i].dwState=READING_STATE;
break;

default:
{
printf("Invalidpipestate.\n");
return0;
}
}
}


//Thepipestatedetermineswhichoperationtodonext.

switch(Pipe[i].dwState)
{
//READING_STATE:
//Thepipeinstanceisconnectedtotheclient
//andisreadytoreadarequestfromtheclient.

caseREADING_STATE:
fSuccess=ReadFile(Pipe[i].hPipeInst,
Pipe[i].chRequest,
BUFSIZE*sizeof(TCHAR),
&Pipe[i].cbRead,
&Pipe[i].oOverlap);

//Thereadoperationcompletedsuccessfully.

if(fSuccess&&Pipe[i].cbRead!=0)
{
Pipe[i].fPendingIO=FALSE;
Pipe[i].dwState=WRITING_STATE;
continue;
}

//Thereadoperationisstillpending.

dwErr=GetLastError();
if(!fSuccess&&(dwErr==ERROR_IO_PENDING))
{
Pipe[i].fPendingIO=TRUE;
continue;
}

//Anerroroccurred;disconnectfromtheclient.

DisconnectAndReconnect(i);
break;

//WRITING_STATE:
//Therequestwassuccessfullyreadfromtheclient.
//Getthereplydataandwriteittotheclient.

caseWRITING_STATE:
GetAnswerToRequest(&Pipe[i]);

fSuccess=WriteFile(Pipe[i].hPipeInst,
Pipe[i].chReply,
Pipe[i].cbToWrite,
&cbRet,
&Pipe[i].oOverlap);

//Thewriteoperationcompletedsuccessfully.

if(fSuccess&&cbRet==Pipe[i].cbToWrite)
{
Pipe[i].fPendingIO=FALSE;
Pipe[i].dwState=READING_STATE;
continue;
}

//Thewriteoperationisstillpending.

dwErr=GetLastError();
if(!fSuccess&&(dwErr==ERROR_IO_PENDING))
{
Pipe[i].fPendingIO=TRUE;
continue;
}

//Anerroroccurred;disconnectfromtheclient.

DisconnectAndReconnect(i);
break;

default:
{
printf("Invalidpipestate.\n");
return0;
}
}
}

return0;
}




//DisconnectAndReconnect(DWORD)
//Thisfunctioniscalledwhenanerroroccursorwhentheclient
//closesitshandletothepipe.Disconnectfromthisclient,then
//callConnectNamedPipetowaitforanotherclienttoconnect.

VOIDDisconnectAndReconnect(DWORDi)
{
//Disconnectthepipeinstance.

if(!DisconnectNamedPipe(Pipe[i].hPipeInst))
{
printf("DisconnectNamedPipefailedwith%d.\n",GetLastError());
}

//Callasubroutinetoconnecttothenewclient.

Pipe[i].fPendingIO=ConnectToNewClient(Pipe[i].hPipeInst,
&Pipe[i].oOverlap);

Pipe[i].dwState=Pipe[i].fPendingIO?
CONNECTING_STATE://stillconnecting
READING_STATE;//readytoread
}



//ConnectToNewClient(HANDLE,LPOVERLAPPED)
//Thisfunctioniscalledtostartanoverlappedconnectoperation.
//ItreturnsTRUEifanoperationispendingorFALSEifthe
//connectionhasbeencompleted.

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