Advertisement

UDP IOCP error on WSARecvFrom() call

Started by May 24, 2003 02:21 PM
5 comments, last by RonHiler 21 years, 8 months ago
This returns a 997 error (ERROR_IO_PENDING) on my WSARecvFrom() call. Now, I know that that a WSA_IO_PENDING is normal for an overlapped call, but I didn''t think a 997 was supposed to happen as well. Is this error harmless? Should I ignore it the same way I ignore a WSA_IO_PENDING error? Here''s the offending code snippets...

    //get a buffer for the receive port and post a read
    BufferIndex = GetBuffer();
    PendingReadBufferList.push_back(BufferIndex);
    WinSockError = DataBuffer[BufferIndex].StartRead(&ReceiveSocket);
    if (WinSockError == SOCKET_ERROR)
        {
        if (WSAGetLastError() != WSA_IO_PENDING)
            {
            [....error handling....];
            }
        }
 

int BufferClass::StartRead(SOCKET *Socket)
    {
    WSABUF WSABuf;

    Operation = OP_READ;
    ZeroMemory(&Overlapped, sizeof(WSAOVERLAPPED));
    WSABuf.len = BUFFER_SIZE;
    WSABuf.buf = Data;
    ClientAddressSize = sizeof(sockaddr);
    Flags = 0;

    return WSARecvFrom(*Socket, &WSABuf, 1, &NumBytes, &Flags, (sockaddr*)&ClientAddress, &ClientAddressSize, &Overlapped, NULL);
    }
 
Am I doing something wrong? The nature of the error suggests it may or may not be working. I''ve just never seen anyone check for the ERROR_IO_PENDING as well as WSA_IO_PENDING on a receive call. Ron
Creation is an act of sheer will
You have posted a call using a buffer that is on the stack. Once you return, that part of memory is being overwritten by the application and thus the OS''s contention in using such memory.


  class nsOverlapped{	public:		nsOverlapped( )		{		}		~nsOverlapped( )		{		}	public:		WSAOVERLAPPED		m_ol;		struct sockaddr_in	m_sAddr;		int					m_iLen;		WSABUF				m_wsaBuffer;		DWORD				m_dwNbBytes;		nsIOType			m_eIOType;		char				m_cBuffer[ PCKT_MAX_SIZE ];};//******************************************************//  $$S  cnsSocketServer::PostRecvFrom()////	returns:	-1, there was an error//				 0, completion was immediate//				+1, completion was posted////******************************************************int cnsSocketServer::PostRecvFrom( void ){	//---- Create a new OVL struct	nsOverlapped *	l_pOvl = new nsOverlapped;	//---- Initialize the OVL struct	::memset( &l_pOvl->m_ol, 0, sizeof(WSAOVERLAPPED) );	l_pOvl->m_wsaBuffer.buf	= &l_pOvl->m_cBuffer[ 0 ];	l_pOvl->m_wsaBuffer.len	= PCKT_MAX_SIZE;	l_pOvl->m_dwNbBytes		= 0;	l_pOvl->m_eIOType		= nsIOT_RECV;	l_pOvl->m_iLen			= sizeof( struct sockaddr_in );	//---- Post the recvfrom() call.	DWORD	l_dwFlags = 0;	int		l_iRet = ::WSARecvFrom( m_sockUDP.GetSocket(), &l_pOvl->m_wsaBuffer, 1,							&l_pOvl->m_dwNbBytes, &l_dwFlags, (struct sockaddr*)&l_pOvl->m_sAddr,							&l_pOvl->m_iLen, &l_pOvl->m_ol, NULL );	//---- Analyze the error code.	if ( l_iRet == SOCKET_ERROR )	{		DWORD l_dwErr = ::WSAGetLastError();		if ( l_dwErr != WSA_IO_PENDING )		{			//---- ERROR			delete l_pOvl;			return( -1 );		}		else		{			//---- POSTED			return( 1 );		}	}	//---- EXECUTED IMMEDIATELY	return( 0 );}  


-cb
Advertisement
Man that code was hidious to read.

Since ERROR_IO_PENDING is the same as WSA_IO_PENDING, what seems to be the problem?

[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
Ah, I see, so I must make the WSABUF structure a member of the class. So many pitfalls in IOCP

DF: Apparently they are *not* the same thing, though I admit they seem to be related, which is what threw me off. I wasn''t sure if I was getting an error or not I was checking for the WSA_IO_PENDING error, but it wasn''t coming up. The ERROR_IO_PENDING error, on the other hand, fell through into my error handler. Very confusing.

I will make the WSABUF a member variable and see if that fixes it.
Creation is an act of sheer will
Thanks for the tip cb, I''m sure you averted what would have been a nasty bug

It didn''t make the error go away, though. As far as I can tell from my research, ERROR_IO_PENDING is equivalent to WSA_IO_PENDING. I read one document claiming they were supposed to be defined as the same code. Clearly this is not the case on my machine.

So anyway, I''m going to ignore both of them, and presume they mean that the operation is successful, unless someone knows something different.
Creation is an act of sheer will
WSA_IO_PENDING is defined as ERROR_IO_PENDING in the "winsock2.h" header file, so unless your compiler or defines are messed up, WSA_IO_PENDING == ERROR_IO_PENDING.

[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
Advertisement
Strangely my defines do seem to be messed up.

You''re right, in the Winsock header is this bit:

#ifdef WIN32
#define WSA_IO_PENDING (ERROR_IO_PENDING)
#else
#define WSA_IO_PENDING (WSAEWOULDBLOCK)
#endif

I checked, and sure enough, my WSA_IO_PENDING was set to WSAEWOULDBLOCK. This is very odd, because I do have the #define WIN32 in my code. Somewhere it was getting undefined. As a temporary measure, I stuck a
#if !defined WIN32
#define WIN32
#endif
right in front of my winsock2.h include, and then it was set properly.

I''ll have to hunt down why my first WIN32 define isn''t sticking. I find that very strange.

Thanks for pointing out the declaration. At least I know the code is working, if not why my define isn''t
Creation is an act of sheer will

This topic is closed to new replies.

Advertisement