我正在编写一个不断发送和接收数据的应用程序。我的初始发送/接收成功运行,但是当我期望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);
}
}
答案 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