5

के लिए नागल के एल्गोरिदम को अक्षम करें मैं MPCF का उपयोग कर एक मल्टीप्लेयर गेम बना रहा हूं। आप आईफोन का उपयोग कर आईपैड पर एक स्पेसशिप को नियंत्रित करते हैं।NSOutputStream

मैं अंतराल और विलंबता और बफरिंग के विभिन्न राशि का सामना कर रहा हूँ/यादृच्छिक बार और अंतराल पर रुक जाता है और अब Technical Q&A NW26 कागज कि Nagle एल्गोरिथ्म अक्षम बारे में बात करती सेब पर पहुँचे हैं। मैं इसे आज़मा रहा हूं लेकिन मेरा प्रोग्राम दुर्घटनाग्रस्त रहता है और मुझे समझ में नहीं आता क्यों। ऐसा लगता है कि CFWriteStreamCopyProperty हमेशा वापस लौटता है।

- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode 
{ 
    switch (eventCode) { 
     case NSStreamEventOpenCompleted: 

      // Trying to get a handle to the native socket 
      CFSocketNativeHandle rawsock; 

      // This always return NULL 
      CFDataRef socketData = CFWriteStreamCopyProperty((__bridge CFWriteStreamRef)(stream), kCFStreamPropertySocketNativeHandle); 

      // And this row always crash (coz of socketData being NULL i guess) 
      CFDataGetBytes(socketData, CFRangeMake(0, sizeof(CFSocketNativeHandle)), (UInt8 *)&rawsock); 
      CFRelease(socketData); 

      // Code example from Apple that need a handle to the native socket, that I am trying to get above 
      int err; 
      static const int kOne = 1; 
      err = setsockopt(rawsock, IPPROTO_TCP, TCP_NODELAY, &kOne, sizeof(kOne)); 
      if (err < 0) {  
       err = errno; 
      } 

      break; 

     default: 
      break; 
    } 
} 

किसी भी मदद की सराहना की जाती है।

+0

क्या आपको कभी इसके लिए समाधान मिला? मैं विलंबता को कम करने की कोशिश कर रहा हूं और ' प्रेषणडेटा: toPeers: withMode: त्रुटि:' 'MCSessionSendDataUnreliable'' के साथ, इसलिए मैं पैकेट नुकसान से निपटने से बच सकता हूं ... – jou

+0

नहीं, क्षमा करें। ब्लूटूथ LE पर स्विच किया गया। – bobmoff

+0

बहुत बुरा ... आपकी प्रतिक्रिया के लिए धन्यवाद। – jou

उत्तर

5

आपको लगता है कि stream एक NSOutputStream है, लेकिन NSInputStream भी पारित किया जा सकता है। तो यह उस रेखा पर दुर्घटनाग्रस्त हो जाता है।

यहाँ एक नमूना कोड है कि दोनों स्थितियों को संभाल सकता है और एक दुर्घटना को ठीक करता:

- (void)disableNaglesAlgorithmForStream:(NSStream *)stream { 

    CFDataRef socketData; 

    // Get socket data 
    if ([stream isKindOfClass:[NSOutputStream class]]) { 
     socketData = CFWriteStreamCopyProperty((__bridge CFWriteStreamRef)((NSOutputStream *)stream), kCFStreamPropertySocketNativeHandle); 
    } else if ([stream isKindOfClass:[NSInputStream class]]) { 
     socketData = CFReadStreamCopyProperty((__bridge CFReadStreamRef)((NSInputStream *)stream), kCFStreamPropertySocketNativeHandle); 
    } 

    // get a handle to the native socket 
    CFSocketNativeHandle rawsock; 

    CFDataGetBytes(socketData, CFRangeMake(0, sizeof(CFSocketNativeHandle)), (UInt8 *)&rawsock); 
    CFRelease(socketData); 

    // Disable Nagle's algorythm 

    // Debug info 
    BOOL isInput = [stream isKindOfClass:[NSInputStream class]]; 
    NSString * streamType = isInput ? @"INPUT" : @"OUTPUT"; 

    int err; 
    static const int kOne = 1; 
    err = setsockopt(rawsock, IPPROTO_TCP, TCP_NODELAY, &kOne, sizeof(kOne)); 
    if (err < 0) { 
     err = errno; 
     NSLog(@"Could Not Disable Nagle for %@ stream", streamType); 
    } else { 
     NSLog(@"Nagle Is Disabled for %@ stream", streamType); 
    } 
} 

यह case NSStreamEventOpenCompleted:

में सही बुलाया जाना चाहिए किसी को भी सोच रहा जब प्रतिलिपि चिपकाया कारण है कि यह संकलन नहीं करता :

#import <arpa/inet.h>  // for IPPROTO_TCP 
#include <netinet/tcp.h> // for TCP_NODELAY 

हालांकि, यह समय-समय पर विलंबता मुद्दों के साथ मदद नहीं करता है। मैं अभी भी इसे रोकने के लिए एक रास्ता खोज रहा हूं।

मैं एक साधारण वीडियो कि इस मुद्दे को दर्शाता है दर्ज की गई और मेरा मानना ​​है कि आप एक ही एक का सामना कर रहे: https://www.dropbox.com/s/omdqkbckph4b1y2/Multipeer%20Connectivity.mov?dl=0

संपादित करें: मैं एक समय-समय पर विलंबता समस्याओं को ठीक करने के लिए एक रास्ता खोजने के लिए सक्षम था। यह एक MCNearbyServiceAdvertiser है जो मुद्दों का कारण बनता है। आपको झंडे से छुटकारा पाने के लिए एक सहकर्मी विज्ञापन को रोकने की आवश्यकता है: कनेक्शन के सफल होने के तुरंत बाद MCNearbyServiceAdvertiser उदाहरण पर stopAdvertisingPeer विधि को कॉल करें।

MCNearbyServiceAdvertiser *nearbyServiceAdvertiser; 

- (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state { 

    switch (state) { 

     case MCSessionStateConnected: { 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       [self.nearbyServiceAdvertiser stopAdvertisingPeer]; 
      }); 
     ... 
    } 
    ... 
} 

लेकिन देरी केवल 30 सेकंड के बाद बंद हो जाएगा। मुझे नहीं पता कि इसे तुरंत गायब कैसे किया जाए।

+0

ग्रेट उत्तर, मुझे अपने ऐप में एक ही समस्या थी जिससे मैं हर दूसरे कई छोटे पैकेट भेज रहा था। इस जवाब पर ठोकर खाई और ऐसा लगता है कि मेरी समस्या ठीक हो गई है। – mhorgan

संबंधित मुद्दे