iOS 8 - 服务器 'randomly' 未接收到使用 tcp/ip 协议(protocol)发送的数据包

标签 ios objective-c tcp ios8

本质上,我遇到的问题是我的基于 tcp/ip 的服务器随机地没有收到我发送的一些数据包。我确定它实际上不是随机的,但我还没有弄清楚是什么导致了这个问题。这个确切的代码在我的应用程序的以前版本中完美运行。这是我的代码:

初始化网络连接:

- (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];
}

randomPort 函数随机返回 1244 或 1245,这是服务器的端口号引用。常量 kSERVER_ADDRESS 只是一个存储服务器地址的字符串。

要发送一个数据包,我使用这个函数:

- (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];
    });
 }

调度输入流:

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

并处理网络事件:

- (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];
    }
}

我已经验证了大约 70% 的时间服务器没有收到数据包,大约 30% 的时间服务器收到了数据包并且一切正常。我还验证了这不是端口号的问题,两个端口都工作正常。此外,没有发生网络错误。有时服务器会在很长的延迟(15-20 秒)后收到数据包,有时甚至根本没有收到数据包。如果有人能阐明这个问题,将不胜感激。在 iOS 中使用 tcp/ip 协议(protocol)时,我绝对是新手。先感谢您。

最佳答案

您确定数据包正在离开您的手机吗?您可以使用 Charles (How to use Charles Proxy on the Xcode 6 (iOS 8) Simulator?) 或 Wireshark 找出离开您的应用程序的网络事件,以确保它们被发送到服务器。

如果数据包肯定会离开应用程序,可能是您的服务器有问题吗?您可以尝试使用不同的服务器还是在本地进行测试以尝试找出错误是否出自您的应用程序或服务器。

关于iOS 8 - 服务器 'randomly' 未接收到使用 tcp/ip 协议(protocol)发送的数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27737459/

相关文章:

ios - Xcode 6.3(和 6.2)在 [UIFont fontWithName : size:] 上命中断点

iphone - reloadData 只刷新一行

objective-c - 用作全局变量的 AppDelegate 变量不起作用

ios - 返回 UITableViewController 时关闭 UIWebView

ios - 尝试使用 HealthKit 获取步数,但它总是返回 0.0

ios - 在 iOS 6 MKMapView 上显示公交站、餐馆和其他地方

iphone - uitableview 在滚动到顶部时自动更新

c# - TCP 接收后绑定(bind)数据

c# - 当数据以 '1c' 开头时,TCP 数据包不会从俄罗斯到达加拿大

c - TCP 连接错误 "No buffer space available"