Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I have to bind a UDP socket in my client program to receive data? (I always get WSAEINVAL)

Tags:

c++

winsock

I am creating a UDP socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP) via Winsock and trying to recvfrom on this socket, but it always returns -1 and I get WSAEINVAL (10022). Why?

When I bind() the port, that does not happen, but I have read that it is very lame to bind the client's socket.

I am sending data to my server, which answers, or at least, tries to.

Inc::STATS CConnection::_RecvData(sockaddr* addr, std::string &strData) {     int ret;            // return code     int len;            // length of the data     int fromlen;        // sizeof(sockaddr)     char *buffer;       // will hold the data     char c;      //recv length of the message     fromlen = sizeof(sockaddr);     ret = recvfrom(m_InSock, &c, 1, 0, addr, &fromlen);     if(ret != 1)     { #ifdef __MYDEBUG__         std::stringstream ss;         ss << WSAGetLastError();         MessageBox(NULL, ss.str().c_str(), "", MB_ICONERROR | MB_OK); #endif         return Inc::ERECV;     }     ... 

This is a working example I wrote a few moments ago, and it works without the call to bind() in the client:

#pragma comment(lib, "Ws2_32.lib")  #define WIN32_LEAN_AND_MEAN  #include <WS2tcpip.h> #include <Windows.h> #include <iostream>  using namespace std;  int main() {     SOCKET sock;     addrinfo* pAddr;     addrinfo hints;     sockaddr sAddr;     int fromlen;     const char czPort[] = "12345";     const char czAddy[] = "some ip";      WSADATA wsa;     unsigned short usWSAVersion = MAKEWORD(2,2);      char Buffer[22] = "TESTTESTTESTTESTTEST5";     int ret;      //Start WSA     WSAStartup(usWSAVersion, &wsa);      //Create Socket     sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);      //Resolve host address     memset(&hints, 0, sizeof(hints));     hints.ai_family = AF_INET;     hints.ai_protocol = IPPROTO_UDP;     hints.ai_socktype = SOCK_DGRAM;      if(getaddrinfo(czAddy, czPort, &hints, &pAddr))     {         std::cerr << "Could not resolve address...\n";         std::cin.get();         return 1;     }      //Start Transmission     while(1)     {         ret = sendto(sock, Buffer, sizeof(Buffer), 0, pAddr->ai_addr,                      pAddr->ai_addrlen);         if(ret != sizeof(Buffer))         {             std::cerr << "Could not send data\n";             std::cin.get();             return 1;         }          fromlen = sizeof(SOCKADDR);         ret = recvfrom(sock, Buffer, sizeof(Buffer), 0, &sAddr, &fromlen);         if(ret != sizeof(Buffer))         {             std::cout << "Could not receive data -  error: " <<                            WSAGetLastError() << std::endl;             std::cin.get();             return 1;         }          Buffer[ret-1] = '\0';         std::cout << "Received: " << Buffer << std::endl;     }     return 0; } 
like image 326
Juarrow Avatar asked Jun 16 '10 20:06

Juarrow


People also ask

Is bind necessary for UDP client?

As far as I remember bind is not required for a UDP socket because a bind call is made for you by the stack.

Do I need to close UDP socket?

Close the socket Since there is no concept of a connection in UDP, there is no need to call shutdown.

What does bind do in UDP?

What does bind() function do in TCP/UDP server? Answer: Bind() function in socket programming is used to associate the socket with local address i.e. IP Address, port and address family.

Why do you need to bind a socket?

The bind() method is used when a socket needs to be made a server socket. As server programs listen on published ports, it is required that a port and the IP address to be assigned explicitly to a server socket. For client programs, it is not required to bind the socket explicitly to a port.


1 Answers

With UDP, you have to bind() the socket in the client because UDP is connectionless, so there is no other way for the stack to know which program to deliver datagrams to for a particular port.

If you could recvfrom() without bind(), you'd essentially be asking the stack to give your program all UDP datagrams sent to that computer. Since the stack delivers datagrams to only one program, this would break DNS, Windows' Network Neighborhood, network time sync....

You may have read somewhere on the net that binding in a client is lame, but that advice only applies to TCP connections.

like image 84
Warren Young Avatar answered Sep 29 '22 04:09

Warren Young