转自:http://hi.baidu.com/duan2834/item/5b9f877e1ce298580d0a07d6
使用CFNetwork框架
使用 TCP协议建立到服务器的连接,还有一种办法是使用CFNetwork框架,CFNetwork是核心服务框架(C库)中的一个框架,它为网络协议提供了抽象,如HTTP,FTP和BSD套接字。
为了弄清楚如何使用CFNetwork框架中的各种类,在 NetworkViewController.m文件中增加下面的代码:
1 #import "NetworkViewController.h"然后使用下面的代码定义connectToServerUsingCFStream:portNo::
1 -(void) connectToServerUsingCFStream:(NSString *) urlStr portNo: (uint) portNo {你第一次使用CFStreamCreatePairWithSocketToHost()方法创建一个可读写的流,通过TCP/IP连接到服务器,这个方法返回这个可读写流(readStream和writeStream)的引用,它们和Objective C中的NSInputStream和NSOutputStream是等效的。
发送数据
使用 NSOutputStream对象向服务器发送数据,如:
1 -(void) writeToServer:(const uint8_t *) buf {
2 [oStream write:buf maxLength:strlen((char*)buf)];
3 }
4
这个方法向服务器发送一 组无符号整数字节。
读取数据
从服务器接收数据时,将会触发stream:handleEvent:方法,因此可以使用这个方法接收所有入站数据,这个方法实现如下:
1 (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode {这个方法包括两个参数:一个是NSStream实例,一个是NSStreamEvent常量,NSStreamEvent常量可以是以下的值:
NSStreamEventNone:无事件发生。
NSStreamEventOpenCompleted:打开事件已经成功完成。
NSStreamEventHasBytesAvailable:已经读取的流字节数。
NSStreamEventHasSpaceAvailable:流接收的可写入的字节数。
NSStreamEventErrorOccurred:在流上发生了错误。
NSStreamEventEndEncountered:已经抵达流的结尾。
读取入站数据时,你应该检查 NSStreamEventHasBytesAvailable常量,在这个方法中,你可以读取入站数据流,然后UIAlertView对象显示接收到的数据。
stream:handleEvent:方法也是检查连接错误的一个好方法,例如,如果 connectToServerUsingStream:portNo:方法连接到服务器时失败了,错误将使用stream:handleEvent:方法通知,NSStreamEvent常量设置为NSStreamEventErrorOccurred。
断开连接
为了断开与服务器的连接,定义如下的断开方法:
-(void) disconnect {
[iStream close];
[oStream close];
}
然后将下面的代码添加到dealloc分发 中:
- (void)dealloc {
[self disconnect];
[iStream release];
[oStream release];
if (readStream) CFRelease(readStream);
if (writeStream) CFRelease(writeStream);
[super dealloc];
}
测试应用程序
现在可以将所有代码集合到一起进行测试了,在NetworkViewController.h文件中,声明下面的出口和行为:
#import
@interface NetworkViewController : UIViewController {
IBOutlet UITextField *txtMessage;
}
@property (nonatomic, retain) UITextField *txtMessage;
-(IBAction) btnSend: (id) sender;
@end
双击NetworkViewController.xib,在Interface Builder中打开编辑它,在View窗口中,使用下面的视图填充它,如图1所示。
l 文本区域(Text Field)
l 圆形按钮(Round Rect Button)
图 1 填充:使用视图填充View窗口
执行下面的操作
1、在File’s Owner上点击,将其拖到文本区域视图中,选择txtMessage。
2、选中圆形按钮视图,将其拖到File’s Owner上,选择btnSend。
在File’s Owner上点击右键,验证它的连接,如图2所示。
图 2 验证:验证File’s Owner上的连接
回到NetworkViewController.m文件,将下面的代码添加到 viewDidLoad方法中。
- (void)viewDidLoad {
[self connectToServerUsingStream:@"192.168.1.102" portNo:500];
//---OR---
//[self connectToServerUsingCFStream:@"192.168.1.102" portNo:500];
[super viewDidLoad];
}
上面的代码假设你正连接到一个ip地址为192.168.1.102的服务器的500端口上。btnSend:方法的代码如下:
-(IBAction) btnSend: (id) sender {
const uint8_t *str =
(uint8_t *) [txtMessage.text cStringUsingEncoding:NSASCIIStringEncoding];
[self writeToServer:str];
txtMessage.text = @"";
}
在dealloc方法中重新发布txtMessage出口。
- (void)dealloc {
[txtMessage release];
[self disconnect];
[iStream release];
[oStream release];
if (readStream) CFRelease(readStream);
if (writeStream) CFRelease(writeStream);
[super dealloc];
}
构建服务器
现在已经构建好一个可以在iPhone上运行的客户端,并已经可以通过它向服务器发送一些文本信息,但为了测试这个应用程序还需要一个服务端程序,我使用C#构建了一个非常简单的控制台服务器,下面是 Program.cs文件的代码。
1 using System;服务端程序执行下面的任 务:
l 它假设服务器的ip地址是192.168.1.102,在你的终端上测试时,请将这个ip地址替换为你运行这个服务端程序的计算机的ip地址。
l 它将接收到的所有数据返回给客户端。
l 一旦接收到数据,服务端不再监听入站数据,如果客户端要再次发生数据,需要重新连接到服务器。
在文本区域中输入一些文字,然后点击 Send按钮,如果连接成功,你将会看到Alert视图显示接收到数据。