views:

778

answers:

2

I am writing an application which is continuously sending and receiving data. My initial send/receive is running successfully but when I am expecting data of size 512 bytes in the recvfrom I get its return value as -1 which is "Resource temporarily unavailable." and errno is set to EAGAIN. If I use a blocking call i.e. without Timeout the application just hangs in recvfrom. Is there any max limit on recvfrom on iPhone? Below is the function which receives data from the server. I am unable to figure out what can be going wrong.

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

}

A: 

Read the manpage:

If no messages are available at the socket, the receive call waits for a message to arrive, unless the socket is nonblocking (see fcntl(2)) in which case the value -1 is returned and the external variable errno set to EAGAIN.

Peter Hosey
I want to know whether is there any max limit for number of IO Threads to be created or may be the network interfaces are full?
Neo
Read what I pasted: “If no messages are available at the socket, [problem you're experiencing]”. recvfrom is blocking/returning -1 because there's nothing for you to receive.
Peter Hosey
A: 

I was writing a UDP application and think I came across a similar issue. Peter Hosey is correct in stating that the given result of recvfrom means that there is no data to be read; but you were wondering, how can there be no data?

If you are sending several UDP datagrams at a time from some host to your iphone, some of those datagrams may be discarded because the receive buffer size (on the iphone) is not large enough to accommodate that much data at once.

The robust way to fix the problem is to implement a feature that allows your application to request a retransmission of missing datagrams. A not as robust solution (that doesn't solve all the issues that the robust solution does) is to simply increase the receive buffer size using setsockopt(2).

The buffer size adjustment can be done as follows:

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...
}

You may have to play around with buffer size to find what's optimal for your application.

Whisty