|
|
|
date: 27 Dec 2005 15:57:56 -0800,
group: microsoft.public.platformsdk.networking
back
WSARecv
Hello:
I have a multi-threaded server app that receives requests does some
transforms and then sends the requests along to a 2nd server. The 2nd
server responds and this info is sent to the client.
Communication with the 2nd server is done via non blocking sockets
using wsasend and wsarecv.
I'm using an internal protocol that has as its first 4 bytes the length
of the entire packet.
My WSARecv loop from the 2nd server works most of the time but
sometimes it seems to recv bytes even though the 2nd server hasn't sent
any (I confirmed this with a sniffer).
I call the return below in a loop...first I call it looking for 4 bytes
to get the size of the packet and then I call it looking for the
remainder of the packet.
Since I'm running in a windows service, I'm also waiting on an event
that gets set when the service is shutdown.
I've been banging my head on this for awhile...
anyone know why WSARecv would receive bytes when there should be
nothing to receive?
I did verify that WSALastError is set to WSA_IO_PENDING...
Thanks
DWORD receive_async_data(SOCKET sock, char* buffer, int32 len)
{
WSABUF buf;
DWORD received=0;
DWORD flags=0;
WSAOVERLAPPED ovl;
int r = ES_OK;
HANDLE qevents[2]; // overlapped results and quit events
BOOL br=FALSE;
buf.buf = buffer;
buf.len = len;
ZeroMemory(&ovl,sizeof(WSAOVERLAPPED));
ovl.hEvent = WSACreateEvent();
qevents[0] = get_quit_event_handle();
qevents[1] = ovl.hEvent;
// Sleep(30000);
r = WSARecv(sock,&buf,1,&received,&flags,&ovl,NULL);
while (r != ES_OK)
{
r = WaitForMultipleObjects( 2, qevents, FALSE, INFINITE );
if ( r - WAIT_OBJECT_0 == 0 ) // quit request
{
goto EXIT;
}
else if ( r - WAIT_OBJECT_0 != 1 ) //some error condidtion
{
r = WSAGetLastError();
gESLog.lock(); gESLog << dmp_log::tmstr() << " ERROR: waiting for
queue, WSA err.: " << (size_t)r << ENDL; gESLog.unlock();
gESLog.flush_stream();
goto EXIT;
}
else
break; // we have rec'd data
}
//overlapped results should be ready
received = 0;
r = ES_OK;
WSAResetEvent(ovl.hEvent);
br = WSAGetOverlappedResult( sock, &ovl, &received, FALSE, &flags);
if (!br)
r = WSAGetLastError();
EXIT:
CloseHandle(ovl.hEvent);
return r;
}
date: 27 Dec 2005 15:57:56 -0800
author: unknown
Re: WSARecv
Check that you haven't some additional s/w in the stack ( LSP ... ) and
compare the times sniffer show for packets and WSAERecv() ( put time just
after it , that sounds very )
Arkady
wrote in message
news:1135727876.495596.50200@g47g2000cwa.googlegroups.com...
> Hello:
>
> I have a multi-threaded server app that receives requests does some
> transforms and then sends the requests along to a 2nd server. The 2nd
> server responds and this info is sent to the client.
>
> Communication with the 2nd server is done via non blocking sockets
> using wsasend and wsarecv.
>
> I'm using an internal protocol that has as its first 4 bytes the length
> of the entire packet.
>
> My WSARecv loop from the 2nd server works most of the time but
> sometimes it seems to recv bytes even though the 2nd server hasn't sent
> any (I confirmed this with a sniffer).
>
> I call the return below in a loop...first I call it looking for 4 bytes
> to get the size of the packet and then I call it looking for the
> remainder of the packet.
>
> Since I'm running in a windows service, I'm also waiting on an event
> that gets set when the service is shutdown.
>
> I've been banging my head on this for awhile...
>
> anyone know why WSARecv would receive bytes when there should be
> nothing to receive?
>
> I did verify that WSALastError is set to WSA_IO_PENDING...
>
> Thanks
>
>
> DWORD receive_async_data(SOCKET sock, char* buffer, int32 len)
> {
> WSABUF buf;
> DWORD received=0;
> DWORD flags=0;
> WSAOVERLAPPED ovl;
> int r = ES_OK;
> HANDLE qevents[2]; // overlapped results and quit events
> BOOL br=FALSE;
>
> buf.buf = buffer;
> buf.len = len;
>
> ZeroMemory(&ovl,sizeof(WSAOVERLAPPED));
> ovl.hEvent = WSACreateEvent();
>
> qevents[0] = get_quit_event_handle();
> qevents[1] = ovl.hEvent;
>
> // Sleep(30000);
> r = WSARecv(sock,&buf,1,&received,&flags,&ovl,NULL);
>
>
> while (r != ES_OK)
> {
> r = WaitForMultipleObjects( 2, qevents, FALSE, INFINITE );
> if ( r - WAIT_OBJECT_0 == 0 ) // quit request
> {
> goto EXIT;
> }
> else if ( r - WAIT_OBJECT_0 != 1 ) //some error condidtion
> {
> r = WSAGetLastError();
> gESLog.lock(); gESLog << dmp_log::tmstr() << " ERROR: waiting for
> queue, WSA err.: " << (size_t)r << ENDL; gESLog.unlock();
> gESLog.flush_stream();
> goto EXIT;
> }
> else
> break; // we have rec'd data
> }
>
> //overlapped results should be ready
> received = 0;
> r = ES_OK;
> WSAResetEvent(ovl.hEvent);
> br = WSAGetOverlappedResult( sock, &ovl, &received, FALSE, &flags);
>
> if (!br)
> r = WSAGetLastError();
>
>
> EXIT:
> CloseHandle(ovl.hEvent);
> return r;
> }
>
date: Thu, 29 Dec 2005 10:04:13 +0200
author: Arkady Frenkel
Re: WSARecv
Additionally , by default socket you call WSARecv/Send on them are blocked
and you need to make them non-blocked explicitely , maybe you did it , but
that not seen in the part of the code you showed JFYI
Arkady
"Arkady Frenkel" wrote in message
news:uGKGg5EDGHA.2704@TK2MSFTNGP15.phx.gbl...
> Check that you haven't some additional s/w in the stack ( LSP ... ) and
> compare the times sniffer show for packets and WSAERecv() ( put time just
> after it , that sounds very )
> Arkady
>
> wrote in message
> news:1135727876.495596.50200@g47g2000cwa.googlegroups.com...
>> Hello:
>>
>> I have a multi-threaded server app that receives requests does some
>> transforms and then sends the requests along to a 2nd server. The 2nd
>> server responds and this info is sent to the client.
>>
>> Communication with the 2nd server is done via non blocking sockets
>> using wsasend and wsarecv.
>>
>> I'm using an internal protocol that has as its first 4 bytes the length
>> of the entire packet.
>>
>> My WSARecv loop from the 2nd server works most of the time but
>> sometimes it seems to recv bytes even though the 2nd server hasn't sent
>> any (I confirmed this with a sniffer).
>>
>> I call the return below in a loop...first I call it looking for 4 bytes
>> to get the size of the packet and then I call it looking for the
>> remainder of the packet.
>>
>> Since I'm running in a windows service, I'm also waiting on an event
>> that gets set when the service is shutdown.
>>
>> I've been banging my head on this for awhile...
>>
>> anyone know why WSARecv would receive bytes when there should be
>> nothing to receive?
>>
>> I did verify that WSALastError is set to WSA_IO_PENDING...
>>
>> Thanks
>>
>>
>> DWORD receive_async_data(SOCKET sock, char* buffer, int32 len)
>> {
>> WSABUF buf;
>> DWORD received=0;
>> DWORD flags=0;
>> WSAOVERLAPPED ovl;
>> int r = ES_OK;
>> HANDLE qevents[2]; // overlapped results and quit events
>> BOOL br=FALSE;
>>
>> buf.buf = buffer;
>> buf.len = len;
>>
>> ZeroMemory(&ovl,sizeof(WSAOVERLAPPED));
>> ovl.hEvent = WSACreateEvent();
>>
>> qevents[0] = get_quit_event_handle();
>> qevents[1] = ovl.hEvent;
>>
>> // Sleep(30000);
>> r = WSARecv(sock,&buf,1,&received,&flags,&ovl,NULL);
>>
>>
>> while (r != ES_OK)
>> {
>> r = WaitForMultipleObjects( 2, qevents, FALSE, INFINITE );
>> if ( r - WAIT_OBJECT_0 == 0 ) // quit request
>> {
>> goto EXIT;
>> }
>> else if ( r - WAIT_OBJECT_0 != 1 ) //some error condidtion
>> {
>> r = WSAGetLastError();
>> gESLog.lock(); gESLog << dmp_log::tmstr() << " ERROR: waiting for
>> queue, WSA err.: " << (size_t)r << ENDL; gESLog.unlock();
>> gESLog.flush_stream();
>> goto EXIT;
>> }
>> else
>> break; // we have rec'd data
>> }
>>
>> //overlapped results should be ready
>> received = 0;
>> r = ES_OK;
>> WSAResetEvent(ovl.hEvent);
>> br = WSAGetOverlappedResult( sock, &ovl, &received, FALSE, &flags);
>>
>> if (!br)
>> r = WSAGetLastError();
>>
>>
>> EXIT:
>> CloseHandle(ovl.hEvent);
>> return r;
>> }
>>
>
>
date: Thu, 29 Dec 2005 10:29:43 +0200
author: Arkady Frenkel
|
|