UDP Socket recvfrom fails to receive packet in non-block mode, but when off it works perfectly

I don't have the slightest idea why my UDP server is able to receive packets while the socket's non-block mode is off. If I turn it on so it doesn't block the thread, bytes received are -1 and when I check the errno code, I get 11.

I googled the error code and I found EAGAIN. I'm still confused :(

I'll share my server code, I got it from a tutorial site:

// Server
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <arpa/inet.h> 
#include <netinet/in.h> 
#include <fcntl.h>
#include <errno.h>
#include <iostream>

#define PORT	 8080 
#define MAXLINE 1024 

int main() { 
	int sockfd; 
	char buffer[MAXLINE]; 
	char *hello = "Slsls"; 
	struct sockaddr_in servaddr, cliaddr; 
	
	// Creating socket file descriptor 
	if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) { 
		perror("socket creation failed"); 
		exit(EXIT_FAILURE); 
	} 
	
    int flags = fcntl(sockfd, F_GETFL, 0);

    if (fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) == -1) {
        printf("Failed non-block\n");
        return false;
    }


	memset(&servaddr, 0, sizeof(servaddr)); 
	memset(&cliaddr, 0, sizeof(cliaddr)); 
	
	// Filling server information 
	servaddr.sin_family = AF_INET; // IPv4 
	servaddr.sin_addr.s_addr = INADDR_ANY; 
	servaddr.sin_port = htons(PORT); 
	
	// Bind the socket with the server address 
	if ( bind(sockfd, (const struct sockaddr *)&servaddr, 
			sizeof(servaddr)) < 0 ) 
	{ 
		perror("bind failed"); 
		exit(EXIT_FAILURE); 
	} 

    while (true) {
        socklen_t len; 
        socklen_t bytes; 

        len = sizeof(cliaddr); //len is value/resuslt 

        bytes = recvfrom(sockfd, (char *)buffer, MAXLINE, 0, ( struct sockaddr *) &cliaddr, &len); 
        
        if (bytes > -1) {
            printf("Client (%d bytes): %s\n", bytes, buffer);
        }
        else {
            std::cout << "Error Reveiving: " << errno << std::endl;
        }
    } 
	
	return 0; 
} 
I don't see the problem? When it is blocking it waits until data is available. When it is non blocking the receive function does not wait. So you need to keep reading until it does not return an error or wait for a signal the tells you that data is available.
Presumably by going for non-blocking, you have in mind something else to do if there is no immediate data.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    while (true) {
        socklen_t len; 
        socklen_t bytes; 

        len = sizeof(cliaddr); //len is value/resuslt 

        bytes = recvfrom(sockfd, (char *)buffer, MAXLINE, 0, ( struct sockaddr *) &cliaddr, &len); 
        
        if (bytes > -1) {
            // buffer isn't \0 terminated, so don't print more than there is.
            printf("Client (%d bytes): %.*s\n", bytes, bytes, buffer);
            if ( bytes == 0 ) break;  // the show is over
        }
        else {
            if ( errno == EAGAIN ) {
                // go do something else for a while
                // perhaps sleep for say a second
            } else {
                std::cout << "Error Reveiving: " << errno << std::endl;
            }
        }
    } 


Your printf was also wrong (fixed).
That code, if it works, will spin, i.e. it will keep going around in a loop, stopping briefly for the rare occasions that data is available to be read.

You should use select() to wait for data to arrive. It has a timeout on the wait that will allow you to do some work while waiting and it allows you to wait on multiple file descriptors. And let's face it, the only reason to use non-blocking sockets is to do something else while waiting for the data to arrive.
Hey everybody, my apologies, I didn't know I got replies on this question. Much appreciated, I'll mark it as solved!
Topic archived. No new replies allowed.