5

I am having a problem with sendto.

I have a receiver who receives UPD packets with recvfrom and then replies to the sender using sendto.

Unfortunately, I am getting errno 11 (Resource temporarily unavailable). I am using two sockets.

The first packet is actually sent but not the ones afterwards:

sendto :: Success

error: 0.

sendto :: Resource temporarily unavailable

error: 11.

sendto :: Resource temporarily unavailable

...

This is an extract of my code:

    int sockfd, sockSend;

    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
            perror("socket");

    if ((sockSend = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
            perror("socket");

    if (fcntl(sockfd, F_SETOWN, getpid()) < 0) {
            perror("fcntl"); 
    }
    if (fcntl(sockfd, F_SETFL, O_RDONLY | O_NONBLOCK | FASYNC) < 0) {
            perror("fcntl"); 
    } 

    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr))
                    < 0)
            perror("bind");

And in a SIGIO handler:

    len = sizeof(recv_addr);
    char buffer[payload];
    bzero(buffer, payload);
    n = recvfrom(sockfd, buffer, payload, MSG_DONTWAIT, (struct sockaddr *)&recv_addr, &len);

    while (n > 0) {

                            sprintf(response, "%d\n%d\n%d\n", items, target_buf, pb_sp);          
                            sendto(sockSend, response, strlen(response), 0, (struct sockaddr *) &recv_addr, sizeof(recv_addr));
                            // sleep(1);

                            perror("sendto :");
                            printf("error: %d.\n", errno);

     }

Could this issue come because the port is still hot, and I need to wait before reusing it? I've tried to change port but it hasn't helped.

Update: If the sleep(1) is commented out, then the packets actually get send!

Thanks a lot for your help.

Jary
  • 53
  • 1
  • 1
  • 4
  • Are you using two sockets with the same port? If so, what is the reason? – penguin359 Apr 20 '11 at 22:47
  • Perhaps `SO_REUSEADDR` would help. Or you could just keep the port open rather than opening and closing it, or use a new randomly assigned port number each time if that's feasible. – R.. GitHub STOP HELPING ICE Apr 20 '11 at 22:52
  • I have added more code. I have 2 sockets but only one gets binded to a port (to receive data on a specific port), the other one can send data from any port. – Jary Apr 20 '11 at 22:53
  • R: I just tried to use SO_REUSEADDR and it did not help. What do you mean by keeping the port assumed? I don't think it is getting closed as I am not calling close()? – Jary Apr 20 '11 at 23:00
  • I realized that using sleep() removes the problem, but I am not sure how to fix the issue without it. – Jary Apr 21 '11 at 00:10

2 Answers2

11

The error you are getting:

EAGAIN or EWOULDBLOCK: The socket is marked nonblocking and the requested operation would block. POSIX.1-2001 allows either error to be returned for this case, and does not require these constants to have the same value, so a portable application should check for both possibilities.

You set the socket to non-blocking (O_NONBLOCK). The socket is still busy sending the previous message. You cannot send another until the first has finished sending. That's why sleeping helped.

Don't set it to non-blocking, or try again after select says you can.

ikegami
  • 367,544
  • 15
  • 269
  • 518
  • Thanks a lot. But O_NONBLOCK is for sockfd, shouldn't sockSend be blocking (default behavior)? I use sockfd to receive and sockSend to send data. I removed O_NONBLOCK in fcntl() and the same behavior occurs. This was what you were mentioning, right? – Jary Apr 21 '11 at 00:17
  • By removing O_NONBLOCK AND also MSG_DONTWAIT it ends up working! Thank you very very much! Is there any way though to keep one socket blocking (Sending) and one non-blocking (for receiving) please?! – Jary Apr 21 '11 at 00:51
0

If you have to set the socket to non-blocking, you can do it safely (and only?) using select:

select() and pselect() allow a program to monitor multiple file descriptors, waiting until one or more of the file descriptors become "ready" for some class of I/O operation (e.g., input possible). A file descriptor is considered ready if it is possible to perform the corresponding I/O operation (e.g., read(2)) without blocking.

Ali Abbasinasab
  • 382
  • 3
  • 13