I have written a short piece of code that fetches a value from a server over UDP.
The code works great in its current form.
However, I'm not sure on how to implement proper handling of errors that might occur.
For example, I have tried to implement code to catch the -1 value that should occur due to error with opening the FD for the socket, and also for the sending.
However, trying to use this code towards a IP that does not exist, it seems as it just opens up, and actually sends out the UDP packet. This might be normal, since its not actually failing per se.
What happens then is that it just sits at the code for receiving data for ever.
I would like for it to either time out due to not getting any reply and then just return so that the user gets feedback that the server is not responding.
What would be the best way to achieve this? Most of the examples I found, even in books does not really cover what happens when the server does not reply
This is the code I have so far:
int getcount ()
{
/*TODO:
Add proper error handling:
error when socket is opened
error when sending
error when receiving and add receiver timeout
*/
char *ip = "192.168.1.183";
int port = 27015;
int sockfd;
int err;
struct sockaddr_in addr;
char buffer[1024]; //Store the server reply here
char firstreq[1024] = "ÿÿÿÿUÿÿÿÿ"; //This is what we need to ask to get a challengekey
char challenge[1024]; //Something to store the challenge in
char concatted[1024] = "ÿÿÿÿU"; //Something to add the challenge to and then request the actual data
socklen_t addr_size;
memset(&addr, '\0', sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(ip);
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) //Try to catch error when opening the fd for the socket.
{
printf ("Socket open failed");
return(-1);
}
addr_size = sizeof(addr);
//Send this message to get a reply with a challenge value:
err = sendto(sockfd, firstreq, 9, 0, (struct sockaddr*)&addr, sizeof(addr));
if (err < 0) //Try to catch error when sending the request.
{
printf("Send failed");
return (err);
}
//Recieve the challenge value:
err = recvfrom(sockfd, challenge, 9, 0, (struct sockaddr*)&addr, &addr_size);
//Concat the challenge value and message together:
memcpy(concatted + 4 + 1, challenge + 5, 10 - 5 + 1);
//Reply with this to server
sendto(sockfd, concatted, 9, 0, (struct sockaddr*)&addr, sizeof(addr));
bzero(buffer, 1024);
//Recieve the data from server:
recvfrom(sockfd, buffer, 1024, 0, (struct sockaddr*)&addr, &addr_size);
return(buffer[5]); //Return the 6th value that is the value we want.
}