这是一篇介绍GCDAynscSocket客户端简单使用的文章(服务端后续添加)

背景:在这篇文章之前我对socket的了解仅限于知道有TCP、UDP两种方式,使用抓包工具时甚至看不懂抓包数据(惭愧...),所以本文介绍内容深度有限,主要介绍了一些简单用法。

在这篇文章中主要介绍:

1、使用GCDAynscSocket创建连接、发送数据、接收数据、断开连接;

2、发生数据粘包的处理。

------------------------------------------------------------------------------------

1、创建连接

GCDAynscSocket的初始化般使用两种方式:

  // aDelegate是设置的委托对象,而dq是委托所在的线程,sq是socket所在的线程。其中dp不能为空,sq可以为空

  - (id)initWithDelegate:(id)aDelegate delegateQueue:(dispatch_queue_t)dq;

  - (id)initWithDelegate:(id)aDelegate delegateQueue:(dispatch_queue_t)dq socketQueue:(dispatch_queue_t)sq;

  /**
  * @brief 连接到服务器
  */
  - (void)socketConnectHost
  {

    self.socket = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:delegateQueue];

    NSError *error = nil;

    [self.socket connectToHost:self.socketHost onPort:self.socketPort withTimeout:3 error:&error];

    [self.socket readDataWithTimeout:30 tag:100];

  }

连接是否成功都是在委托方法中查看的

// 连接成功的委托方法  

- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port

{

  NSLog(@"连接成功了...");

}

// 连接失败或中途断开连接的委托方法

- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err

{

  NSLog(@"连接失败... 断开连接了...");  

}

2、发送数据

  发送数据比较简单,调用[self.socket writeData:data withTimeout:-1 tag:1]即可

  /**

  *  @brief   写入字符串数据

  *  @param   sendStr 要写入的字符串

  */

  - (void)writeAndSendData:(NSString *)sendStr

  {

   NSData *data = [sendStr dataUsingEncoding: NSUTF8StringEncoding];

  [self.socket writeData:data withTimeout:-1 tag:1];

  }

3、接收数据

  // 在委托方法中接收数据

  - (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag

  {

    // 对得到的data值进行解析

   [self parseSocket:sock withData:data withTag:tag];

  }

在此处有一个疑问:

在接收数据之前,是否必须执行[self.socket readDataWithTimeout:-1 tag:100]??最初开始使用时,是必须添加的否则接收不到数据,但是现在工程中没有执行这句代码,为什么可以一直接收数据呢?

4、断开连接

  断开连接直接调用方法[self.socket disconnect]即可,可以在委托方法查看是否断开

  /**

  *  @brief   切断socket

   */

  -(void)cutOffSocket

  {

   [self.socket disconnect];

  }

5、数据粘包处理

通常在tcp中都要处理数据粘包。我使用的是给数据添加包头的方式,这也是网上比较推荐的一种方式。

思路:定义好包头协议后,在数据发送端每次发送数据之前都添加一个包头(因为是每次发送都添加,所以我认为只要能够满足解包需求包头要尽可能短)。接收端根据包头信息对接收到的数据进行拆包。

一个简单的包头数据:  有5个字节包含两项内容开始:字符$和数据包长度msgLen。

char     startStr = '$';

uint32_t msgLen;

msgLen  = (uint32_t)(str.length + 5);

在接收端接收到数据后,根据包头信息,找到开始字符$,然后读出包的长度,即可正确拆包。

在整个过程中要注意:如果发送端对数据进行了编码,那么接收端要进行相应的解码,否则会造成乱码,拆包失败。

总结:

在整个使用学习过程中,网络知识一窍不通,又无人指导,感觉举步维艰,还好最终实现了!回头看看前面自己绕的弯路觉得很可笑,纠结的问题更是...

且学且努力!

转载于:https://www.cnblogs.com/songshu-yilia/p/4549160.html

GCDAynscSocket简单使用-客户端相关推荐

  1. python16进制字节序_第 1 章 套接字、IPv4和简单的客户端/服务器编程

    第 1 章 套接字.IPv4和简单的客户端/服务器编程 本章攻略: 打印设备名和IPv4地址 获取远程设备的IP地址 将IPv4地址转换成不同的格式 通过指定的端口和协议找到服务名 主机字节序和网络字 ...

  2. python能做哪些客户端_Python 实现简单的客户端认证

    问题 你想在分布式系统中实现一个简单的客户端连接认证功能,又不想像SSL那样的复杂. 解决方案 可以利用 hmac 模块实现一个连接握手,从而实现一个简单而高效的认证过程.下面是代码示例: impor ...

  3. java rest客户端_Java中的简单REST客户端

    java rest客户端 如今,大多数用于与某些服务器通信的移动应用程序都使用REST服务. 这些服务也是JavaScript或jQuery的常用惯例. 现在,我知道在Java中为REST服务创建客户 ...

  4. Java中的简单REST客户端

    如今,大多数用于与某些服务器通信的移动应用程序都使用REST服务. 这些服务也是与JavaScript或jQuery一起使用的常见做法. 现在,我知道在Java中为REST服务创建客户端的2种方法,在 ...

  5. java服务器向客户端发消息_java一个简单的客户端向服务端发送消息

    java一个简单的客户端向服务端发送消息 客户端代码: package com.chenghu.tcpip; import java.io.IOException; import java.io.Ou ...

  6. 基于Domoticz智能家居系统(十七)DIY一款基于MySensors的ESP8266+NRF24L01的MQTT(WIFI)和RF无线网关(三)一个简单MySensors客户端的验证实验

    DIY一款基于MySensors的ESP8266+NRF24L01的MQTT(WIFI)和RF无线网关(三)一个简单MySensors客户端的验证实验 一个简单MySensors客户端的验证实验 一. ...

  7. Python 实现简单的客户端认证

    更多编程教程请到:菜鸟教程 https://www.piaodoo.com/ 友情链接: 高州阳光论坛https://www.hnthzk.com/ 人人影视http://www.op-kg.com/ ...

  8. Netty简单实现客户端与服务端收发消息

    Netty简单实现客户端与服务端收发消息 这个小案例主要是实现netty收发消息,分为客户端,及服务端,以及包含了相关状态处理,主要的代码会放在最后 gitHub 地址上,有需要可以看一下 首先来简单 ...

  9. 【初识Netty使用Netty实现简单的客户端与服务端的通信操作Netty框架中一些重要的类以及方法的解析】

    一.Netty是什么? Netty 由 Trustin Lee(韩国,Line 公司)2004 年开发 本质:网络应用程序框架 实现:异步.事件驱动 特性:高性能.可维护.快速开发 用途:开发服务器和 ...

最新文章

  1. 11个鲜为人知的实用Linux命令 - Part 2
  2. linux gnome启动命令,如何在Gnome Shell上自动启动程序
  3. C语言中字符型和字符串型的对比
  4. 清华博士庞天宇90页的PPT分享,如何让AI模型更皮实,更稳定?(精彩直播回放)...
  5. php怎么截取数组最后元素,PHP如何获取数组最后一个元素的键和值?(图文+视频)...
  6. 如何在套接字IO操作上设置超时机制
  7. 都别争了!分布式锁也是锁
  8. hdu 1995 汉诺塔
  9. 图解Java设计模式
  10. 用html做krc转换lrc的文件,来,教你怎么把酷狗音乐krc歌词转换成lrc歌词文件?
  11. YOLO: 3 步实时目标检测安装运行教程 [你看那条狗,好像一条狗!]
  12. 推荐!十个好用的百度网盘搜索引擎
  13. 确认main_arena相对libc的偏移地址
  14. html响应式布局ipad,响应式布局(Responsive design)
  15. EGE基础入门篇(六):基本图形
  16. 砍一刀免费拿营销玩法解说
  17. CameraX Java 1.0.0-alpha10 安卓开发
  18. 疫情之下,IT 培训品牌「 IT 兄弟连」宣告停工
  19. 恭喜你!发现宝藏一份---干货技术文章汇总
  20. power 见解_客户见解的两个简单来源,可改善用户体验

热门文章

  1. 使用oracle 的 PL/Sql 定时执行一个存储过程
  2. html5标签属性大全_HTML5中video标签如何使用
  3. matplotlib plt.subplot
  4. Thread的run()与start()的区别
  5. UDP sendto和recvfrom使用详解
  6. java用for循环修改密码_Java for循环的几种用法分析
  7. Matlab矩阵的拼接
  8. TortoiseSVN使用帮助和下载
  9. Sass笔记(CSS 的预编译语言)
  10. 产品经理思维模型:传播三大原理