客户端我们使用iPhone应用程序,画面比较简单。点击发送按钮,给服务器发送一些字符串过去。点击接收按钮就会从服务器读取一些字符串,并且显示在画面上。

有关客户端应用的UI部分不再介绍了,我们直接看代码部分,Socket客户端可以采用CFStream或NSStream实现,CFStream 实现方式与服务器端基本一样。为了给读者介绍更多的知识,本例我们采用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

定义属性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];}

它们都调用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);}

在读取数据分支(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];}

转载于:https://www.cnblogs.com/wwm881101/p/5808944.html

iOS网络编程实践--NSStream实现TCP Socket iPhone客户端相关推荐

  1. java 网络编程(二) tcp传输实现客户端和服务端进行信息交流

    1.使用Tcp从一台电脑往另一台电脑上发送文本数据 客户端: import java.io.*; import java.net.*; /**** 客户端,* 通过查阅socket对象,发现在该对象建 ...

  2. iOS网络编程实践--蓝牙对等网络通信实例讲解

    基于蓝牙对等网络通信就是使用Game Kit中的GKSession.GKSessionDelegate. GKPeerPickerController和GKPeerPickerControllerDe ...

  3. 创建收发文件的服务器端 客户端,TCP/IP网络编程 Chap.5 基于TCP的服务器端/客户端(2)...

    已知字符串长度情况下完善回声客户端 # gcc echo_client2.c -o eclient2 # ./eclient2 127.0.0.1 9190 Connected Input messa ...

  4. 《iOS网络编程与云端应用最佳实践》微博转发送书了!

    <iOS网络编程与云端应用最佳实践>微博转发送书了! 新浪微博地址:http://weibo.com/2078101705/zy15U4a5D,转发本条微博即有机会获得<iOS网络编 ...

  5. 转发网络《iOS网络编程与云端应用最佳实践》微博转发送书了

    在写这篇文章之前,xxx已经写过了几篇关于改转发网络主题的文章,想要了解的朋友可以去翻一下之前的文章 <iOS网络编程与云端应用最佳实践>微博转发送书了! 新浪微博地址:http://we ...

  6. [深入浅出Cocoa]iOS网络编程之NSStream

    2019独角兽企业重金招聘Python工程师标准>>> [深入浅出Cocoa]iOS网络编程之NSStream 目录(?)[+] [深入浅出Cocoa]iOS网络编程之NSStrea ...

  7. 【网络编程实践--陈硕】学习笔记 | 汇总目录

    本文参考<网络编程实践>–陈硕(Muduo作者)视频课程所写.基于课程内容所做归纳和整理. <网络编程实战>配套页面:http://chenshuo.com/pnp Blog ...

  8. 《9.linux网络编程实践》

    转自 https://edu.csdn.net/lecturer/505 朱老师物联网大讲堂 <9.linux网络编程实践> 第一部分.章节目录 3.9.1.linux网络编程框架 3.9 ...

  9. iOS网络编程-iCloud键值数据存储编程实例

    iCloud键值数据存储设计 iCloud键值数据存储编程实例,画面中有两个开关控件,左图是设备1点击"设置iCloud数据"按钮,将控件状态保存到iCloud服务器.右图是设备2 ...

最新文章

  1. 嵌入式linux编程,嵌入式Linux学习笔记 - 嵌入式Linux基础知识和开发环境的构建_Linux编程_Linux公社-Linux系统门户网站...
  2. python异常处理语句编程题_一篇文章让你掌握Python异常处理所有知识点,记得收藏...
  3. MySQL中使用innobackupex、xtrabackup进行大数据的备份和还原
  4. ffmpeg 编码如何做带宽控制输出
  5. 计算机上安装了新的ie版本,win7电脑自带的IE11浏览器如何降级到IE8
  6. 求解无约束最优化问题的共轭梯度法matlab程序,Matlab实现FR共轭梯度法
  7. MXY-API管理系统安装教程
  8. ssh远程连接windows
  9. miniC语言编译器设计与实现(编译原理实验课程)
  10. 华为5G CPE是做什么用的?
  11. 【数据挖掘】关联规则的术语及定义
  12. 本科学历马斯克当选美国工程院院士!张宏江、萨蒂亚:“我们都有美好的未来”...
  13. 中国联通亮相5G创新应用大会5G创新开启数字化转型新征程
  14. 股票历史行情数据api_历史API
  15. 手机相册里不能有的四种照片,你有没有中招?
  16. faster-rcnn在ubuntu16.04环境下的超级详细的配置(转)
  17. Web-Crawler(爬虫基础)
  18. 硬盘转速比几乎就是磁盘性能比:请选择7200转硬盘
  19. 用scrapy爬取京东商城的商品信息
  20. npm的卸载与安装流程

热门文章

  1. 【HDU - 1247】Hat’s Words(字典树,预处理,tricks)
  2. Java (jdk win 10)
  3. 大一计算机绩点3算什么水平,绩点只有3?我可以解释一下
  4. CSS中属性个属性值怎么区分,[CSS] 详细解释 @media 属性与 (max
  5. python解图片迷宫生成路径_用Python代码来解图片迷宫的方法整理
  6. java reader_Java之字符输入流,Reader类的简单介绍
  7. lpc1768的gpio库函数_LPC1768之GPIO流水灯的实验例程
  8. 在c语言中优先级最低的是6,C语言中 *,<<,= ,->哪个优先级最低
  9. linux配置定时删除日志文件,Linux使用shell脚本定时删除历史日志文件
  10. Android入门(一) | Android Studio的配置与使用