iOS 网络编程实践--NSStream实现TCP Socket iPhone客户端 .
来源:互联网 发布:国外数据可视化公司 编辑:程序博客网 时间:2024/05/16 12:08
客户端我们使用iPhone应用程序,画面比较简单。点击发送按钮,给服务器发送一些字符串过去。点击接收按钮就会从服务器读取一些字符串,并且显示在画面上。
有关客户端应用的UI部分不再介绍了,我们直接看代码部分,Socket客户端可以采用CFStream或NSStream实现。为了给读者介绍更多的知识,本例我们采用NSStream实现。NSStream实现采用Objective-C语言,一些面向对象的类。
下面我们看看客户端视图控制器ViewController.h
- #import <CoreFoundation/CoreFoundation.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #define PORT 9000
- @interface ViewController : UIViewController<NSStreamDelegate>
- {
- int flag ; //操作标志 0为发送 1为接收
- }
- @property (nonatomic, retain) NSInputStream *inputStream;
- @property (nonatomic, retain) NSOutputStream *outputStream;
- @property (weak, nonatomic) IBOutlet UILabel *message;
- - (IBAction)sendData:(id)sender;
- - (IBAction)receiveData:(id)sender;
- @end
- #import <CoreFoundation/CoreFoundation.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #define PORT 9000
- @interface ViewController : UIViewController<NSStreamDelegate>
- {
- int flag ; //操作标志 0为发送 1为接收
- }
- @property (nonatomic, retain) NSInputStream *inputStream;
- @property (nonatomic, retain) NSOutputStream *outputStream;
- @property (weak, nonatomic) IBOutlet UILabel *message;
- - (IBAction)sendData:(id)sender;
- - (IBAction)receiveData:(id)sender;
- @end
#import <CoreFoundation/CoreFoundation.h>#include <sys/socket.h>#include <netinet/in.h> #define PORT 9000 @interface ViewController : UIViewController<NSStreamDelegate>{int flag ; //操作标志 0为发送 1为接收} @property (nonatomic, retain) NSInputStream *inputStream;@property (nonatomic, retain) NSOutputStream *outputStream; @property (weak, nonatomic) IBOutlet UILabel *message; - (IBAction)sendData:(id)sender;- (IBAction)receiveData:(id)sender; @end
定义属性inputStream和outputStream,它们输入流NSInputStream和输出流NSOutputStream类。它们与服务器CFStream实现中的输入流CFReadStreamRef和输出流CFWriteStreamRef对应的。
视图控制器ViewController.m的初始化网络方法initNetworkCommunication代码:
- - (void)initNetworkCommunication
- {
- CFReadStreamRef readStream;
- CFWriteStreamRef writeStream;
- CFStreamCreatePairWithSocketToHost(NULL,
- (CFStringRef)@”192.168.1.103″, PORT, &readStream, &writeStream); ①
- _inputStream = (__bridge_transfer NSInputStream *)readStream; ②
- _outputStream = (__bridge_transfer NSOutputStream*)writeStream; ③
- [_inputStream setDelegate:self]; ④
- [_outputStream setDelegate:self]; ⑤
- [_inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
- forMode:NSDefaultRunLoopMode]; ⑥
- [_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
- forMode:NSDefaultRunLoopMode]; ⑦
- [_inputStream open]; ⑧
- [_outputStream open]; ⑨
- }
- 点击发送和接收按钮触发的方法如下:
- /* 点击发送按钮 */
- - (IBAction)sendData:(id)sender {
- flag = 0;
- [self initNetworkCommunication];
- }
- /* 点击接收按钮 */
- - (IBAction)receiveData:(id)sender {
- flag = 1;
- [self initNetworkCommunication];
- }
- - (void)initNetworkCommunication
- {
- CFReadStreamRef readStream;
- CFWriteStreamRef writeStream;
- CFStreamCreatePairWithSocketToHost(NULL,
- (CFStringRef)@”192.168.1.103″, PORT, &readStream, &writeStream); ①
- _inputStream = (__bridge_transfer NSInputStream *)readStream; ②
- _outputStream = (__bridge_transfer NSOutputStream*)writeStream; ③
- [_inputStream setDelegate:self]; ④
- [_outputStream setDelegate:self]; ⑤
- [_inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
- forMode:NSDefaultRunLoopMode]; ⑥
- [_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
- forMode:NSDefaultRunLoopMode]; ⑦
- [_inputStream open]; ⑧
- [_outputStream open]; ⑨
- }
- 点击发送和接收按钮触发的方法如下:
- /* 点击发送按钮 */
- - (IBAction)sendData:(id)sender {
- flag = 0;
- [self initNetworkCommunication];
- }
- /* 点击接收按钮 */
- - (IBAction)receiveData:(id)sender {
- flag = 1;
- [self initNetworkCommunication];
- }
- (void)initNetworkCommunication{CFReadStreamRef readStream;CFWriteStreamRef writeStream;CFStreamCreatePairWithSocketToHost(NULL,(CFStringRef)@”192.168.1.103″, PORT, &readStream, &writeStream); ①_inputStream = (__bridge_transfer NSInputStream *)readStream; ②_outputStream = (__bridge_transfer NSOutputStream*)writeStream; ③[_inputStream setDelegate:self]; ④[_outputStream setDelegate:self]; ⑤[_inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]forMode:NSDefaultRunLoopMode]; ⑥[_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]forMode:NSDefaultRunLoopMode]; ⑦[_inputStream open]; ⑧[_outputStream open]; ⑨}点击发送和接收按钮触发的方法如下:/* 点击发送按钮 */- (IBAction)sendData:(id)sender {flag = 0;[self initNetworkCommunication];}/* 点击接收按钮 */- (IBAction)receiveData:(id)sender {flag = 1;[self initNetworkCommunication];}
它们都调用initNetworkCommunication方法,并设置操作标识flag,如果flag为0发送数据,flag为1接收数据。
流的状态的变化触发很多事件,并回调NSStreamDelegate协议中定义的方法stream:handleEvent:,其代码如下:
- -(void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {
- NSString *event;
- switch (streamEvent) {
- case NSStreamEventNone:
- event = @”NSStreamEventNone”;
- break;
- case NSStreamEventOpenCompleted:
- event = @”NSStreamEventOpenCompleted”;
- break;
- case NSStreamEventHasBytesAvailable:
- event = @”NSStreamEventHasBytesAvailable”;
- if (flag ==1 && theStream == _inputStream) {
- NSMutableData *input = [[NSMutableData alloc] init];
- uint8_t buffer[1024]; ①
- int len;
- while([_inputStream hasBytesAvailable]) ②
- {
- len = [_inputStream read:buffer maxLength:sizeof(buffer)]; ③
- if (len > 0)
- {
- [input appendBytes:buffer length:len];
- }
- }
- NSString *resultstring = [[NSString alloc]
- initWithData:input encoding:NSUTF8StringEncoding];
- NSLog(@”接收:%@”,resultstring);
- _message.text = resultstring;
- }
- break;
- case NSStreamEventHasSpaceAvailable:
- event = @”NSStreamEventHasSpaceAvailable”;
- if (flag ==0 && theStream == _outputStream) {
- //输出
- UInt8 buff[] = ”Hello Server!”; ④
- [_outputStream write:buff maxLength: strlen((const char*)buff)+1]; ⑤
- //关闭输出流
- [_outputStream close];
- }
- break;
- case NSStreamEventErrorOccurred:
- event = @”NSStreamEventErrorOccurred”;
- [self close]; ⑥
- break;
- case NSStreamEventEndEncountered:
- event = @”NSStreamEventEndEncountered”;
- NSLog(@”Error:%d:%@”,[[theStream streamError] code],
- [[theStream streamError] localizedDescription]);
- break;
- default:
- [self close]; ⑦
- event = @”Unknown”;
- break;
- }
- NSLog(@”event——%@”,event);
- }
- -(void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {
- NSString *event;
- switch (streamEvent) {
- case NSStreamEventNone:
- event = @”NSStreamEventNone”;
- break;
- case NSStreamEventOpenCompleted:
- event = @”NSStreamEventOpenCompleted”;
- break;
- case NSStreamEventHasBytesAvailable:
- event = @”NSStreamEventHasBytesAvailable”;
- if (flag ==1 && theStream == _inputStream) {
- NSMutableData *input = [[NSMutableData alloc] init];
- uint8_t buffer[1024]; ①
- int len;
- while([_inputStream hasBytesAvailable]) ②
- {
- len = [_inputStream read:buffer maxLength:sizeof(buffer)]; ③
- if (len > 0)
- {
- [input appendBytes:buffer length:len];
- }
- }
- NSString *resultstring = [[NSString alloc]
- initWithData:input encoding:NSUTF8StringEncoding];
- NSLog(@”接收:%@”,resultstring);
- _message.text = resultstring;
- }
- break;
- case NSStreamEventHasSpaceAvailable:
- event = @”NSStreamEventHasSpaceAvailable”;
- if (flag ==0 && theStream == _outputStream) {
- //输出
- UInt8 buff[] = ”Hello Server!”; ④
- [_outputStream write:buff maxLength: strlen((const char*)buff)+1]; ⑤
- //关闭输出流
- [_outputStream close];
- }
- break;
- case NSStreamEventErrorOccurred:
- event = @”NSStreamEventErrorOccurred”;
- [self close]; ⑥
- break;
- case NSStreamEventEndEncountered:
- event = @”NSStreamEventEndEncountered”;
- NSLog(@”Error:%d:%@”,[[theStream streamError] code],
- [[theStream streamError] localizedDescription]);
- break;
- default:
- [self close]; ⑦
- event = @”Unknown”;
- break;
- }
- NSLog(@”event——%@”,event);
- }
-(void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {NSString *event;switch (streamEvent) {case NSStreamEventNone:event = @”NSStreamEventNone”;break;case NSStreamEventOpenCompleted:event = @”NSStreamEventOpenCompleted”;break;case NSStreamEventHasBytesAvailable:event = @”NSStreamEventHasBytesAvailable”;if (flag ==1 && theStream == _inputStream) {NSMutableData *input = [[NSMutableData alloc] init];uint8_t buffer[1024]; ①int len;while([_inputStream hasBytesAvailable]) ②{len = [_inputStream read:buffer maxLength:sizeof(buffer)]; ③if (len > 0){[input appendBytes:buffer length:len];}}NSString *resultstring = [[NSString alloc]initWithData:input encoding:NSUTF8StringEncoding];NSLog(@”接收:%@”,resultstring);_message.text = resultstring;}break;case NSStreamEventHasSpaceAvailable:event = @”NSStreamEventHasSpaceAvailable”;if (flag ==0 && theStream == _outputStream) {//输出UInt8 buff[] = ”Hello Server!”; ④[_outputStream write:buff maxLength: strlen((const char*)buff)+1]; ⑤//关闭输出流[_outputStream close];}break;case NSStreamEventErrorOccurred:event = @”NSStreamEventErrorOccurred”;[self close]; ⑥break;case NSStreamEventEndEncountered:event = @”NSStreamEventEndEncountered”;NSLog(@”Error:%d:%@”,[[theStream streamError] code],[[theStream streamError] localizedDescription]);break;default:[self close]; ⑦event = @”Unknown”;break;}NSLog(@”event——%@”,event);}
在读取数据分支(NSStreamEventHasBytesAvailable)中,代码第①行为读取数据准备缓冲区,本例中设置的是1024个字节,这个大小会对流的读取有很多的影响。第②行代码使用hasBytesAvailable方法判断是否流有数据可以读,如果有可读数据就进行循环读取。第③行代码使用流的read:maxLength:方法读取数据到缓冲区,第1个参数是缓冲区对象buffer,第2个参数是读取的缓冲区的字节长度。
在写入数据分支(NSStreamEventHasSpaceAvailable)中,代码第④行是要写入的数据,第⑤行代码[_outputStream write:buff maxLength: strlen((const char*)buff)+1]是写如数据方法。
第⑥和第⑦行代码[self close]调用close方法关闭,close方法代码如下:
- -(void)close
- {
- [_outputStream close];
- [_outputStream removeFromRunLoop:[NSRunLoop currentRunLoop]
- forMode:NSDefaultRunLoopMode];
- [_outputStream setDelegate:nil];
- [_inputStream close];
- [_inputStream removeFromRunLoop:[NSRunLoop currentRunLoop]
- forMode:NSDefaultRunLoopMode];
- [_inputStream setDelegate:nil];
- }
- iOS网络编程实践--NSStream实现TCP Socket iPhone客户端
- iOS 网络编程实践--NSStream实现TCP Socket iPhone客户端
- iOS 网络编程实践--NSStream实现TCP Socket iPhone客户端 .
- iOS网络编程实践--NSStream实现TCP Socket iPhone客户端
- iOS网络编程实践--NSStream实现TCP Socket iPhone客户端
- iOS网络编程实践--NSStream实现TCP Socket iPhone客户端
- iOS网络编程实践--NSStream实现TCP Socket iPhone客户端
- iOS网络编程实践--NSStream实现TCP Socket iPhone客户端
- iOS网络编程实践--NSStream实现TCP Socket iPhone客户端
- iOS网络编程实践--NSStream实现TCP Socket iPhone客户端
- iOS网络编程实践--NSStream实现TCP Socket iPhone客户端
- iOS网络编程实践–NSStream实现TCP Socket iPhone客户端
- iOS网络编程实践–NSStream实现TCP Socket iPhone客户端
- iOS NSStream TCP Socket iPhone 客户端实现效果
- iOS网络编程之NSStream
- iOS网络编程之NSStream
- iOS网络编程之NSStream
- iOS网络编程之NSStream
- UITableView底部FooterView实现上拉刷新
- WINCE 给命令条添加按钮和加载图片
- Uploadify 配置错误信息提示
- Colorization, Gray, Color-to-Gray, Color Models
- SDL学习笔记三(文字的显示)
- iOS 网络编程实践--NSStream实现TCP Socket iPhone客户端 .
- poj 2524
- wince 静态文本框字体和颜色、背景色的动态更改
- UIResponder UITouch
- jsp的request及增进研究【1】--资料准备
- 在窗体上放置一个菜单、一个工具栏控件,工具栏上有两个按钮,分别对应“打开文本文件”、“保存文本文件”
- DP(7)Post Office 1160
- WINCE 检测SD卡
- ajax值数据传递