使用重叠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);
}
相关文章推荐
- [使用重叠IO的命名管道服务器示例]Named Pipe Server Using Overlapped I/O
- windows下使用重叠IO(OVERLAPPE)命名管道服务端
- 配置远程客户机使用命名管道协议访问SQL服务器
- 重叠IO管道服务器,支持多客户端
- 配置远程客户机使用命名管道协议访问SQL服务器
- 使用完成例程的命名管道服务器
- 重叠IO--命名管道同时进行读写操作
- 配置远程客户机使用命名管道协议访问SQL服务器
- System.IO系列:局域网内多线程使用命名管道在进程之间通信实例
- System.IO系列:局域网内多线程使用命名管道在进程之间通信实例
- 【LINUX/UNIX网络编程】之使用消息队列,信号量和命名管道实现的多进程服务器(多人群聊系统)
- bash中一次性给多个变量赋值--命名管道的使用
- System.IO之使用管道在进程间通信 (System.IO.Pipes使用)
- 在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。未找到或无法访问服务器。请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接。 (provider: 命名管道提供程序, error: 40 - 无法打开到 SQL
- Linux进程间通信——使用命名管道
- linux使用管道,IO重定向
- 在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。未找到或无法访问服务器。请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接。 (provider: 命名管道提供程序, error: 40 - 无法打开到 SQL
- 在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。未找到或无法访问服务器。请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接。 (provider: 命名管道提供程序, error: 40 - 无法打开到 SQL
- Linux进程间通信——使用命名管道