Search code examples
csocketsudprecvfrom

recvfrom in socket programming with C


So I was trying to understand socket programming in C when I came across this code:

/* Sample UDP client */

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char**argv)
{
    int sockfd,n;
    struct sockaddr_in servaddr;
    char sendline[] = "Hello UDP server! This is UDP client";
    char recvline[1000];

    if (argc != 2)
    {
        printf("usage:  ./%s <IP address>\n",argv[0]);
        return -1;
    }

    sockfd=socket(AF_INET,SOCK_DGRAM,0);

    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr=inet_addr(argv[1]);
    servaddr.sin_port=htons(32000);

    sendto(sockfd,sendline,strlen(sendline),0,(struct sockaddr *)&servaddr,sizeof(servaddr));
    n=recvfrom(sockfd,recvline,10000,0,NULL,NULL);
    recvline[n]=0;
    printf("Received: %s\n",recvline);
    return 0;
}

It seems that the recvfrom() call does not need an ip address to send the message. A look at the man pages revealed the following lines:

If src_addr is not NULL, and the underlying protocol provides the source address, this source address is filled in. When src_addr is NULL, nothing is filled in; in this case, addrlen is not used, and should also be NULL.

So I think that the underlying protocol provides the source IP address. My problem is, how does it really figure out the address to receive the message from ? Is it that, once you send a message to an address, you cannot use the same socket to send messages to other addresses ? So that it keeps on using the same address ?

Please help. Couldn't find an answer anywhere in Google or any lecture note.

Thank you in advance.


Solution

  • You have a misconception that recvfrom pulls data from a particular source address.

    recvfrom is generally used for connectionless protocols like UDP. When an UDP packet is received, it could be from any source address. src_addr returns this address for the application usage.

    If you are expecting messages only from a particular address, there are 2 ways. (1) Either you can ignore the packets received from other addresses by comparing the address returned in src_addr, or (2) use connect to specify a particular remote address from where you are expecting messages and the lower socket layer takes care of ignoring packets from other sources. After connect, you could also use recv instead of recvfrom.

    Sending messages are done through sendto. You seem to be confusing the 2 calls. Using sendto it is possible to send messages to difference addresses on the same socket.