iPhone не может получать данные с помощью UDP recvfrom - PullRequest
0 голосов
/ 20 апреля 2009

Я пишу приложение, которое постоянно отправляет и получает данные. Мой начальный отправка / получение успешно выполняется, но когда я ожидаю, что данные размером 512 байт в recvfrom, я получаю его возвращаемое значение как -1, что означает «Ресурс временно недоступен». и errno установлен в EAGAIN. Если я использую блокирующий вызов, то есть без тайм-аута, приложение просто зависает в recvfrom. Есть ли максимальное ограничение на recvfrom на iPhone? Ниже приведена функция, которая получает данные с сервера. Я не могу понять, что может быть не так.

{   struct timeval tv;

tv.tv_sec = 3;
tv.tv_usec = 100000;

    setsockopt (mSock, SOL_SOCKET, SO_RCVTIMEO, (char   *)&tv, sizeof tv);

    NSLog(@"Receiving.. sock:%d",mSock);

    recvBuff = (unsigned char *)malloc(1024);
    if(recvBuff == NULL)
        NSLog(@"Cannot allocate memory to recvBuff");

    fromlen = sizeof(struct sockaddr_in);
    n = recvfrom(mSock,recvBuff,1024,0,(struct sockaddr *)&from, &fromlen);

    if (n == -1) {
        [self error:@"Recv From"];
        return;
    }
    else
    {
        NSLog(@"Recv Addr: %s Recv Port: %d",inet_ntoa(from.sin_addr), ntohs(from.sin_port));
        strIPAddr = [[NSString alloc] initWithFormat:@"%s",inet_ntoa(from.sin_addr)];
        portNumber = ntohs(from.sin_port);
        lIPAddr = [KDefine StrIpToLong:strIPAddr];
        write(1,recvBuff,n);
        bcopy(recvBuff, data, n);
        actualRecvBytes = n;
        free(recvBuff);
    }

}

Ответы [ 3 ]

1 голос
/ 27 ноября 2009

Я писал приложение UDP и думаю, что столкнулся с подобной проблемой. Питер Хоси прав, утверждая, что данный результат recvfrom означает, что нет данных для чтения; но вам было интересно, откуда не может быть данных?

Если вы отправляете несколько дейтаграмм UDP одновременно с какого-либо хоста на ваш iphone, некоторые из этих дейтаграмм могут быть отброшены, поскольку размер буфера приема (на iphone) недостаточно велик, чтобы вместить столько данных одновременно. 1004 *

Надежный способ решения проблемы - реализовать функцию, которая позволяет вашему приложению запрашивать повторную передачу отсутствующих дейтаграмм. Не столь надежное решение (которое не решает все проблемы, которые делает это надежное решение) состоит в том, чтобы просто увеличить размер буфера приема, используя setsockopt(2).

Настройка размера буфера может быть выполнена следующим образом:

int rcvbuf_size = 128 * 1024; // That's 128Kb of buffer space.
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, 
        &rcvbuf_size, sizeof(rcvbuf_size)) == -1) {
    // put your error handling here...
}

Возможно, вам придется поэкспериментировать с размером буфера, чтобы найти оптимальный для вашего приложения.

1 голос
/ 20 апреля 2009

Чтение Руководство :

Если в сокете нет доступных сообщений, вызов приема ожидает поступления сообщения, если сокет не является неблокирующим (см. fcntl (2) ), в этом случае возвращается значение -1 и внешняя переменная errno установлена ​​на EAGAIN.

0 голосов
/ 25 сентября 2018

Для меня это была проблема кастинга. По сути, a присваивал возвращаемое значение int вместо size_t

int rtn = recvfrom(sockfd,... // wrong

вместо:

size_t rtn = recvfrom(sockfd,...// correct
...