IOCP and UDP
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
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
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
-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:
and here''s the call to post the WSARecvFrom() request:
-cb
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
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!
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement