(六十五)iOS的socket实现(GCDAsyncSocket)
本文介绍使用GCDAsyncSocket来实现iOS端的socket,有关简易服务端的代码已经在上一篇文章中提到,这里不再赘述,将直接介绍如何实现客户端。
首先下载CocoaAsyncSocket框架,如果下载过iOS的XMPP框架,在Vendor中有这个框架,将框架导入工程,并包含其头文件GCDAsyncSocket.h。
①这是一个异步socket框架,在子线程中完成socket的连接和数据接收,通过代理的方式通知控制器,因此要成为它的代理,代理名为GCDAsyncSocketDelegate。
②创建GCDAsyncSocket对象,并且使之成为成员属性,该对象兼备了输入输出流的功能,后续需要使用。
GCDAsyncSocket *_socket;
我们在这里传入一个全局队列,让它工作在子线程,防止网络不畅时阻塞主线程。
_socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
③连接服务端,还是假设服务端在本地,端口为12345,使用socket的connectToHost方法连接:
NSString *host = @"127.0.0.1";
int port = 12345;
NSError *error = nil;
[_socket connectToHost:host onPort:port error:&error];
if (error) {
NSLog(@"%@",error);
}
④实现代理方法来获取数据:
4.1连接成功的代理:
-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port{
NSLog(@"成功连接到%@:%d",host,port);
}
4.2连接结束的代理:
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{
if (err) {
NSLog(@"%@",err);
}
}
4.3接收数据的代理:
特别注意此处,只有先在发送成功的代理中调用读取方法,才会调用读取的代理方法:
这里的tag是用于区分不同的消息的,在写一条消息的时候需要指定tag,通过不同的tag判断服务器返回的消息的类型。这里有两类消息,分别是登录消息和聊天消息,只有后者会被显示,reloadDataWithText是用于tableView显示数据的方法。
这里对数据处理起来很简单,只需要把data直接转化为NSString即可。
// 数据成功发送到服务器
- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag{ // 需要自己调用读取方法,socket才会调用代理方法读取数据
[_socket readDataWithTimeout:-1 tag:tag]; }
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{ switch (tag) {
case LoginTag:
break;
case MsgTag:{
NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[self reloadDataWithText:msg];
break;
}
default:
break;
} }
⑤发送一条消息:
使用socket的writeData方法,这里不需要指定消息的长度和缓冲区大小,十分方便,tag会被传入,在调用上面提到的代理方法(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag时会被传入,用于判断消息类型。
// 发送 iam:name 表示name登录
NSString *loginStr = @"iam:soulghost";
// 把string转成NSData
NSData *data = [loginStr dataUsingEncoding:NSUTF8StringEncoding];
[_socket writeData:data withTimeout:-1 tag:LoginTag];
需要注意的是异步socket工作在子线程,如果要更新UI,必然会在socket的代理方法中调用更新UI的方法,这时更新UI的代码运行于子线程,不能立即刷新UI界面,因此应该把更新UI的函数放在主线程中执行:
dispatch_async(dispatch_get_main_queue(), ^{
// 更新UI的代码
});
(六十五)iOS的socket实现(GCDAsyncSocket)的更多相关文章
- 第三百六十五节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)的基本查询
第三百六十五节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)的基本查询 1.elasticsearch(搜索引擎)的查询 elasticsearch是功能 ...
- Gradle 1.12用户指南翻译——第六十五章. Maven 发布(新)
其他章节的翻译请参见:http://blog.csdn.net/column/details/gradle-translation.html翻译项目请关注Github上的地址:https://gith ...
- “全栈2019”Java第六十五章:接口与默认方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- 孤荷凌寒自学python第六十五天学习mongoDB的基本操作并进行简单封装4
孤荷凌寒自学python第六十五天学习mongoDB的基本操作并进行简单封装4 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第十一天. 今天继续学习mongoDB的简单操作 ...
- OpenCV开发笔记(六十五):红胖子8分钟带你深入了解ORB特征点(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- 《手把手教你》系列技巧篇(六十五)-java+ selenium自动化测试 - cookie -下篇(详细教程)
1.简介 今天这一篇,宏哥主要讲解:利用WebDriver 提供可以读取.添加和删除cookie 信息的相关操作方法.验证浏览器中是否存在某个cookie.原因是:因为基于真实的cookie 的测试是 ...
- FastAPI(六十五)实战开发《在线课程学习系统》基础架构的搭建
在之前三篇,我们分享的就是需求的分析,基本接口的整理,数据库链接的配置.这次我们分享项目的基本框架,目录结构如下: common目录 通用的目录,一些通用的处理放在这里 models目录 数据库相关的 ...
- SpringBoot进阶教程(六十五)自定义注解
在上一篇文章<SpringBoot进阶教程(六十四)注解大全>中介绍了springboot的常用注解,springboot提供的注解非常的多,这些注解简化了我们的很多操作.今天主要介绍介绍 ...
- 六十五、SAP中通过BREAK-POINT下断点,进行调试
一.代码如下,有2个断点的按钮,可以可以写入BREAK-POINT人工断点 二.运行之后,程序会被断下来, 四个执行按钮,意思分别为:单步进入子程序,单步不进入子程序,返回外面,执行到断点处 三.我们 ...
随机推荐
- 浅谈Java中的equals和==与hashCode
转载:https://www.cnblogs.com/dolphin0520/p/3592500.html 参考:http://blog.csdn.net/yinzhijiezhan/article/ ...
- Ubuntu安装与配置KVM
事前检查 查看一下linux是32位还是64位 file /bin/ls 确认一下 CPU支持硬件虚拟化(不支持也没关系,可以继续) egrep -o '(vmx|svm)' /proc/cpuinf ...
- R语言中函数调试
有时候会用R语言写一下简单的脚本处理函数,加入需要调试的话可以按照下面的步骤进行: fun <- function(x , y){ x + y x - y x * y x / y } debug ...
- MySQL LIKE 子句
MySQL LIKE 子句 我们知道在MySQL中使用 SQL SELECT 命令来读取数据, 同时我们可以在 SELECT 语句中使用 WHERE 子句来获取指定的记录. WHERE 子句中可以使用 ...
- PHP Filter 函数
PHP Filter 简介 PHP 过滤器用于对来自非安全来源的数据(比如用户输入)进行验证和过滤. 安装 Filter 函数是 PHP 核心的组成部分.无需安装即可使用这些函数. PHP Filte ...
- Bootstrap3 表格-带边框的表格
添加 .table-bordered 类为表格和其中的每个单元格增加边框. <table class="table table-bordered"> ... </ ...
- Android中软键盘弹出时底部菜单上移问题
当在Android的layout设计里面如果输入框过多,则在输入弹出软键盘的时候,下面的输入框会有一部分被软件盘挡住,从而不能获取焦点输入. 解决办法: 方法一:在你的activity中的oncrea ...
- Python 通过继承实现标准对象的子类
idict是dict的子类,它的键值和属性是同步的,并且有强大的默认值机制. 例如,假设x是idict的一个实例,且x['a']['b']=12,则有x.a.b=12.反之亦然; 假设'c'不在x的键 ...
- Android逆向工程
在Root前提下,我们可以使用Hooker方式绑定so库,通过逆向方式篡改数值,从而达到所谓破解目的.然而,目前无论是软件加固方式,或是数据处理能力后台化,还是客户端数据真实性验证,都有了一定积累和发 ...
- Retrofit 2.0 超能实践(四),完成大文件断点下载
作者:码小白 文/CSDN 博客 本文出自:http://blog.csdn.net/sk719887916/article/details/51988507 码小白 通过前几篇系统的介绍和综合运用, ...