(六十五)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人工断点 二.运行之后,程序会被断下来, 四个执行按钮,意思分别为:单步进入子程序,单步不进入子程序,返回外面,执行到断点处 三.我们 ...
随机推荐
- web.xml is missing and <failOnMissingWebXml> is set to true
这时候需要右击项目-->Java EE Tools-->Generate Deployment Descriptor Stub .然后系统会在src/main/webapp/WEB_INF ...
- mongodb数据库备份迁移 windows -> linux
mongodb数据库备份迁移 windows -> linux cd 到本机mongodb的安装目录 如: C:\Program Files\MongoDB\Server\3.4\bin 可以发 ...
- 重构:从Promise到Async/Await
摘要: 夸张点说,技术的发展与历史一样,顺之者昌,逆之者亡.JS开发者们,赶紧拥抱Async/Await吧! GitHub仓库: Fundebug/promise-asyncawait 早在半年多之前 ...
- react 或 vue 中引用 jQuery 插件
前言 今天与遇到一个令人抓狂的事情, 因为项目中有个交互太过于复杂而且冷门, 没有人封装类似react-swiper那种的移植过来的插件 只有现成的jQuery插件. 而时间并不宽裕,自己重写成rea ...
- 如何搭建lamp(CentOS7+Apache+MySQL+PHP)环境
我的环境:虚拟机是:VMware-workstation-full-8.0.0-471780.exe:Linux系统用的是:CentOS-7-x86_64-Minimal-1503-01.ios;(阿 ...
- Django Views(视图函数)
http请求中产生两个核心对象: http请求:HttpRequest对象 http响应:HttpResponse对象 所在位置:django.http 之前我们用到的参数request就是HttpR ...
- Linux(十七)动态监控进程
17.1 介绍 top与ps命令很相似.它们都用来显示正在执行的进程.top与ps最大的不同之处,在于top在执行一段时间可以更新正在运行的进程 17.2 语法 top [选项] 常用选项 ...
- makefile 和shell文件相互调用
shell 文件内调用makefile文件: #!/bin/bash cd ctemplate-2.1./configuresudo make -f installcd ../cd Templat ...
- move_uploaded_file的failed to open stream错误处理
PHP的基本语法学习的差不多了,现在开始学习PHP的文件上传功能实现了.功能中使用到了move_uploaded_file方法,运行时报错: failed to open stream. 经过查资料, ...
- Android Studio NDK 代码 Source Insight调试 (NDK 目前开发方案 | NDK 编译 | 导入 so 库 | 项目编码转换)
作者 : 韩曙亮 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/52088039 最近在移植一个 JNI 项目, 比较纠结, A ...