sendto: ресурс временно недоступен (errno 11) - PullRequest
5 голосов
/ 21 апреля 2011

У меня проблема с sendto.

У меня есть получатель, который получает пакеты UPD с помощью recvfrom, а затем отвечает отправителю с помощью sendto.

К сожалению, я получаю сообщение об ошибке 11 (Ресурс временно недоступен).Я использую два сокета.

Первый пакет фактически отправлен, но не тот, что потом:

sendto :: Success

ошибка: 0.

sendto :: Ресурс временно недоступен

ошибка: 11.

sendto :: Ресурс временно недоступен

...

Это выдержка из моего кода:

    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");

А в обработчике SIGIO:

    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);

     }

Может ли эта проблема возникнуть, поскольку порт еще горячий, и мне нужно подождать, прежде чем использовать его повторно?Я пытался сменить порт, но это не помогло.

Обновление: если сон (1) закомментирован, то пакеты действительно отправляются!

Большое спасибо за вашпомощь.

Ответы [ 2 ]

10 голосов
/ 21 апреля 2011

Ошибка, которую вы получаете:

EAGAIN или EWOULDBLOCK: сокет помечен как неблокирующий, и запрошенная операция будет заблокирована. POSIX.1-2001 допускает возврат любой ошибки для этого случая и не требует, чтобы эти константы имели одинаковое значение, поэтому переносимое приложение должно проверять обе возможности.

Вы устанавливаете сокет как неблокирующий (O_NONBLOCK). Сокет все еще занят отправкой предыдущего сообщения. Вы не можете отправить другой, пока первая не закончила отправку. Вот почему сон помог.

Не устанавливайте его как неблокирующее или попробуйте снова после того, как select скажет, что вы можете.

0 голосов
/ 14 августа 2015

Если вам нужно установить неблокирующее гнездо, вы можете сделать это безопасно (и только?), Используя select:

select () и pselect () позволяют программе отслеживать несколько файловых дескрипторов, ожидая, пока один или несколько файловых дескрипторов станут «готовыми» для некоторого класса I / O операция (например, возможен ввод). Файловый дескриптор считается готовым, если можно выполнить соответствующую операцию ввода-вывода (например, read (2)) без блокировки.

...