如何做代购网站/网络黄页推广软件
GCDAsynSocket是一个开源的基于GCD的异步的socket库。它支持IPV4和IPV6地址,TLS/SSL协议。同时它支持iOS端和Mac端。本篇主要介绍一下GCDAsynSocket中的TCP用法和实现。
首先通过下面这个方法初始化一个GCDAsynSocket对象。
- (id)initWithDelegate:(id<GCDAsyncSocketDelegate>)aDelegate delegateQueue:(dispatch_queue_t)dq socketQueue:(dispatch_queue_t)sq;
这里面需要传入代理的对象,代理队列以及socket队列。其中socket队列不能是一个并发的队列,不然读写就乱了。同时为了防止socket队列死锁,通过dispatch_queue_set_specific
来为这个队列添加key值。
dispatch_queue_set_specific(socketQueue, IsOnSocketQueueOrTargetQueueKey, nonNullUnusedPointer, NULL);
同时这里面初始化了readQueue、writeQueue数组,和一个4K数据缓冲区,后面读写的数据都会先经过这个缓冲区。
readQueue = [[NSMutableArray alloc] initWithCapacity:5];
currentRead = nil;writeQueue = [[NSMutableArray alloc] initWithCapacity:5];
currentWrite = nil;preBuffer = [[GCDAsyncSocketPreBuffer alloc] initWithCapacity:(1024 * 4)];
接着通过下面这个方法建立一个tcp连接:
- (BOOL)connectToHost:(NSString *)hostonPort:(uint16_t)portviaInterface:(nullable NSString *)interfacewithTimeout:(NSTimeInterval)timeouterror:(NSError **)errPtr;
你需要传入host,port,timeout等信息。其中interface是一个备用的port,绝大多数情况下只需传nil。它会把里面的操作都放入上面的socketQueue中。
在这方法里面,先做了一个地址检测。
NSMutableArray *addresses = [[self class] lookupHost:hostCpy port:port error:&lookupErr];
同时在里面会做一个超时计时器,超时时间为一开始传入的时间。
- (void)startConnectTimeout:(NSTimeInterval)timeout
{if (timeout >= 0.0){connectTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, socketQueue);__weak GCDAsyncSocket *weakSelf = self;dispatch_source_set_event_handler(connectTimer, ^{ @autoreleasepool {#pragma clang diagnostic push#pragma clang diagnostic warning "-Wimplicit-retain-self"__strong GCDAsyncSocket *strongSelf = weakSelf;if (strongSelf == nil) return_from_block;[strongSelf doConnectTimeout];#pragma clang diagnostic pop}});dispatch_time_t tt = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeout * NSEC_PER_SEC));dispatch_source_set_timer(connectTimer, tt, DISPATCH_TIME_FOREVER, 0);dispatch_resume(connectTimer);}
}
然后尝试去连接这个地址,中间先会做一些ipv4地址和ipv6地址的转换,接着会并发的发送connect()
连接。一旦连接成功,就会在didConnect
方法中开启读写流连接。一旦进入didConnect
方法,就会关闭前面的超时计时器,因为已经建立tcp握手连接。另外通过CFStreamCreatePairWithSocket
的读写流连接也都是放在socketQueue中执行的。接着通过registerForStreamCallbacksIncludingReadWrite
注册读写的回调。注册完之后会把读写放在一个cfstreamThread
线程中进行执行,并且在cfstreamThread
加入了通过计时器激活的runloop,用来不停的循环检测。
[strongSelf lookup:aStateIndex didSucceedWithAddress4:address4 address6:address6];
--[self connectSocket:socketFD address:address stateIndex:aStateIndex];
----connect(socketFD, (const struct sockaddr *)[address bytes], (socklen_t)[address length]);
------[strongSelf didConnect:aStateIndex];
--------createReadAndWriteStream
----------CFStreamCreatePairWithSocket(NULL, (CFSocketNativeHandle)socketFD, &readStream, &writeStream);
------------registerForStreamCallbacksIncludingReadWrite
--------------CFReadStreamSetClient(readStream, readStreamEvents, &CFReadStreamCallback, &streamContext)
--------------CFWriteStreamSetClient(writeStream, writeStreamEvents, &CFWriteStreamCallback, &streamContext)
----------------startCFStreamThreadIfNeeded
------------------CFReadStreamScheduleWithRunLoop(asyncSocket->readStream, runLoop, kCFRunLoopDefaultMode);
------------------CFWriteStreamScheduleWithRunLoop(asyncSocket->writeStream, runLoop, kCFRunLoopDefaultMode);
这样一个连接就建立了。如果连接建立就会回调到这个代理方法中。你可以在里面读写数据。
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port;
一旦收到服务端返回的数据,就会回调到这个方法。
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag;
参考:CocoaAsyncSocket
相关文章:

GCDAsynSocket之TCP简析
GCDAsynSocket是一个开源的基于GCD的异步的socket库。它支持IPV4和IPV6地址,TLS/SSL协议。同时它支持iOS端和Mac端。本篇主要介绍一下GCDAsynSocket中的TCP用法和实现。 首先通过下面这个方法初始化一个GCDAsynSocket对象。 - (id)initWithDelegate:(id<GCDAsyn…...

大型网站系统架构演化实例_1.单体架构和垂直架构
大型网站的技术挑战主要来自于庞大的用户,高并发的访问和海量的数据,任何简单的业务一旦需要处理数以P计的数据和面对数以亿计的用户,问题就会变得很棘手。通常大型网站架构主要解决这类问题。 1.第一阶段:单体架构 大型网站都是…...

2024蓝桥杯——宝石问题
先展示题目 声明 以下代码仅是我的个人看法,在自己考试过程中的优化版,本人考试就踩了很多坑,我会—一列举出来。代码可能很多,但是总体时间复杂度不高只有0(N) 函数里面的动态数组我没有写开辟判断和free,这里我忽略…...

three.js加载模型报错,Error: THREE.GLTFLoader: No DRACOLoader instance provided.
three.js加载模型报错,Error: THREE.GLTFLoader: No DRACOLoader instance provided. 原因:该模型是压缩过的,需要 DRACOLoader 我们先找到该文件夹 node_modules three examples jsm libs draco 将draco拷贝到public下 import { GLTFLoad…...

Spring VS Spring Boot
目录 定义 Spring Spring Boot 区别 优劣对比 Spring Spring的优势 Spring的劣势 Spring Boot Spring Boot的优势 Spring Boot的劣势 适用场景 Spring的适用场景 Spring Boot的适用场景 初学者如何选择学习 定义 Spring Spring是一个轻量级的、开源的Java开发…...

Linux入门(Linux介绍,安装,常用命令,防火墙的设置,注意事项)
目录 一、Linux介绍 1. Linux简介 1 什么是Linux 2 Linux的应用 3 为什么要学习Linux 2. Linux分类 1 按照市场需求分 2 按照原生程度分 3.小结 二、Linux安装 1. vmware介绍 2. 安装VMWare 3. 安装CentOS 4. 登录查看ip 5. 远程连接工具 1 使用FinalShell连接L…...

vue2创建项目的两种方式,配置路由vue-router,引入element-ui
提示:vue2依赖node版本8.0以上 文章目录 前言一、创建项目基于vue-cli二、创建项目基于vue/cli三、对吧两种创建方式四、安装Element ui并引入五、配置路由跳转四、效果五、参考文档总结 前言 使用vue/cli脚手架vue create创建 使用vue-cli脚手架vue init webpack创…...

MySql 表中的id突然变很大,如何给id重新排序
目录 一、场景 二、解决方法 一、场景 我们在开发过程中,难免遇到id突然增大的情况。 由于id突然增大很多,我们重新增加数据时候id会默认加1 那么如何让id 重新从1按顺序排序呢 二、解决方法 点击编辑表,然后新建一个字段id2,将…...

leetcode练习——哈希表
目录 3. 无重复字符的最长子串 题目描述 解题思路 代码实现 349. 两个数组的交集 题目描述 解题思路 代码实现 454. 四数相加 II 题目描述 解题思路 代码实现 242. 有效的字母异位词 题目描述 解题思路 代码实现 438. 找到字符串中所有字母异位词 题目…...

配置交换机 SSH 管理和端口安全
实验1:配置交换机基本安全和 SSH管理 1、实验目的 通过本实验可以掌握: 交换机基本安全配置。SSH 的工作原理和 SSH服务端和客户端的配置。 2、实验拓扑 交换机基本安全和 SSH管理实验拓扑如图所示。 3、实验步骤 (1)配置交换机S1 Swit…...

基于SpringBoot+Vue的装饰工程管理系统(源码+文档+包运行)
一.系统概述 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术的弊端问题。因为传统装饰工程项目信息管理难度大,容错率低&a…...

vue3中axios添加请求和响应的拦截器
本章主要是以记录为主。 在src创建一个utils文件夹,并在utils中创建一个request.js文件。 // 引入axios import axios from "axios"; // import qs from "qs"; // 创建axios实例 const instance axios.create(); // 请求拦截器 instance.int…...

<router-link>出现Error: No match for {“name“:“home“,“params“:{}}
在将<a></a>标签换到<router-link></router-link>的时候出现No match for {"name":"home","params":{}}这样的错误,其中格式并无错误, <router-link class"navbar-brand active" …...

prompt 工程整理(未完、持续更新)
工作期间会将阅读的论文、一些个人的理解整理到个人的文档中,久而久之就积累了不少“个人”能够看懂的脉络和提纲,于是近几日准备将这部分略显杂乱的内容重新进行梳理。论文部分以我个人的理解对其做了一些分类,并附上一些简短的理解…...

兼容性测试用例
备注:本文为博主原创文章,未经博主允许禁止转载。如有问题,欢迎指正。 个人笔记(整理不易,有帮助,收藏+点赞+评论,爱你们!!!你的支持是我写作的动力) 笔记目录:学习笔记目录_pytest和unittest、airtest_weixin_42717928的博客-CSDN博客 个人随笔:工作总结随笔_8、…...

阿里云4核8G云服务器价格多少钱?700元1年
阿里云4核8G云服务器价格多少钱?700元1年。阿里云4核8G服务器租用优惠价格700元1年,配置为ECS通用算力型u1实例(ecs.u1-c1m2.xlarge)4核8G配置、1M到3M带宽可选、ESSD Entry系统盘20G到40G可选,CPU采用Intel(R) Xeon(R…...

ts 中的keyof 和typeof
作用: keyof:用于获取对象类型的所有键的联合类型。typeof:用于获取变量或表达式的类型。 返回类型: keyof:返回的是一个对象类型的所有键组成的联合类型。typeof:返回的是一个值的类型。 使用场景…...

每日一题:买卖股票的最佳时机II
给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。 在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。 返回 你能获得的 最大 利润 。 示例 1&a…...

nginx安装在linux上
nginx主要用于反向代理和负载均衡,现在简单的说说如何在linux操作系统上安装nginx 第一步:安装依赖 yum install -y gcc-c pcre pcre-devel zlib zlib-devel openssl openssl-devel 第二步: 下载nginx,访问官网,ngin…...

ENSP-旁挂式AC
提醒:如果AC不能成功上线AP,一般问题不会出在AC上,优先关注AC-AP线路上的二层或三层组网的三层交换机 拓扑图 管理VLAN:99 | 业务VLAN:100 注意点: 1.连接AP的接口需要打上pvid为管理vlan的标签 2.AC和…...

如何获取手机root权限?
获取手机的 root 权限通常是指在 Android 设备上获取超级用户权限,这样用户就可以访问和修改系统文件、安装定制的 ROM、管理应用权限等。然而,需要注意的是,获取 root 权限可能会导致手机失去保修、安全性降低以及使系统变得不稳定。在获取 …...

2023年全国青少年信息素养大赛(Python)海南赛区复赛真题
2023年全国青少年信息素养大赛(Python)海南赛区复赛真题第1题,整数加8 题目描述: 输入一个整数,输出这个整数加8 的结果。 输入描述: 输入一行一个正整数。 输出描述: 输出求和的结果。 样例1: 输入: 5 输出: 13 x= int(input()) print(x+8) 第2题,哼哈二将 题目描…...

node.js服务器动态资源处理
一、node.js服务器动态资源处理与静态资源处理的区别? 静态与动态服务器主要区别于是否读取数据库,若然在数据库中的资料处理中将数据转换成可取用格式的结构,也就是说把对象转化为可传输的字节序列过程称为序列化,反之则为反序列…...

DNS是TCP还是UDP
既使用TCP也使用UDP 1. 域名解析时用UDP 在大多数情况下,DNS请求使用UDP协议,因为UDP协议可以提供较高的效率和安全性,尤其是在查询的响应大小较小(通常不超过512字节)时。非可靠连接,因为传输的数据量小…...

Redis魔法:解锁高性能缓存的神奇之门(二)
本系列文章简介: 在现代的软件开发中,高性能和高可用性是每个开发者都追求的目标。然而,随着数据量和访问频率的不断增长,传统的数据库存储方案往往难以应对这种挑战。这就引出了一个问题:如何在保证数据的高效访问和持…...

ROS2 仿真学习02 Gazebo导入官方示例模型
1.下载模型 git clone https://gitee.com/bingda-robot/gazebo_models.git将gazebo_models拖到到.gazebo当中(如果没看到.gazebo文件请按住CTRLh) 2.添加模型到gazebo的Insert 这就将官方示例的模型都导入到Gazebo 了 随便试试一个模型...

echarts图表按需导入
引入核心包引入图表类型引入使用组件引入渲染器注册所有引入 在项目中引入 Apache ECharts // 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。 import * as echarts from echarts/core; // 引入柱状图图表,图表后缀都为 Chart impo…...

蓝桥杯(基础题)
试题 C: 好数 时间限制 : 1.0s 内存限制: 256.0MB 本题总分:10 分 【问题描述】 一个整数如果按从低位到高位的顺序,奇数位(个位、百位、万位 )上 的数字是奇数,偶数位(十位、千位、十万位 &…...

【R语言】概率密度图
概率密度图是用来表示连续型数据的分布情况的一种图形化方法。它通过在数据的取值范围内绘制一条曲线来描述数据的分布情况,曲线下的面积代表了在该范围内观察到某一数值的概率。具体来说,对于给定的连续型数据,概率密度图会使用核密度估计&a…...

【学习】软件测试需求分析要从哪些方面入手
软件测试需求分析是软件测试过程中非常重要的一个环节,它是为了明确软件测试的目标、范围、资源和时间等要素,以确保软件测试的有效性和全面性。本文将从以下几个方面对软件测试需求分析进行详细的阐述: 一、软件测试目标 软件测试目标是指…...