Reputation: 325
I want to implement a server/client using named pipes (for IPC).I'm using async (overlapped) connections and I/O completion port (I searched a lot and it seems that it is the most efficient way to do that).
First here are the codes:
server: http://pastebin.com/XxeXdunC
and client: http://pastebin.com/fbCH2By8
The problem is in the server (i can improve the client but i will do that when the server works).
I use I/O completion port like that : basically, I run a thread in which I call ReadFile(). If it returns TRUE, I get all the data, if it returns FALSE, and the error is ERROR_IO_PENDING, I wait with GetQueuedCompletionStatus().
What is strange is that, even if I read all the data, the last ReadFile() call fails and the error is ERROR_IO_PENDING
The thread in which I call ReadFile() is beginning line 64 of the server code.
The client sends 24 bytes (the string "salut, c'est le client !") and the ReadFile() buffer is of length 5 bytes (to check how my server deals data that is larger than the Readfile() buffer)
The output is:
waiting for client...
WaitForMultipleObjects : 0
client connected (1)
ReadFile 1 msg (5 -> 05) : salut
ReadFile 2 msg (5 -> 10) : salut, c'e
ReadFile 2 msg (5 -> 15) : salut, c'est le
ReadFile 2 msg (5 -> 20) : salut, c'est le clie
ReadFile 2 msg (4 -> 24) : salut, c'est le client !
ReadFile2: ERROR_IO_PENDING
GQCIOS 0 255 003D3A18
ReadFile3: ERROR_IO_PENDING
ReadFile1: ERROR_IO_PENDING
GQCIOS 5 255 003D3A2C
ReadFile3: ERROR_IO_PENDING
ReadFile1: ERROR_IO_PENDING
GQCIOS 5 255 003D3A2C
ReadFile3: ERROR_IO_PENDING
ReadFile1: ERROR_IO_PENDING
GQCIOS 5 255 003D3A2C
ReadFile3: ERROR_IO_PENDING
ReadFile1: ERROR_IO_PENDING
GQCIOS 5 255 003D3A2C
ReadFile3: ERROR_IO_PENDING
ReadFile1: ERROR_IO_PENDING
GQCIOS 4 255 003D3A2C
ReadFile3: ERROR_IO_PENDING
ReadFile1: ERROR_IO_PENDING
What I do not understand is that even if I read all the data, ReadFile() still returns a pending operation (it's the "ReadFile2: ERROR_IO_PENDING" error message after the last "msg" output)
Is my loop wrong ? Do I misuse ReadFile() / GetQueuedCompletionStatus() ?
thank you
Upvotes: 1
Views: 1162
Reputation: 8815
Where is your write related function? it seems that your code is in wrong order. In the _read_data_cb
routine, GetQueuedCompletionStatus
should be called first, then depending on the lpOverlapped
parameter, the received data should be ready in the buffer that you specified in the ReadFile function. Since you're calling Readfile without checking whether OVERLAPPED
is a overlapped structure for the send context or recv context, you're not getting the expected output. The following code should clear things up:
while(TRUE)
{
bReturnValue=GetQueuedCompletionStatus(pIOCPServer->m_pIOCP, &dwBytesTransferred,(DWORD *)pClient,reinterpret_cast<LPOVERLAPPED*>(&pOverlapped),INFINITE);
if(!bReturnValue)
{
if(NULL==pOverlapped)
continue;
else
break;
}
else
{
if(pOverlapped==NULL)
continue;
}
if(dwBytesTransferred==0)
break;
if(lpOverlapped==&(pClient->m_pRecvContext->overlapped))
pClient->handleRecvEvent(dwBytesTransferred)
else if(lpOverlapped==&(pClient->m_pSendContext->overlapped))
pClient->handleSendEvent(dwBytesTransferred)
}
...
Upvotes: 1