objective-c 如何使用 NSOutputStream 的写消息?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/703729/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use NSOutputStream's write message?
提问by Chilly Zhong
I want to send a UIImage to a server through a socket.
我想通过套接字将 UIImage 发送到服务器。
a)I open the outputstream:
a)我打开输出流:
- (IBAction)send:(id)sender {
NSURL *website = [NSURL URLWithString:str_IP];
NSHost *host = [NSHost hostWithName:[website host]];
[NSStream getStreamsToHost:host port:1100 inputStream:nil outputStream:&oStream];
[oStream retain];
[oStream setDelegate:self];
[oStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[oStream open];
}
b) I write NSData to outputstream after open completed and handle the error if error occurs.
b) 打开完成后我将 NSData 写入 outputstream 并在发生错误时处理错误。
- (void) stream: (NSStream *) stream handleEvent: (NSStreamEvent) eventCode
{
//printf("EVENT: Start.\n");
switch(eventCode)
{
case NSStreamEventOpenCompleted:
{
//printf("EVENT: Open completed.\n");
if(stream == oStream)
{
//printf("Sending...\n");
NSData *data = UIImageJPEGRepresentation(drawImage.image, 90);
NSInteger x = [oStream write:[data bytes] maxLength:[data length]];
}
break;
}
case NSStreamEventEndEncountered:
{
//printf("EVENT: End encountered.\n");
break;
}
case NSStreamEventHasSpaceAvailable:
{
//printf("EVENT: Has space available.\n");
break;
}
case NSStreamEventHasBytesAvailable:
{
//printf("EVENT: Has bytes available.\n");
break;
}
case NSStreamEventErrorOccurred:
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error Occurred"
message:nil
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
break;
}
case NSStreamEventNone:
{
//printf("EVENT: None.\n");
break;
}
}
//printf("EVENT: End.\n");
}
When I run this code, NSStreamEventOpenCompleted and NSStreamEventErrorOccurred is called.The NSOutputStream's write method was called successfully and all the data is not nil. But after the data is written to the oStream, the eventCode will change to NSStreamEventErrorOccurred.
当我运行这段代码时,调用了 NSStreamEventOpenCompleted 和 NSStreamEventErrorOccurred。NSOutputStream 的 write 方法被调用成功,所有数据都不是 nil。但是数据写入oStream后,eventCode会变成NSStreamEventErrorOccurred。
So I think maybe it's not the correct way to use [oStream write]. What's the correct way to use this message then? I find this message returns an NSInteger of -1073748088, what might be the problem?
所以我认为这可能不是使用 [oStream write] 的正确方法。那么使用此消息的正确方法是什么?我发现此消息返回 -1073748088 的 NSInteger,可能是什么问题?
回答by Adam Rosenfield
You should be writing the data only after space becomes available in the output stream. When the stream finishes opening, it doesn't always immediately have space available, so writing to it won't work. If you move the writecall to the NSStreamEventHasSpaceAvailablehandler, it should succeed.
只有在输出流中有可用空间后,您才应该写入数据。当流完成打开时,它并不总是立即有可用空间,因此写入它不起作用。如果您将write调用移动到NSStreamEventHasSpaceAvailable处理程序,它应该会成功。
Also, the computer on the other end of the socket has no way of knowing the length of the data you're sending. Unless you're signaling the end-of-data by closing the socket, you should explicitly send the data length along with the data:
此外,套接字另一端的计算机无法知道您发送的数据的长度。除非您通过关闭套接字来表示数据结束,否则您应该显式地将数据长度与数据一起发送:
case NSStreamEventHasSpaceAvailable:
{
if(stream == oStream)
{
NSData *data = UIImageJPEGRepresentation(drawImage.image, 90);
// Convert from host to network endianness
uint32_t length = (uint32_t)htonl([data length]);
// Don't forget to check the return value of 'write'
[oStream write:(uint8_t *)&length maxLength:4];
[oStream write:[data bytes] maxLength:length];
}
break;
}

