Reputation: 23
I'm trying to create an UDP interaction client/server. I'm having some issues trying to send messages with this code. During the execution I've got this error:
"Address family not supported by protocol" after the sendto function. Thanks in advance!
int prepare_udp_socket(char *pong_addr, char *pong_port)
{
struct addrinfo gai_hints, *pong_addrinfo = NULL;
int ping_socket;
int gai_rv;
int np;
/*** Specify the UDP sockets' options ***/
memset(&gai_hints, 0, sizeof gai_hints);
gai_hints.ai_family=AF_INET;
gai_hints.ai_socktype=SOCK_DGRAM;
gai_hints.ai_flags=0;
gai_hints.ai_protocol = IPPROTO_UDP;
if ((ping_socket = socket(gai_hints.ai_family, gai_hints.ai_socktype, gai_hints.ai_protocol)) == -1)
fail_errno("UDP Ping could not get socket");
/*** change socket behavior to NONBLOCKING ***/
if(fcntl(ping_socket,F_SETFL, O_NONBLOCK)==-1)
fail_errno("set NONBLOCKING socket fail");
//call getaddrinfo() in order to get Pong Server address in binary form
gai_rv=getaddrinfo(pong_addr, pong_port, &gai_hints, &pong_addrinfo);
if(gai_rv!=0){
printf("Getaddrinfo failed\n");
exit(1);
}
/*** connect the ping_socket UDP socket with the server ***/
if(connect(ping_socket, pong_addrinfo->ai_addr, pong_addrinfo->ai_addrlen)!=0){
fail_errno("Can't connect");
}
freeaddrinfo(pong_addrinfo);
return ping_socket;
}
double do_ping(int msg_size, int msg_no, char message[msg_size], int ping_socket, double timeout)
{
int lost_count = 0;
char answer_buffer[msg_size];
ssize_t recv_bytes, sent_bytes;
int offset;
struct sockaddr_storage pong_addr;
size_t pong_addr_len = sizeof(struct sockaddr_storage);
struct timespec send_time, recv_time;
double roundtrip_time_ms;
int re_try = 0;
/*** write msg_no at the beginning of the message buffer ***/
if(sprintf(message,"%d\n",msg_no)<0){
fail("sprintf(...) failed");
}
do {
debug(" ... sending message %d\n", msg_no);
/*** Store the current time in send_time ***/
if(clock_gettime(CLOCK_MONOTONIC,&send_time)!=0){
fail_errno("clock_gettime failed with sendTime");
}
/*** Send the message through the socket ***/
**if((sent_bytes = sendto(ping_socket, &message, msg_size,0,(struct sockaddr*)&pong_addr,pong_addr_len)) == -1){
fail_errno("Cannot send bytes throught the socket");**
}
Upvotes: 2
Views: 2851
Reputation: 13826
The problem is in your do_ping
function, sendto
expect the address and length as its 5th and 6th arguments, they are input arguments, that means, you need to specify the address of the destination host you want to send the packets to, you have to initialize the address to a valid one. What you are doing is like 'recvfrom` actually.
Also, message
is a pointer to char inside the function, so don't use &message
in sendto
, just pass message
.
struct sockaddr_storage pong_addr;
// pong_addr is not initialized here, initialize pong_addr to a valid address, like the one you got from `getaddrinfo` call
size_t pong_addr_len = sizeof(struct sockaddr_storage);
// then call sendto to send to the address
if((sent_bytes = sendto(ping_socket, message, msg_size, 0, (struct sockaddr*)&pong_addr, pong_addr_len)) == -1){
fail_errno("Cannot send bytes throught the socket");**
}
Upvotes: 1