1

Essentially the problem that I am having is that my tcp/ip based server is randomly not receiving some of the packets I send. I'm sure that it's not actually random, but I have yet to figure out what is causing the issue. This exact code worked perfectly in the previous version of my app. Here is my code:

Initializing network connection:

- (void)initNetworkCommunication {
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    int randomPort = [self randomPort];

    CFStreamCreatePairWithSocketToHost(NULL,(__bridge CFStringRef)kSERVER_ADDRESS, randomPort, &readStream, &writeStream);
    inputStream = (__bridge NSInputStream *)readStream;
    outputStream = (__bridge NSOutputStream *)writeStream;

    [inputStream setDelegate:self];
    [outputStream setDelegate:self];

    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream open];
}

The function randomPort returns either 1244 or 1245 at random, which are port number references for the server. the constant kSERVER_ADDRESS is simply a string storing the server's address.

To send a packet I use this function:

- (void)sendPacket:(NSData *)packet {
    [self initNetworkCommunication];
    [outputStream write:[packet bytes] maxLength:[packet length]];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self performSelector:@selector(scheduleInThread:) onThread:[[self class] networkThread] withObject:nil waitUntilDone:YES];
    });
 }

Scheduling the input stream:

- (void)scheduleInThread:(id)sender {
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
    [inputStream open];
}

And handling network events:

- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode {
    BOOL shouldClose = NO;
    switch(eventCode) {
         case NSStreamEventHasBytesAvailable:
         {
             NSLog(@"bytes available");
             uint8_t *buffer = malloc(10000);
             NSInteger len = [inputStream read:buffer maxLength:10000];
             self.networkData = [[NSData alloc] initWithBytesNoCopy:buffer length:len];
             NSString *dataString = [[NSString alloc] initWithData:self.networkData encoding:NSUTF8StringEncoding];
             NSLog(@"%@", dataString);
             NSLog(@"length: %li", len);
             [self.delegate serverAgent:self didReceiveNetworkData:YES];
             break;
         }
        case NSStreamEventNone:
        {
            break;
        }
        case NSStreamEventHasSpaceAvailable:
        {
            break;
        } 
        case NSStreamEventEndEncountered:
        {
            shouldClose = YES;
            [self closeThread];
            break;
        }
        case NSStreamEventErrorOccurred:
        {
            isNetworkAvailable = NO;
            shouldClose = YES;
            [[NSNotificationCenter defaultCenter] postNotificationName:kNETWORK_UNAVAILABLE_NOTIFICATION object:nil];
            break;
        }
        case NSStreamEventOpenCompleted: {
            isNetworkAvailable = YES;
            [[NSNotificationCenter defaultCenter] postNotificationName:kNETWORK_AVAILABLE_NOTIFICATION object:nil];
            break;
        }
    }
    if(shouldClose) {
        [stream close];
    }
}

I have verified that about 70% of the time the server does not receive the packet, and about 30% of the time the server receives the packet and everything works perfectly. I have also verified that it is not an issue of the port number, both ports are working fine. Additionally, no network error is occurring.Sometimes the server receives the packet after a long delay (15-20s) and sometimes the packet isn't received at all. If anyone could shed some light onto this issue it would be much appreciated. I definitely am a novice when it comes to using the tcp/ip protocol with iOS. Thank you in advance.

angerboy
  • 495
  • 2
  • 5
  • 22

1 Answers1

0

Are you sure the packets are leaving your phone? you can use Charles (How to use Charles Proxy on the Xcode 6 (iOS 8) Simulator?) or Wireshark to find out the network activity leaving your app to make sure they are being sent to the server.

If the packets are definitely leaving the app, could it be a problem with your server? can you try a different server or test locally to try and find if the error lies with your app or server.

Community
  • 1
  • 1