Advertisement

IOCP and UDP

Started by October 27, 2003 07:10 PM
7 comments, last by rakiner 21 years, 3 months ago
Hi, I was wondering if anyone could explain how you obtain the sockaddr of the sender using iocp and udp.
Huh? Getting the address of the sender has nothing at all to do with what model of winsock you are using. It is in the same place no matter what, namely, in one of the parameters of your receive call.

In the case of UDP, in which presumably you are using RecvFrom or WSARecvFrom, the sender''s address will be in the From or lpFrom parameter (respectively).

For instance, if you call WSARecvFrom like so:
WinSockError = WSARecvFrom(*Socket, &WSABuf, 1, &NumBytes, &Flags, (sockaddr*)&ClientAddress, &ClientAddressSize, &Overlapped, NULL);

When you get the read completion notification, ClientAddress.sin_addr.s_addr will hold the IP address, while ClientAddress.sin_port will hold the port (that the client sent on, not the port received on).

HTH, Ron
Creation is an act of sheer will
Advertisement
Ah, thanks, I was under the impression that you had to use ReadFile() with iocp, which works fine with tcp since you call AcceptEx() and get a bunch of sockets. Which would be the better choice for recieving functions, recvfrom() or WSARecvFrom(), and do you know what the advantages would be of them?
IOCP works with WSAOVERLAPPED structs, so WSARecvFrom() / WSASendTo() need to be used; you don''t have much choice I''m afraid.

-cb
I''m having a problem. It seems that WSARecvFrom() is incompatible with iocp. I start a completion port and listen but dont recieve anything, so I tried calling ReadFile() before I waited on GetQueuedCompletionStatus() and got error 10014 after calling WSARecvFrom(). If I call WSARecvFrom() before GetQueuedCompletionStatus() nothing happens aswell. However, when I call ReadFile() before and after GetQueuedCompletionStatus() I recieve every packet. Any clue why this is happening? Is WSARecvFrom() incompatible with iocp? Any ideas on how I could obtain the sockaddr a different way if WSARecvFrom() won''t work? Any help would be appreciated.
> Is WSARecvFrom() incompatible with iocp?

I have a project that uses that and never had any problem whatsoever. Some WSARecvFrom() parameters are meant to be stored as part of the WSAOVERLAPPED struct so that they would be filled when a packet does come in. Here is what I use:

enum nsIOType{   nsIOT_ERROR = 0,   nsIOT_QUIT,   nsIOT_RECV,   nsIOT_SEND};class cnsOverlapped{   public:      WSAOVERLAPPED         m_ol;      struct sockaddr_in    m_sAddr;      int                   m_iAddrLen;      nsIOType              m_eIOType;      char                  m_cBuffer[ nsPCKT_MAX_SIZE ];};


and here''s the call to post the WSARecvFrom() request:

int cnsLibnetSockIocp::PostRecvFrom( void ){	WSABUF			l_wsaBuff;	DWORD			l_dwBytes;	DWORD			l_dwFlags = 0L;	//---- Create a new OVL struct	cnsOverlapped *	l_pOvl = NewOverlapped( NULL );	//---- Initialize the OVL struct	l_wsaBuff.buf			= &l_pOvl->m_cBuffer[ 0 ];	l_wsaBuff.len			= nsPCKT_MAX_SIZE;	l_pOvl->m_eIOType		= nsIOT_RECV;	l_pOvl->m_iAddrLen		= sizeof( struct sockaddr_in );	//---- Post the recvfrom() call.	int		l_iRet = ::WSARecvFrom( m_sock, &l_wsaBuff, 1, &l_dwBytes, &l_dwFlags,									(struct sockaddr*)&l_pOvl->m_sAddr,									&l_pOvl->m_iAddrLen, &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
Thanks for the reply, I think I am calling WSARecvFrom correctly... but maybe I am creating the socket and completion port wrong? Currently i use the socket() function to create the socket, then bind() on INADDR_ANY, and finally I create the port with CreateIoCompletionPort(). After that i have the threads enter a loop and wait on GetQueuedCompletionStatus(), and once iocp triggers the status it should call WSARecvFrom(). The problem is GetQueuedCompletionStatus() is never triggered, so should I be creating the socket or port differently? Are there any special socket flags that need to be set? And is there maybe something I forgot to do after I created the port?
Ah, I got it to work. I was passing in 0 for the flag value instead of an address of a variable set to 0. But I also need to call ReadFile() once right after creating the io port or no data will be recieved ever. Do you have to do this as well? Just curious... Thanks for all the help though!
> Currently i use the socket() function to create the socket

m_sock = ::WSASocket( AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, WSA_FLAG_OVERLAPPED );

The WSA_FLAG_OVERLAPPED is crucial.

-cb

This topic is closed to new replies.

Advertisement