[英]NSOutputStream always writes zero bytes
這里正是繼蘋果的文檔: https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Streams/Streams.html -我不能讓任何網絡NSOutputStream 永遠寫入數據。 它總是返回一個蘋果文檔似乎不應該返回的數字(0-蘋果聲稱這是針對固定大小的流,而不是網絡流?)。
Apple的所有示例代碼都忽略了返回代碼(似乎假定它是肯定的-我在網上找到的許多示例都使用無符號類型!這是非常錯誤的:()。
我已經成功:
...所有這些工作,通過遠程登錄到IP地址+端口來確認...
...但是隨后只需遵循Apple文檔,就會出現嚴重錯誤:
void handleConnect (
CFSocketRef s,
CFSocketCallBackType callbackType,
CFDataRef address,
const void *data,
void *info
)
{
NSLog(@"handleConnect called with callbackType = %li", callbackType);
(myclass) server = (myclass*) info;
BOOL canAccept = callbackType & kCFSocketAcceptCallBack;
BOOL canWrite = callbackType & kCFSocketWriteCallBack;
BOOL canRead = callbackType & kCFSocketReadCallBack;
NSLog(@" ... acceptable? %@ .. readable? %@ .. writeable? %@", canAccept?@"yes":@"no", canRead?@"yes":@"no", canWrite?@"yes":@"no" );
if( canAccept)
{
NSLog(@"[%@] Accepted a socket connection from remote host. Address = %@", [server class], addressString );
/**
"which means that a new connection has been accepted. In this case, the data parameter of the callback is a pointer to a CFSocketNativeHandle value (an integer socket number) representing the socket.
To handle the new incoming connections, you can use the CFStream, NSStream, or CFSocket APIs. The stream-based APIs are strongly recommended."
*/
// "1. Create read and write streams for the socket with the CFStreamCreatePairWithSocket function."
CFReadStreamRef clientInput = NULL;
CFWriteStreamRef clientOutput = NULL;
// for an AcceptCallBack, the data parameter is a pointer to a CFSocketNativeHandle
CFSocketNativeHandle nativeSocketHandle = *(CFSocketNativeHandle *)data;
CFStreamCreatePairWithSocket(kCFAllocatorDefault, nativeSocketHandle, &clientInput, &clientOutput);
// "2. Cast the streams to an NSInputStream object and an NSOutputStream object if you are working in Cocoa."
// "3. Use the streams as described in “Writing a TCP-Based Client.”
self.outputBuffer = [NSMutableData dataWithData:[@"Hello" dataWithEncoding:NSUTF8StringEncoding]];
self.outputBytesWrittenRecently = 0;
((NSOutputStream*)output).delegate = self;
[((NSOutputStream*)output) scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[((NSOutputStream*)output) open]; // MUST go last, undocumented Apple bug
}
}
...以及委托方法:
-(void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
BOOL streamOpened = eventCode & NSStreamEventOpenCompleted;
BOOL streamReadyToWrite = eventCode & NSStreamEventHasSpaceAvailable;
BOOL streamReadyToRead = eventCode & NSStreamEventHasBytesAvailable;
BOOL streamEnded = eventCode & NSStreamEventEndEncountered;
BOOL streamErrored = eventCode & NSStreamEventErrorOccurred;
if( streamReadyToWrite )
#define C_BUFFER_IN_MEMORY_SIZE_WRITE ( 4096 ) // Apple vaguely recommends 4k, but I tried numbers down to 100 with no effect
uint8_t extraCBufferNSStreamSucks[ C_BUFFER_IN_MEMORY_SIZE_WRITE ];
NSRange rangeOfBytesToAttemptToWriteNext = { self.outputBytesWrittenRecently, MIN( C_BUFFER_IN_MEMORY_SIZE_WRITE, self.outputBuffer.length - self.outputBytesWrittenRecently) };
[self.outputBuffer getBytes:&extraCBufferNSStreamSucks range:rangeOfBytesToAttemptToWriteNext];
NSLog(@"About to write data to stream, this might block...");
NSInteger amountWritten = [self.outputS write:extraCBufferNSStreamSucks maxLength:C_BUFFER_IN_MEMORY_SIZE_WRITE];
NSLog(@"...finished write data to stream, it might have blocked");
if( amountWritten > 0 )
{
self.outputBytesWrittenRecently += amountWritten;
NSRange totalWrittenRange = { 0, self.outputBytesWrittenRecently };
NSLog(@"Written %i bytes: %@", amountWritten, [[[NSString alloc] initWithData:[self.outputBuffer subdataWithRange:totalWrittenRange] encoding:NSUTF8StringEncoding] autorelease] );
if( self.outputBytesWrittenRecently == self.outputBuffer.length )
{
NSLog(@"Finished writing data!");
}
}
else
NSLog(@"ERROR: failed to write bytes to stream (bytes written = %i)", amountWritten);
}
啊! 沒有記錄,但是...如果您的NSStream實例變為nil,則Apple返回成功-而不是返回錯誤,但是對於寫入的字節數返回0。
就我而言,init方法中的錯字意味着我要用nil覆蓋剛捕獲的NSOutputStream和NSInputStream。
ARGH。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.