NSOutputStream डेटा भेजने के समाप्त होने पर कनेक्शन बंद कैसे हो सकता है?एनएसओटपुटस्ट्रीम समाप्त होने पर कनेक्शन बंद करें
चारों ओर खोज करने के बाद मुझे पता चला है कि ईवेंट NSStreamEventEndEncountered
केवल तभी कॉल किया जाता है जब सर्वर कनेक्शन छोड़ देता है। अगर आउटपुटस्ट्रीम ने डेटा भेजने के लिए समाप्त नहीं किया है।
StreamStatus
हमेशा 0 (कनेक्शन बंद) या 2 (कनेक्शन खुला) लौटा रहा है लेकिन कभी नहीं 4 (डेटा लिखना)।
क्योंकि ऊपर वर्णित दोनों विधियां मुझे लिखने की प्रक्रिया के बारे में पर्याप्त नहीं बता रही हैं, मैं यह निर्धारित करने में सक्षम नहीं हूं कि स्ट्रीम अभी भी लिख रहा है या यदि यह समाप्त हो गया है और मैं अब कनेक्शन बंद कर सकता हूं।
Googleling के 5 दिनों के बाद और कोशिश कर रहा हूं कि मैं पूरी तरह से विचारों से बाहर हूं ... किसी भी मदद की सराहना की। धन्यवाद
संपादित जोड़ा कोड का अनुरोध किया के रूप में:
- (void)startSend:(NSString *)filePath
{
BOOL success;
NSURL * url;
assert(filePath != nil);
assert([[NSFileManager defaultManager] fileExistsAtPath:filePath]);
assert([filePath.pathExtension isEqual:@"png"] || [filePath.pathExtension isEqual:@"jpg"]);
assert(self.networkStream == nil); // don't tap send twice in a row!
assert(self.fileStream == nil); // ditto
// First get and check the URL.
...
....
.....
// If the URL is bogus, let the user know. Otherwise kick off the connection.
...
....
.....
if (! success) {
self.statusLabel.text = @"Invalid URL";
} else {
// Open a stream for the file we're going to send. We do not open this stream;
// NSURLConnection will do it for us.
self.fileStream = [NSInputStream inputStreamWithFileAtPath:filePath];
assert(self.fileStream != nil);
[self.fileStream open];
// Open a CFFTPStream for the URL.
self.networkStream = CFBridgingRelease(
CFWriteStreamCreateWithFTPURL(NULL, (__bridge CFURLRef) url)
);
assert(self.networkStream != nil);
if ([self.usernameText.text length] != 0) {
success = [self.networkStream setProperty:self.usernameText.text forKey:(id)kCFStreamPropertyFTPUserName];
assert(success);
success = [self.networkStream setProperty:self.passwordText.text forKey:(id)kCFStreamPropertyFTPPassword];
assert(success);
}
self.networkStream.delegate = self;
[self.networkStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
///////******** LINE ADDED BY ME TO DISONNECT FROM FTP AFTER CLOSING CONNECTION *********////////////
[self.networkStream setProperty:(id)kCFBooleanFalse forKey:(id)kCFStreamPropertyFTPAttemptPersistentConnection];
///////******** END LINE ADDED BY ME *********////////////
[self.networkStream open];
// Tell the UI we're sending.
[self sendDidStart];
}
}
- (void)stopSendWithStatus:(NSString *)statusString
{
if (self.networkStream != nil) {
[self.networkStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
self.networkStream.delegate = nil;
[self.networkStream close];
self.networkStream = nil;
}
if (self.fileStream != nil) {
[self.fileStream close];
self.fileStream = nil;
}
[self sendDidStopWithStatus:statusString];
}
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
// An NSStream delegate callback that's called when events happen on our
// network stream.
{
#pragma unused(aStream)
assert(aStream == self.networkStream);
switch (eventCode) {
case NSStreamEventOpenCompleted: {
[self updateStatus:@"Opened connection"];
} break;
case NSStreamEventHasBytesAvailable: {
assert(NO); // should never happen for the output stream
} break;
case NSStreamEventHasSpaceAvailable: {
[self updateStatus:@"Sending"];
// If we don't have any data buffered, go read the next chunk of data.
if (self.bufferOffset == self.bufferLimit) {
NSInteger bytesRead;
bytesRead = [self.fileStream read:self.buffer maxLength:kSendBufferSize];
if (bytesRead == -1) {
[self stopSendWithStatus:@"File read error"];
} else if (bytesRead == 0) {
[self stopSendWithStatus:nil];
} else {
self.bufferOffset = 0;
self.bufferLimit = bytesRead;
}
}
// If we're not out of data completely, send the next chunk.
if (self.bufferOffset != self.bufferLimit) {
NSInteger bytesWritten;
bytesWritten = [self.networkStream write:&self.buffer[self.bufferOffset] maxLength:self.bufferLimit - self.bufferOffset];
assert(bytesWritten != 0);
if (bytesWritten == -1) {
[self stopSendWithStatus:@"Network write error"];
} else {
self.bufferOffset += bytesWritten;
}
}
} break;
case NSStreamEventErrorOccurred: {
[self stopSendWithStatus:@"Stream open error"];
} break;
case NSStreamEventEndEncountered: {
// FOR WHATEVER REASON THIS IS NEVER CALLED!!!!
} break;
default: {
assert(NO);
} break;
}
}
हैलो! मेरी स्थिति यह है: इनपुटस्ट्रीम फ़ाइल को पढ़ता है, आउटपुटस्ट्रीम इसे एक FTP सर्वर पर लिखता है। जब इनपुटस्ट्रीम बफर में लिखना समाप्त हो जाता है, तो मैं teh कनेक्शन बंद करता हूं। लेकिन यह एक समस्या पैदा कर रहा है, क्योंकि जब मैं कनेक्शन बंद कर रहा हूं तो आउटपुट स्ट्रीम ने पूरे बफर को ftp पर नहीं लिखा था। तो मुझे यह जानना होगा कि आउटपुटस्ट्रीम ने लेखन समाप्त कर लिया है ताकि मैं फ़ाइल के अंत को बंद किए बिना कनेक्शन बंद कर सकूं। धन्यवाद! – sharkyenergy
समस्या तब नहीं है जब आप इनपुट स्ट्रीम बंद करते हैं लेकिन आप उस बफर को छोड़ देते हैं जिसमें आपने अपना डेटा पढ़ा है (इनपुट स्ट्रीम और बफर दो अलग-अलग ऑब्जेक्ट्स हैं)।यदि आपने इनपुट पढ़ना समाप्त कर लिया है तो आपने अपने डेटा को अपने बफर में कॉपी किया है, इसलिए इनपुट स्ट्रीम को बंद करना ठीक है। आउटपुट स्ट्रीम में लिखने के बाद केवल बफर को छोड़ दें। – aLevelOfIndirection
आउटपुट स्ट्रीम को बंद करने से समस्याएं उत्पन्न होती हैं। मुझे "tryPersistentConnection" को अक्षम करना पड़ा क्योंकि मैं कनेक्शन को लगातार खोल नहीं सकता था। इसलिए जब मैं फ़ाइल अपलोड करता हूं तो मुझे आउटपुटस्ट्रीम बंद करना होगा। समस्या यह नहीं है कि आउटपुटस्ट्रीम अपना काम पूरा कर लेता है। मुझे केवल तब पता है जब इनपुट स्ट्रीम समाप्त हो जाती है .. – sharkyenergy