Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

recvfrom() not filling the from IP address even for UDP messages in first call

I am using recvfrom() to get the UDP datagram into my buffer and passing non-NULL from_addr structure & len argument expecting it to get the source IP. But for the first call, they are NULL. Subsequent calls are filling the addr structure and len field. Is this expected ?

#include <stdio.h>
#include <string.h>

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>


int
main()
{
    struct  sockaddr_in myaddr, from_addr;
    char    from_ip[1024] = "", myip[2014] = "";
    char    rmsg[1024 * 1024] = "";
    int     sock_fd=-1,nbytes=0;
    int     len=0;
    unsigned short port=0;

    sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
    if(sock_fd == -1)
    {
        perror("Socket");
        return -1;
    }

    printf("IP Addr & Port to bound to :");
    scanf("%s%u", myip, &port);

    myaddr.sin_family = AF_INET;
    myaddr.sin_port = htons(port);
    inet_pton(AF_INET, myip, &myaddr.sin_addr);

    printf("Bound to %s:%u\n", myip, htons(port));

    nbytes = bind(sock_fd, &myaddr, sizeof(myaddr));
    if(nbytes == -1)
    {
        perror("Bind");
        return -1;
    }

    do
    {
        /**/nbytes = recvfrom(sock_fd, rmsg, sizeof(rmsg), 0, &from_addr, &len);/**/
        inet_ntop(AF_INET, &from_addr.sin_addr, from_ip, sizeof(from_ip));

        printf("Received %d bytes from %s@%d : %s\n", nbytes, from_ip, ntohs(from_addr.sin_port), rmsg);

        if(strcmp(rmsg, "Bye") == 0)
        {
            printf("Client Disconnected.\n");
        }
        memset(rmsg, 0, sizeof(rmsg));
    }while(1);

    return 0;
}

Output:

-------------------------------OutPut -----------------------------------------
root@ubuntu:/home/akumarkk/Desktop/distributedComp_Project/test# ./userver 
IP Addr & Port to bound to :127.0.0.1 12
Bound to 127.0.0.1:3072
Received 2 bytes from 0.0.0.0@0 : hi
Received 6 bytes from 127.0.0.1@49511 : second
Received 7 bytes from 127.0.0.1@49511 : message
Received 3 bytes from 127.0.0.1@49511 : Bye
Client Disconnected.
like image 274
Anil Kumar K K Avatar asked May 05 '14 12:05

Anil Kumar K K


People also ask

Is UDP Recvfrom blocking?

By default, Recvfrom() is blocking: when a process issues a Recvfrom() that cannot be completed immediately (because there is no packet), the process is put to sleep waiting for a packet to arrive at the socket. Therefore, a call to Recvfrom() will return immediately only if a packet is available on the socket.

How many bytes will the Recvfrom () call return?

RETURN VALUE Upon successful completion, recvfrom() shall return the length of the message in bytes. If no messages are available to be received and the peer has performed an orderly shutdown, recvfrom() shall return 0. Otherwise, the function shall return -1 and set errno to indicate the error.

What does the Recvfrom function do?

The recvfrom function reads incoming data on both connected and unconnected sockets and captures the address from which the data was sent. This function is typically used with connectionless sockets. The local address of the socket must be known.


1 Answers

You must populate len before calling recvfrom, you can't leave it 0:

len = sizeof from_addr;
nbytes = recvfrom(sock_fd, rmsg, sizeof(rmsg), 0, &from_addr, &len);
like image 149
cnicutar Avatar answered Sep 30 '22 21:09

cnicutar