2015-11-13 9 views
7

संवाद नहीं कर सकता है मुझे बोनजोर के साथ उद्देश्य सी में एक टीसीपी सर्वर/क्लाइंट के विकास के साथ कोई समस्या है।आईओएस एनएसएसटीम टीसीपी सर्वर क्लाइंट

सर्वर की तरफ मैं सही ढंग से स्ट्रीम खोलता हूं और मैं डेटा भेजने और प्राप्त करने के लिए हैंडलएवेंट फ़ंक्शन का उपयोग करता हूं। लेकिन मुझे नहीं पता कि डेटा भेजने और प्राप्त करने का सही तरीका क्या है। मैं इस उत्कृष्ट पोस्ट पढ़ें: Correct way to send data through a socket with NSOutputStream तो मैं एक पैकेट पंक्तिबद्ध प्रणाली का उपयोग डेटा भेजने के लिए:

switch(eventCode) { 

    case NSStreamEventOpenCompleted: { 
     NSLog(@"Complete"); 

    } break; 

    case NSStreamEventHasSpaceAvailable: { 
     if (stream == _outputStream) 
      [self _sendData]; 
    } break; 

...

- (void)_sendData { 
flag_canSendDirectly = NO; 
NSData *data = [_dataWriteQueue lastObject]; 
if (data == nil) { 
    flag_canSendDirectly = YES; 
    return; 
} 
uint8_t *readBytes = (uint8_t *)[data bytes]; 
readBytes += currentDataOffset; 
NSUInteger dataLength = [data length]; 
NSUInteger lengthOfDataToWrite = (dataLength - currentDataOffset >= 1024) ? 1024 : (dataLength - currentDataOffset); 
NSInteger bytesWritten = [_outputStream write:readBytes maxLength:lengthOfDataToWrite]; 
currentDataOffset += bytesWritten; 
if (bytesWritten > 0) { 
    self.currentDataOffset += bytesWritten; 
    if (self.currentDataOffset == dataLength) { 
     [self.dataWriteQueue removeLastObject]; 
     self.currentDataOffset = 0; 
    } 
} 

}

। तो मूल रूप से मैं अपने पैकेट को कई पैकेट पर अलग भेजता हूं। लेकिन मुझे नहीं लगता कि क्लाइंट साइड पर डेटा का पुनर्निर्माण कैसे करें। और मुझे लगता है कि मैंने NSStreamEventHasBytesAvailable ईवेंट को सही ढंग से नहीं समझा। क्योंकि यहां मैं कई पैकेट भेजता हूं लेकिन क्लाइंट पक्ष पर यह घटना केवल एक बार कॉल होती है। और जब मैं बफर से डेटा का पुनर्निर्माण करता हूं तो डेटा दूषित हो जाता है। अगर कोई इस सब को स्पष्ट कर सकता है तो मैं वास्तव में सराहना करता हूं, दस्तावेज इस बिंदु पर वास्तव में स्पष्ट नहीं है (या शायद मुझे एक बिंदु याद आती है ..)।

 case NSStreamEventHasBytesAvailable: { 
     if (stream == _inputStream) 
     { 
      //read data 
      uint8_t buffer[1024]; 
      int len; 
      while ([_inputStream hasBytesAvailable]) 
      { 
       len = [_inputStream read:buffer maxLength:sizeof(buffer)]; 
       if (len > 0) 
       { 
        NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSUTF8StringEncoding]; 
        //NSData *theData = [[NSData alloc] initWithBytes:buffer length:len]; 
        UnitySendMessage("AppleBonjour_UnityNetworkManager(Clone)", "OnLocalClientReceiveMessageFromServer", [output cStringUsingEncoding:NSUTF8StringEncoding]); 
       } 
      } 
     } 
+0

क्या आपने एक सरल परीक्षण की कोशिश की है? एक छोटी सी छोटी स्ट्रिंग भेजें। जब आप ऐसा करते हैं तो आप अपने चर "आउटपुट" में क्या प्राप्त करते हैं? fwiw; प्रत्येक प्रेषण के लिए उपलब्ध बाइट्स की एक भी कॉल नहीं होनी चाहिए, अगर वे समय पर पहुंच जाएंगे तो उन्हें जोड़ा जाएगा और एक पठन उन्हें सब कुछ मिलेगा। कृपया इस परीक्षा को आजमाएं और हमें बताएं कि आपको क्या मिलता है। –

+0

ओह, मैं एक और चीज़ भूल गया; आप रिसीवर को टेलनेट जैसे सरल टीसीपी प्रोग्राम के साथ परीक्षण कर सकते हैं। बस अपने बंदरगाह से कनेक्ट करें और कुछ पाठ टाइप करें। यदि रिसीवर कोड काम कर रहा है तो आपको अपना टेक्स्ट सीधे प्राप्त करना चाहिए। –

+0

ठीक है एक साधारण स्ट्रिंग काम किया। इसलिए यदि मैं बफर से बड़ा स्ट्रिंग भेजता हूं, तो मुझे हर बार NSStreamEventHasBytesAvailable कहलाता है, इसे पुनर्निर्माण करना होगा। लेकिन जब स्ट्रिंग पूरी तरह से भेजी गई है तो मुझे एक अधिसूचना कैसे मिल सकती है? – thegrandwaazoo

उत्तर

3

ऐसा लगता है, कि तुम दो चर currentDataOffset का उपयोग करें - एक उदाहरण चर और एक संपत्ति - एक ही उद्देश्य के लिए। यदि आपको वास्तव में दोनों की आवश्यकता है, तो आपको 0currentDataOffset पर भी सेट करना चाहिए। लेकिन मुझे लगता है कि टुकड़ा इस तरह दिखना चाहिए:

readBytes += currentDataOffset; 
NSUInteger dataLength = [data length]; 
NSUInteger lengthOfDataToWrite = MIN(dataLength - currentDataOffset, 1024); 
NSInteger bytesWritten = [_outputStream write:readBytes maxLength:lengthOfDataToWrite]; 
if (bytesWritten > 0) { 
    currentDataOffset += bytesWritten; 
    if (currentDataOffset == dataLength) { 
     [self.dataWriteQueue removeLastObject]; 
     currentDataOffset = 0; 
    } 
} 
संबंधित मुद्दे