iPhone无法使用UDP recvfrom接收数据

时间:2009-04-20 08:25:27

标签: iphone cocoa cocoa-touch macos

我正在编写一个不断发送和接收数据的应用程序。我的初始发送/接收成功运行,但是当我期望recvfrom中的大小为512字节的数据时,我得到的返回值为-1,即“资源暂时不可用”。和errno设置为EAGAIN。如果我使用阻塞调用,即没有超时,应用程序只会在recvfrom中挂起。 iPhone上的recvfrom有最大限制吗?以下是从服务器接收数据的功能。我无法弄清楚会出现什么问题。

{   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 个答案:

答案 0 :(得分:1)

阅读the manpage

  

如果套接字上没有可用的消息,则接收调用等待消息到达,除非套接字是非阻塞的(参见fcntl(2)),在这种情况下返回值-1和外部变量{{ 1}}设置为errno

答案 1 :(得分:1)

我正在编写UDP应用程序,并认为我遇到了类似的问题。 Peter Hosey说明recvfrom的给定结果意味着没有数据可读;但你想知道,怎么没有数据?

如果您一次从某个主机向您的iphone发送多个UDP数据报,那么这些数据报中的一些可能会被丢弃,因为接收缓冲区大小(在iphone上)不足以同时容纳那么多数据。 / p>

解决问题的有效方法是实现一项功能,允许您的应用程序请求重新传输丢失的数据报。一个不那么强大的解决方案(不能解决强健解决方案所做的所有问题)只是使用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...
}

您可能需要使用缓冲区大小来找到适合您应用的最佳选择。

答案 2 :(得分:0)

对我来说,这是一个强制性的问题。本质上,a是将返回值分配给int而不是size_t

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

代替:

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