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.
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.
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.
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.
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With