iOS网络编程实践--NSStream实现TCP Socket iPhone客户端
客户端我们使用iPhone应用程序,画面比较简单。点击发送按钮,给服务器发送一些字符串过去。点击接收按钮就会从服务器读取一些字符串,并且显示在画面上。
有关客户端应用的UI部分不再介绍了,我们直接看代码部分,Socket客户端可以采用CFStream或NSStream实现。为了给读者介绍更多的知识,本例我们采用NSStream实现。NSStream实现采用Objective-C语言,一些面向对象的类。
下面我们看看客户端视图控制器ViewController.h
[cpp]
#import <CoreFoundation/CoreFoundation.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 9000
@inte易做图ce 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
@inte易做图ce 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代码:
[cpp]
(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:,其代码如下:
[cpp]
-(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(@&rdqu
补充:移动开发 , IOS ,