iOS CFNetwork 内部原理

iOS - CFNetwork 的使用 iOS - CFNetwork 的使用 1、CFNetwork CFNetwork 是基于 OS 层 BSDSocket 封装(纯 C),用于网络通信,早期的网络请求框架 ASIHTTPRequest 就是基于 CFNetwork 进行的封装。 主要使用的 API:CFSocket 用于底层的通信,CFStream 用于数据的读写。 2、基本使... 阅读详情

一,CFNetwork 简介

首先来回顾下。在前文《 [深入浅出Cocoa]iOS网络编程之Socket》中,提到iOS网络编程层次模型分为三层:
  • Cocoa层:NSURL,Bonjour,Game Kit,WebKit
  • Core Foundation层:基于 C 的 CFNetwork 和 CFNetServices
  • OS层:基于 C 的 BSD socket
前文讲的是最底层的 socket,本文将介绍位于 Core Foundation 中的 CFNetwork。CFNetwork 只是对 BSD socket 的进行了轻量级的封装,但在 iOS 中使用 CFNetwork 有一个显著的好处,那就是 CFNetwork 与系统级别的设置(如:天线设置)以及 run-loop 结合得很好。每一个线程都有自己的 run-loop,因此我们可以 CFNetwork 当中事件源加入到 run-loop 中,这样就可以在线程的 run-loop 中处理网络事件了。BTW,大名鼎鼎的 ASIHttpRequest 库就是基于 CFNetwork 封装的。

本文示例代码就是这样做的,源码请查看:
 

二,CFNetwork API 简介

CFNetwork 接口是基于 C 的,下面的接口用于创建一对 socket stream,一个用于读取,一个用于写入:
void CFStreamCreatePairWithSocketToHost(CFAllocatorRef alloc, CFStringRef host, UInt32 port, CFReadStreamRef *readStream, CFWriteStreamRef *writeStream);

该函数使用 host 以及 port,CFNetwork 会将该 host 转换为 IP 地址,并转换为网络字节顺序。如果我们只需要一个 socket stream,我们可以将另外一个设置为 NULL。还有另外两个“重载”的创建 socket sream的接口:CFStreamCreatePairWithSocket 和 CFStreamCreatePairWithPeerSocketSignature,在这里就不一一介绍了。

注意:在使用这些 socket stream 之前,必须显式地调用其 open 函数:

   
Boolean CFReadStreamOpen(CFReadStreamRef stream);
Boolean CFWriteStreamOpen(CFWriteStreamRef stream);

但与 socket 不同的是,这两个接口是异步的,当成功 open 之后,如果调用方设置了获取 kCFStreamEventOpenCompleted 事件的标志的话就会其调用回调函数。

而该回调函数及其参数设置是通过如下接口进行的:

   
Boolean CFReadStreamSetClient (CFReadStreamRef stream, CFOptionFlags streamEvents, CFReadStreamClientCallBack clientCB, CFStreamClientContext *clientContext);
Boolean CFWriteStreamSetClient(CFWriteStreamRef stream, CFOptionFlags streamEvents, CFWriteStreamClientCallBack clientCB, CFStreamClientContext *clientContext);

该函数用于设置回调函数及相关参数。通过 streamEvents 标志来设置我们对哪些事件感兴趣;clientCB 是一个回调函数,当事件标志对应的事件发生时,该回调函数就会被调用;clientContext 是用于传递参数到回调函数中去。

当设置好回调函数之后,我们可以将 socket stream 当做事件源调度到 run-loop 中去,这样 run-loop 就能分发该 socket stream 的网络事件了。

   
void CFReadStreamScheduleWithRunLoop(CFReadStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode);
void CFWriteStreamScheduleWithRunLoop (CFWriteStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode);

注意,在我们不再关心该 socket stream 的网络事件时,记得要调用如下接口将 socket stream 从 run-loop 的事件源中移除。

   
void CFReadStreamUnscheduleFromRunLoop(CFReadStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode);
void CFWriteStreamUnscheduleFromRunLoop (CFWriteStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode);

当我们将 socket stream 的网络事件调度到 run-loop 之后,我们就能在回调函数中相应各种事件,比如 kCFStreamEventHasBytesAvailable 读取数据:

   
Boolean CFReadStreamHasBytesAvailable (CFReadStreamRef stream);
CFIndex CFReadStreamRead(CFReadStreamRef stream, UInt8 *buffer, CFIndex bufferLength);

或 kCFStreamEventCanAcceptBytes 写入数据:

   
Boolean CFWriteStreamCanAcceptBytes (CFWriteStreamRef stream);
CFIndex CFWriteStreamWrite(CFWriteStreamRef stream, const UInt8 *buffer, CFIndex bufferLength);

最后,我们调用 close 方法关闭 socket stream:

   
void CFReadStreamClose(CFReadStreamRef stream);
void CFWriteStreamClose(CFWriteStreamRef stream);


三,客户端示例代码

与 socket 演示类似,在这里我只演示客户端示例。同样,我们也在一个后台线程中启动网络操作:

[html]  view plain copy print ?
  1.    NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:@"%@:%@", serverHost, serverPort]];  
  2.    NSThread * backgroundThread = [[NSThread alloc] initWithTarget:self  
  3.                                                          selector:@selector(loadDataFromServerWithURL:)  
  4.                                                            object:url];  
  5. [backgroundThread start];  

然后在 loadDataFromServerWithURL 中创建 socket 流,并设置其回调函数,将其加入到 run-loop 的事件源中,然后启动之:

  1. - (void)loadDataFromServerWithURL:(NSURL *)url  
  2. {  
  3.     NSString * host = [url host];  
  4.     NSInteger port = [[url port] integerValue];  
  5.       
  6.     // Keep a reference to self to use for controller callbacks  
  7.     //  
  8.     CFStreamClientContext ctx = {0, (__bridge void *)(self), NULL, NULL, NULL};  
  9.       
  10.     // Get callbacks for stream data, stream end, and any errors  
  11.     //  
  12.     CFOptionFlags registeredEvents = (kCFStreamEventHasBytesAvailable | kCFStreamEventEndEncountered | kCFStreamEventErrorOccurred);  
  13.       
  14.     // Create a read-only socket  
  15.     //  
  16.     CFReadStreamRef readStream;  
  17.     <strong>CFStreamCreatePairWithSocketToHost</strong>(kCFAllocatorDefault, (__bridge CFStringRef)host, port, &readStream, NULL);  
  18.       
  19.     // Schedule the stream on the run loop to enable callbacks  
  20.     //  
  21.     if (<strong>CFReadStreamSetClient</strong>(readStream, registeredEvents, socketCallback, &ctx)) {  
  22.         <strong>CFReadStreamScheduleWithRunLoop</strong>(readStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);  
  23.           
  24.     }  
  25.     else {  
  26.         [self networkFailedWithErrorMessage:@"Failed to assign callback method"];  
  27.         return;  
  28.     }  
  29.       
  30.     // Open the stream for reading  
  31.     //  
  32.     if (<strong>CFReadStreamOpen</strong>(readStream) == NO) {  
  33.         [self networkFailedWithErrorMessage:@"Failed to open read stream"];  
  34.           
  35.         return;  
  36.     }  
  37.       
  38.     CFErrorRef error = <strong>CFReadStreamCopyError</strong>(readStream);  
  39.     if (error != NULL) {  
  40.         if (CFErrorGetCode(error) != 0) {  
  41.             NSString * errorInfo = [NSString stringWithFormat:@"Failed to connect stream; error '%@' (code %ld)", (__bridge NSString*)CFErrorGetDomain(error), CFErrorGetCode(error)];  
  42.             [self networkFailedWithErrorMessage:errorInfo];  
  43.         }  
  44.           
  45.         CFRelease(error);  
  46.           
  47.         return;  
  48.     }  
  49.       
  50.     NSLog(@"Successfully connected to %@", url);  
  51.       
  52.     // Start processing  
  53.     //  
  54.     <strong>CFRunLoopRun</strong>();  
  55. }  

参考前面的接口说明,相信你不难理解上面的代码。前面唯一没有提到的接口就是 CFReadStreamCopyError,该接口用于获取当前的错误信息,如果没有错误则返回 NULL。

   
CFErrorRef CFReadStreamCopyError(CFReadStreamRef stream);
CFErrorRef CFWriteStreamCopyError(CFWriteStreamRef stream);

此外,我们还可以调用如下接口获取 socket stream 的当前状态:

   
CFStreamStatus CFReadStreamGetStatus(CFReadStreamRef stream);
CFStreamStatus CFWriteStreamGetStatus(CFWriteStreamRef stream);

在上面的代码中,我们设置了当有数据可以读取,流到达结尾处时以及错误发生时调用回调函数 socketCallback:

[html]  view plain copy print ?
  1. void socketCallback(CFReadStreamRef stream, CFStreamEventType event, void * myPtr)  
  2. {  
  3.     KSCFNetworkViewController * controller = (__bridge KSCFNetworkViewController *)myPtr;  
  4.       
  5.     switch(event) {  
  6.         case kCFStreamEventHasBytesAvailable: {  
  7.             // Read bytes until there are no more  
  8.             //  
  9.             while (<strong>CFReadStreamHasBytesAvailable</strong>(stream)) {  
  10.                 UInt8 buffer[kBufferSize];  
  11.                 int numBytesRead = <strong>CFReadStreamRead</strong>(stream, buffer, kBufferSize);  
  12.                   
  13.                 [controller didReceiveData:[NSData dataWithBytes:buffer length:numBytesRead]];  
  14.             }  
  15.               
  16.             break;  
  17.         }  
  18.               
  19.         case kCFStreamEventErrorOccurred: {  
  20.             CFErrorRef error = <strong>CFReadStreamCopyError</strong>(stream);  
  21.             if (error != NULL) {  
  22.                 if (CFErrorGetCode(error) != 0) {  
  23.                     NSString * errorInfo = [NSString stringWithFormat:@"Failed while reading stream; error '%@' (code %ld)", (__bridge NSString*)CFErrorGetDomain(error), CFErrorGetCode(error)];  
  24.                       
  25.                     [controller networkFailedWithErrorMessage:errorInfo];  
  26.                 }  
  27.                   
  28.                 CFRelease(error);  
  29.             }  
  30.               
  31.               
  32.             break;  
  33.         }  
  34.               
  35.         case kCFStreamEventEndEncountered:  
  36.             // Finnish receiveing data  
  37.             //  
  38.             [controller didFinishReceivingData];  
  39.               
  40.             // Clean up  
  41.             //  
  42.             <strong>CFReadStreamClose</strong>(stream);  
  43.             <strong>CFReadStreamUnscheduleFromRunLoop</strong>(stream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);  
  44.             <strong>CFRunLoopStop</strong>(CFRunLoopGetCurrent());  
  45.               
  46.             break;  
  47.               
  48.         default:  
  49.             break;  
  50.     }  
  51. }  

上面的代码也很好理解,当有数据可以读取时,读取之,然后更新 UI;当流到达结尾处时,关闭流,执行清理工作;当错误发送时,报告错误信息。


四,扩展

虽然上面的代码只演示了如何使用 CFNetwork 的 CFReadStream 来读取数据,写入数据使用 CFWriteStream,其工作流程也是一样的。在这里就不再介绍了。更多《深入浅出Cocoa》系列文章,敬请访问优快云专栏:http://blog.youkuaiyun.com/column/details/cocoa.html  

iOS ftp上传 本文主要讲诉了iOS 端使用ftp上传图片以及文件的方法。 网络上大多数的文件的上传都是通过ASIHttpRequest库以form表单的形式完成的,比较简单,代码逻辑也比较清晰,在此笔者 就不赘述了。而今天要跟大家分享的是在iOS端使用ftp的形式进行上传的方式。       由于网上关于在iOS端ftp上传的资料很少,而且刚好笔者也需要用到ftp,因此,便促成了此文的诞生。 阅读详情

相关推荐

基于CFNetWork的网络请求框架(iOS源代码)

来源: Licence: MIT 作者: 丶 LHHTTPRequest 是基于CFNetWork的网络请求框架,功能非常强大. LHHTTPRequest 只有两个类: 1.LHHTTPRequest 此类包含了所有的网络请求,一个对象一个请求,GET,POST,下载文件到指定路径,进度追踪,分段下载,断点下载 2.LHNetWorkReachability 此类是判断网络环境的类,可以获取当前网络环境,监测网络变化(通知方式,block方式)

CFNetwork概念(CFNetwork Concepts )

CFNetwork是一个低级别高性能的框架,使你能够精细的控制协议栈。它是BSD套接字的扩展,标准套接字抽象API提供对象来简化任务,例如与FTP和HTTP服务器或解析DNS主机。CFNetwork物理上和理论上都基于BSD套接字。 正如CFNetwork依赖与BSD套接字,有大量的Cocoa类依赖CFNetwork(例如,NSURL)。此外,Cocoa类的web工具包用来在窗口显示网页内容。这

小言的专栏 4115

Mamba实战:如何用Samba框架轻松搞定RGB-D显著性检测(附避坑指南)

本文提供了基于Samba框架进行RGB-D显著性目标检测的实战指南。详细解析了从环境配置、数据预处理到模型推理与可视化的全流程,并重点剖析了多模态数据融合中的常见陷阱与调试技巧,旨在帮助开发者高效部署这一基于Mamba的先进视觉模型,规避工程实践中的典型问题。

dapp9builder的博客 615

CFNetwork编程指南(一)——CFNetwork概念(CFNetwork Concepts)

CFNetwork是一个低级别高性能的框架,使你能够精细的控制协议栈。它是BSD套接字的扩展,标准套接字抽象API提供对象来简化任务,例如与FTP和HTTP服务器通信或解析DNS主机。CFNetwork物理上和理论上都基于BSD套接字。 正如CFNetwork依赖与BSD套接字,有大量的Cocoa类依赖CFNetwork(例如,NSURL)。此外,Cocoa类的web工具包用来在窗口显示网页内容

ihoudf 1949

千兆以太网的接收和crc校验

解析该以太网帧,包括统计该以太网帧长度+过滤功能(端口号对不对,是否为udp协议)+CRC校验,将解析结果存入状态fifo,一旦状态fifo开始有数,就开始开启读过程,读过程开始时,首先读状态fifo,根据从状态fifo里面读出的以太网帧长度,来读数据fifo(这样能够防止跨帧读),然后在根据状态fifo里面读出的crc校验正确标志和过滤标志,来确定是否将数据fifo读出来的数据送给下一个模块。改掉之后在抓一下,可以看到抓出来的数据完全正确,从最后开始看,除去4个crc校验的尾巴,数据是到255结束的。

weixin_45284871的博客 2738

手把手教你用OpenCalib完成激光雷达与相机联合标定:从数据准备到结果可视化

本文详细介绍了使用OpenCalib工具链中的lidar2camera模块完成激光雷达与相机联合标定的全流程,包括数据准备、标定命令执行、结果验证与可视化。通过实战指南,帮助读者掌握工业级标定技术,提升自动驾驶和机器人领域的传感器融合精度。

weixin_30872499的博客 400

[深入浅出Cocoa]iOS网络编程之CFNetwork

[深入浅出Cocoa]iOS网络编程之CFNetwork 罗朝辉 (http://www.cnblogs.com/kesalin/) 本文遵循“署名-非商业用途-保持一致”创作公用协议   一,CFNetwork 简介 首先来回顾下。在前文《[深入浅出Cocoa]iOS网络编程之Socket》中,提到iOS网络编程层次模型分为三层: Cocoa层:NSURL,Bonjour,G...

weixin_34102807的博客 311

物料主数据管理难在哪?基于AI算法的数据清洗工具了解一下

企企通打造的一套以AI模型和算法为核心的产品及服务,可针对各类企业的不同主数据痛点难点,提供多种解决方案,能够快速完成物料主数据清洗、识别、匹配、梳理,满足一物一码、分类梳理、一品多商、多维度比价、精准寻源选品、建立标准物料库、供应商及客户主数据清洗等业务场景需求。随着AI技术的快速发展,智能算法在数据清洗领域的应用越来越广泛,越来越多的数据清洗工作已经开始交由智能算法完成,通过自动化的方式处理大量数据,识别和纠正错误,填补缺失值,检测异常值,以及执行其他数据预处理任务,并提高效率并减少人为错误。

QQT_qqt的博客 1364

CFNetwork(一)

CFNetwork Concepts@官方文档翻译-李冰@译文CFNetwork是给予你有能力全面的控制协议栈的能力的底层,高性能的框架。它是BSD套接字的延伸扩展,标准套接字抽象API对对象提供简化的任务如FTP和HTTP服务器的连接和解析DNS主机。CFNetwork同时基于BSD套接字的物理和理论。正如CFNetwork依赖于BSD套接字,还有一些Cocoa类依赖于CFNetwork(比如NS

libing_py的博客 868

AI 大模型应用数据中心的数据清洗工具

1. 背景介绍 在人工智能大模型应用的浪潮中,数据清洗作为数据预处理的重要环节,对于提升模型性能和可靠性具有至关重要的作用。数据中心作为人工智能模型的运行环境,面临着海量数据流和多样化的数据类型,如何高效、准确地进行数据清洗,成为应用大模型的关键问题之一。本文将详细介绍AI大模型应用数据中心的数据清洗工具,包括核心概念、算法原理、具体操作步骤、应用场

SuperAGI2025 1804

RK3588 实战级 YOLOv5 Android 全解析:NPU 量化 + 多线程 + 跟踪算法,源码一次买齐

本文将带你完成一个完整的AI视觉项目:在搭载RK3588芯片的Android开发板上运行实时目标检测与跟踪应用。实战目标:成功运行官方YOLOV5摄像头实时检测案例技术深度:深入理解RKNN开发框架和源码实现核心技能:掌握NPU推理、多线程并发、目标跟踪等关键技术。

FJN110的博客 156

CFNetwork简介

CFNetwork Concepts CFNetwork is a low-level, high-performance framework that gives you the ability to have detailed control over the protocol stack. It is an extension to BSD sockets, the standard

把握自己。 3339

【AutoSAR】【以太网】TCP/IP 栈详述与配置

目录 一、TCP/IP栈架构 二、TCP\IP栈的可扩展性 三、以太网协议V4 四、以太网协议 V6 五、基于IP的协议 六、函数调用序列图 一、TCP/IP栈架构 根据以上架构图,该栈主要包括:UPD\TCP\DHCP\ICMP\IPV4\IPV6\ARP; 二、TCP\IP栈的可扩展性 TCP\IP栈为适应不同的应用场景需求,将分为三类: 配置工程里的配置项: 三、以太网协议V4 1 IPV4 Internet Protocol (IP)是T.

专注汽车软件开发、AutoSAR、车载以太网、SOA、EE架构。 5695

iOS网络编程之CFNetwork

一,CFNetwork 简介 首先来回顾下。在前文《[深入浅出Cocoa]iOS网络编程之Socket》中,提到iOS网络编程层次模型分为三层: Cocoa层:NSURL,Bonjour,Game Kit,WebKitCore Foundation层:基于 C 的 CFNetwork 和 CFNetServicesOS层:基于 C 的 BSD socket 前文讲的是最底

Ale 610

22、自动化地图制作与Pandas数据处理

本文介绍了在ArcGIS Pro中使用arcpy.mp模块进行自动化地图制作的关键技术,涵盖地图元素的访问、移动与文本修改,以及将布局批量导出为JPEG、PNG和PDF格式的方法。同时,文章深入探讨了Pandas在数据处理和地理空间分析中的应用,特别是Spatially Enabled DataFrames(SEDFs)的使用。通过综合案例展示了地图更新与数据清洗、分析的结合,提升了地图制作与数据处理的效率,为GIS自动化工作流提供了实用指南。

w8x9y0z1的博客 78

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

CFNetwork框架解析(一)

iOS网络编程层次模型分为三层: Cocoa层:NSURL, GameKit,WebKit Core Foundation层: 基于C的CFNetwork 和 CFNetServices OS层:基于C 的 BSD socket CFNetwork只是对BSD socket 进行了轻量级的封装,但在iOS中使用CFNetwork的好处是CFNetwork与系统级别的设置以及runloop结合很好,...

qq_28551705的博客 2844

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

cfnetwork php接口,IOS学习之 CoreFoundation框架的CFNetwork

1. iOS网络编程层次结构也分为三层:Cocoa层:NSURL,Bonjour,Game Kit,WebKitCore Foundation层:基于 C 的CFNetwork 和 CFNetServicesOS层:基于 C 的 BSD socketCocoa层是最上层的基于 Objective-C 的 API,比如 URL访问,NSStream,Bonjour,GameKit等,这是大多数情况下...

weixin_32288959的博客 164

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

iOS CFNetwork Concepts CFNetwork概念 官方文档翻译(三)

原文地址:developer CFNetwork概念 CFNetwork是一个低级的、高性能的框架,使您能够详细的控制协议栈。BSD套接字是一个扩展,提供对象的标准套接字抽象API来简化任务,比如与FTP和HTTP服务器或沟通解决DNS主机。CFNetwork为基础,从主体上和理论上,BSD套接字。 正如CFNetwork依赖于BSD套接字,有大量的Coc

wq820203420的专栏 1231

iOS开发之CFNetWork的简单使用

CFNetWork是苹果提供的位于 Core Foundation 中的一个基于C的底层框架,是对更底层OS层BSD socket的封装,著名的网络框架ASI网络请求方面就是对CFNetWork进行封装的。 CFNetWork主要依赖俩个API,CFSocket 和 CFStream,CFSocket主要用于网络底层的通信,而CFStream包括CFReadStream 和 CFWr

lin_transform的博客 709

CFNetWork

    CFNetWork             iOS网络编程层次模型分为三层: Cocoa层:NSURL,Bonjour,Game Kit,WebKit Core Foundation层:基于 C 的 CFNetwork 和 CFNetServices OS层:基于 C 的 BSD socket       CFNetwork是一种低层的高性能架构,它是基于BSD...

pupin9的专栏 369

CFNetwork编程指南(CFNetwork Programming Guide)

CFNetwork编程指南简介 CFNetwork是核心服务框架中的一个框架,提供了抽象概念的网络协议库。这些抽象感念使得执行各种网络任务变得更容易,例如: 使用BSD套接字使用SSL或TLS创建加密连接解析DNS主机使用HTTP,验证HTTP和HTTP服务器使用FTP服务器发布、解析和浏览Bonjour 服务(NSNetServices和CFNetServices编程指南中有讨论)。

小言的专栏 2667

CFNetwork

首先看张图:  此乃MAC OS X系统中CFNetwork和其余软件层的结构图。 CFNetwork位于底层,但高效地处理协议栈的操作。BSD套接字提供了一些标准对象来方便操作,如与FTP和HTTP服务器通信,解析DNS主机地址。而CFNetwork就是以BSD套接字为基础。 类似,一些cocoa类,如NSURL,使用标准网络协议与服务器通信,就是以CFNetwork为基础。 除

jackshiny的专栏 652
上一篇: iOS 图片排版 常用几个举例
下一篇: iOS网络编程之NSStream
FirstBloodFB
博客等级 码龄12年 7粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值