I have problem about WSARecv() in IOCP , the second parameter of WSABUF, if my buffer length is less than the actual message size how can get the rest of the data ? just make another call to WSARecv() ? Thanks.
Printable View
I have problem about WSARecv() in IOCP , the second parameter of WSABUF, if my buffer length is less than the actual message size how can get the rest of the data ? just make another call to WSARecv() ? Thanks.
Yes, simply call it again.
Thanks for the prompt reply, but when I called it again I get the dwBytesTransfered which is the second parameter of GetQueuedCompletionStatus as 0 . Also, after I called WSARecv() I never get the error WSAEMSGSIZE which tell message was too large to fit into the specified buffer. Is this message for UDP socket only ? because I am using TCP stream socket. How can I detect my specified buffer was not enough to receive the message ?
yes WSAEMSGSIZE is used for datagram socket. Check the return value of GetQueuedCompketionStatus It might helps you.
Quote:
Originally Posted by MSDN
I have already check the return value of GetQueuedCompketionStatus, even if my WSABUF length used is less than the actual message when I called WSARecv(), the return value of GetQueuedCompketionStatus is NON-ZERO. This is my workerThread for IOCP, in case you want to view it. Thanks .
Code:DWORD WINAPI workerThread(LPVOID lParam)
{
DWORD dwBytesTransfered = 0, recvByte = 0, flags = 0, sentByte = 0;
void *lpContext = NULL;
OVERLAPPED *pOverlapped = NULL;
LPPER_HANDLE_DATA lpHandleData = NULL;
int nResult;
WSABUF wsaBuf;
char buffer[MAX_BUFFER_LEN];
wsaBuf.len = MAX_BUFFER_LEN;
wsaBuf.buf = buffer;
while(1)
{
//printf("DEBUG %d\n", GetLastError());
nResult = GetQueuedCompletionStatus(g_hCompletionPort, &dwBytesTransfered,(LPDWORD)&lpContext, &pOverlapped, INFINITE);
lpHandleData = (LPPER_HANDLE_DATA) lpContext;
if(nResult == FALSE || ((nResult == TRUE) && (dwBytesTransfered == 0)))
{
printf("GetQueuedCompletionStatus ERROR : %d\n", GetLastError());
if(GetLastError() != 0) // application has completed successfully
continue;
}
printf("Bytes transfered/received : %d\n", dwBytesTransfered);
switch(lpHandleData->opCode)
{
case OP_READ:
memset(buffer, 0, MAX_BUFFER_LEN);
wsaBuf.buf = buffer;
wsaBuf.len = MAX_BUFFER_LEN;
if(WSARecv(lpHandleData->serverSocket, &wsaBuf, 1, &recvByte, &flags, &lpHandleData->ol, NULL) == SOCKET_ERROR)
if(WSAGetLastError() == WSA_IO_PENDING)
printf("WSARecv WSA_IO_PENDING\n");
else
printf("WSARecv ERROR : %d\n", WSAGetLastError());
lpHandleData->opCode = OP_WRITE;
break;
case OP_WRITE:
printf("flags : %d\n", flags);
printf("Data received : \n%s\n", wsaBuf.buf);
break;
case OP_CONNECT: // just connected to the server
printf("Connected\n");
//printf("DEBUG %d\n", GetLastError());
//memset(&wsaBuf, 0, sizeof(wsaBuf));
memset(buffer, 0, sizeof(buffer));
memset(&lpHandleData->ol, 0, sizeof(lpHandleData->ol));
//\r\nConnection: close
sprintf(buffer, "GET / HTTP/1.1\r\nConnection: close\r\nHost: %s\r\n\r\n", lpHandleData->host);
wsaBuf.buf = buffer;
wsaBuf.len = strlen(buffer);
lpHandleData->opCode = OP_READ;
if(WSASend(lpHandleData->serverSocket, &wsaBuf, 1, &sentByte, flags, &lpHandleData->ol, FALSE) == SOCKET_ERROR)
{
if(WSAGetLastError() == WSA_IO_PENDING)
printf("WSASend WSA_IO_PENDING\n");
else printf("WSASend ERROR : %d\n", WSAGetLastError());
}
else printf("WSASend complete immediately.\n");
break;
}
}
return 0;
}
A zero for dwBytesTransferred means that the connection was closed by the peer. You should call closesocket() and cloe the socket.Quote:
Originally Posted by keenlearner
As Nauman has indicated, this error is for UDP only. You will not see it for TCP.Quote:
Also, after I called WSARecv() I never get the error WSAEMSGSIZE which tell message was too large to fit into the specified buffer. Is this message for UDP socket only ?
There's no need to "detect" anything. If you are expecting more data, simply call WSARecv() again.Quote:
because I am using TCP stream socket. How can I detect my specified buffer was not enough to receive the message ?
Make certain that you are expecting more data, however. You should be using some kind of protocol, that you impose at the application level, to tell the recipient how much data he should expect to receive.
Mike
I just noticed that your worker thread uses the same "buffer" for both sends and recvs. That's an incorrect architecture for IOCP. You need to use a separate, unique buffer for each send and recv, commonly referred-to as a "per I/O buffer", and normally defined inside of a per-I/O structure. A pointer to this structure is returned to you in the lpOverlapped parameter of GetQueuedCompletionStatus.
Mike
Now the WSARecv() return the subsequent data after the subsequent call, and you are right I should have WSABUF in the PER_IO_DATA sructure. Thanks so much.
Hi! I found this thread because i have a similar probem. I need change traffic on fly and i dicide use lsp to achive that! So as example i use microsoft example ftp://ftp.microsoft.com/bussys/Winso...k2/layered.zip
But i have a problem with reallocating lpBuffers variable in WSPRecv function to add in some data.
How i can do that and can you give me your implementation of y code which posted in this thread?