转载自:http://tech.it168.com/a2009/1229/830/000000830741.shtml
使用网络通信流
使用套接字在网络上通信最简单的方法是使用NSStream类,NSStream类是一个表示流的抽象类,你可以使用它读写数据,它可以用在内存、文件或网络上。使用NSStream类,你可以向服务器写数据,也可以从服务器读取数据。
在Mac OS X上,可以使用NSHost和NSStream对象建立到服务器的连接,如:
1 NSInputStream *iStream;
2 NSOutputStream *oStream;
3 uint portNo = 500;
4 NSURL *website = [NSURL URLWithString:urlStr];
5 NSHost *host = [NSHost hostWithName:[website host]];
6 [NSStream getStreamsToHost:host
7 port:portNo
8 inputStream:&iStream
9 outputStream:&oStream];
NSStream类有一个方法getStreamsToHost:port:inputStream:outputStream:,它创建一个到服务器的输入和输出流,但问题是iPhone OS不支持getStreamsToHost:port:inputStream:outputStream:方法,因此上面的代码在iPhone应用程序中是不能运行的。
为了解决这个问题,你可以增加一个类别到现有的NSStream类上,替换getStreamsToHost:port:inputStream:outputStream:方法提供的功能。在Xcode的Classes上点击右键,添加一个文件NSStreamAdditions.m,在NSStreamAdditions.h文件中,增加下面的代码:
1 #import
2 @interface NSStream (MyAdditions)
3 + (void)getStreamsToHostNamed:(NSString *)hostName
4 port:(NSInteger)port
5 inputStream:(NSInputStream **)inputStreamPtr
6 outputStream:(NSOutputStream **)outputStreamPtr;
7 @end
在NSStreamAdditions文件中加入以下代码:
1 #import "NSStreamAdditions.h"
2 @implementation NSStream (MyAdditions)
3 + (void)getStreamsToHostNamed:(NSString *)hostName
4 port:(NSInteger)port
5 inputStream:(NSInputStream **)inputStreamPtr
6 outputStream:(NSOutputStream **)outputStreamPtr
7 {
8 CFReadStreamRef readStream;
9 CFWriteStreamRef writeStream;
10 assert(hostName != nil);
11 assert( (port > 0) && (port < 65536) );
12 assert( (inputStreamPtr != NULL) || (outputStreamPtr != NULL) );
13 readStream = NULL;
14 writeStream = NULL;
15 CFStreamCreatePairWithSocketToHost(
16 NULL,
17 (CFStringRef) hostName,
18 port,
19 ((inputStreamPtr != nil) ? &readStream : NULL),
20 ((outputStreamPtr != nil) ? &writeStream : NULL)
21 );
22 if (inputStreamPtr != NULL) {
23 *inputStreamPtr = [NSMakeCollectable(readStream) autorelease];
24 }
25 if (outputStreamPtr != NULL) {
26 *outputStreamPtr = [NSMakeCollectable(writeStream) autorelease];
27 }
28 }
29 @end
上面的代码为NSStream类增加了一个 getStreamsToHostNamed:port:inputStream:outputStream:方法,现在你可以在你的iPhone应用程序中使用这个方法,使用TCP协议连接到服务器。
在NetworkViewController.m文件中,插入下面的代码:
1 #import "NetworkViewController.h"
2 #import "NSStreamAdditions.h"
3 @implementation NetworkViewController
4 NSMutableData *data;
5 NSInputStream *iStream;
6 NSOutputStream *oStream;
定义connectToServerUsingStream:portNo:方法,以便连接到服务器,然后创建输入和输出流对象:
-(void) connectToServerUsingStream:(NSString *)urlStr
portNo: (uint) portNo {
if (![urlStr isEqualToString:@""]) {
NSURL *website = [NSURL URLWithString:urlStr];
if (!website) {
NSLog(@"%@ is not a valid URL");
return;
} else {
[NSStream getStreamsToHostNamed:urlStr
port:portNo
inputStream:&iStream
outputStream:&oStream];
[iStream retain];
[oStream retain];
[iStream setDelegate:self];
[oStream setDelegate:self];
[iStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[oStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[oStream open];
[iStream open];
}
}
}
在一个运行循环中,你可以调度输入和输出流接收事件,这样可以避免阻塞。