IOS socket编程--Asyncsocket

  1. iPhone的标准推荐是CFNetwork 库编程,其封装好的开源库是 cocoa AsyncSocket库,用它来简化CFNetwork的调用,它提供了异步操作
  2. 主要特性有:
  1. 队列的非阻塞的读和写,而且可选超时。你可以调用它读取和写入,它会当完成后告知你
  2. 自动的socket接收。如果你调用它接收连接,它将为每个连接启动新的实例,当然,也可以立即关闭这些连接
  3. 委托(delegate)支持。错误、连接、接收、完整的读取、完整的写入、进度以及断开连接,都可以通过委托模式调用
  4. 基于run loop的,而不是线程的。虽然可以在主线程或者工作线程中使用它,但你不需要这样做。它异步的调用委托方法,使用NSRunLoop。委托方法包括socket的参数,可让你在多个实例中区分
  5. 自包含在一个类中。你无需操作流或者socket,这个类帮你做了全部
  6. 支持基于IPV4和IPV6的TCP流
  1. 加入:AsynSocket.h .m与AsynUdpSocket.h .m四个文件 及CFNetwork.framework
  2. TCP客户端
  3. #import "AsyncSocket.h"
  4. @interface HelloiPhoneViewController : UIViewController {
  5. UITextField    * textField;
  6. AsyncSocket * asyncSocket;
  7. }
  8. @property (retain, nonatomic) IBOutlet UITextField *textField;
  9. - (IBAction) buttonPressed: (id)sender;
  10. - (IBAction) textFieldDoneEditing: (id)sender;
  11. @end
  12. 在需要联接地方使用connectToHost联接服务器
  13. 其中initWithDelegate的参数中self是必须。这个对象指针中的各个Socket响应的函数将被ASyncSocket所调用.initWithDelegate把将当前对象传递进去,这样只要在当前对象方法实现相应方法
  14. asyncSocket = [[AsyncSocket alloc] initWithDelegate:self];
  15. NSError *err = nil;
  16. if(![asyncSocket connectToHost:host on:port error:&err])
  17. {
  18. NSLog(@"Error: %@", err);
  19. }
  20. 关于NSData对象
  21. 无论SOCKET收发都采用NSData对象.它的定义是 http://developer.apple.com/library/mac /#documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/Reference/Reference.html
  22. NSData主要是带一个(id)data指向的数据空间和长度 length.
  23. NSString 转换成NSData 对象
  24. NSData* xmlData = [@"testdata" dataUsingEncoding:NSUTF8StringEncoding];
  25. NSData 转换成NSString对象
  26. NSData * data;
  27. NSString *result = [[NSString alloc] initWithData:data        encoding:NSUTF8StringEncoding];
  28. 发送数据
  29. AsyncSocket  writeData    方法来发送数据,它有如下定义
  30. - (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
  31. 以下是一个实例语句.
  32. NSData* aData= [@"test data" dataUsingEncoding: NSUTF8StringEncoding];
  33. [sock writeData:aData withTimeout:-1 tag:1];
  34. 在onSocket重载函数,有如定义采用是专门用来处理SOCKET的发送数据的:
  35. -(void)onSocket(AsyncSocket *)sock didWriteDataWithTag:(long)tag
  36. {
  37. NSLog(@"thread(%),onSocket:%p didWriteDataWithTag:%d",[[NSThread currentThread] name],
  38. sock,tag);
  39. }
  40. 接收Socket数据.
  41. 在onSocket重载函数,有如定义采用是专门用来处理SOCKET的接收数据的.
  42. -(void) onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
  43. 在中间将其转换成NSString进行显示.
  44. NSString* aStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
  45. NSLog(@"===%@",aStr);
  46. [aStr release];
  47. 6、TCP连接读取制定长度的数据
  48. socket连接,可能会读取固定长度的字节
  49. [socket readDataToLength: withTimeout :tag]
  50. 各方法的解析
  51. -(void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err;
  52. 发生错误,socket关闭,可以在call-back过程调用"unreadData"去取得socket的最后的数据字节,当连接的时候,该委托方法在    onSocket:didAcceptNewSocket: 或者 onSocket:didConnectToHost: 之前调用
  53. -(void)onSocketDidDisconnect:(ASyncSocket *)sock;
  54. 当socket由于或没有错误而断开连接,如果你想要在断开连接后release socket,在此方法工作,而在onSocket:willDisconnectWithError 释放则不安全
  55. -(void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket;
  56. 当产生一个socket去处理连接时调用,此方法会返回 线程上的run-loop 的新的socket和其应处理的委托,如果省略,则使用[NSRunLoop cunrrentRunLoop]
  57. -(BOOL)onSocketWillConnect:(AsyncSocket *)sock;
  58. -(void)onSocket:(AsyncSocket *)sock didConnectToHost :(NSString *)host port:(UINt16)port;
  59. 当socket连接正准备读和写的时候调用,host属性是一个IP地址,而不是一个DNS 名称
  60. -(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long) tag;
  61. 当socket已完成所要求的数据读入内存时调用,如果有错误则不调用
  62. -(void)onSocket:(Asyncsocket *)sock didReadPartialDataOfLength:(NSUInteger)partiaLength tag:(long)tag;
  63. 当一个socket读取数据,但尚未完成读操作的时候调用,如果使用 readToData: or readToLength: 方法 会发生,可以被用来更新进度条等东西
  64. -(void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag;
  65. 当一个socket已完成请求数据的写入时候调用
  66. -(void)onSocket:(AsyncSocket *)sock didWritePartialDataOfLength:(NSUInteger)partialLength tag:(long)tag;
  67. 当一个socket写入一些数据,但还没有完成整个写入时调用,它可以用来更新进度条等东西
  68. -(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutReadWithTag:(long)tag elapsed:(NSTimeInterval)exapsed bytesDone:(NSUInteger)length
  69. 使用读操作已超时但还没完成时调用,此方法允许随意延迟超时,如果返回一个正的时间间隔,读取的超时将有一定量的扩展,如果不实现这个方法,或会像往常一样返回一个负的时间间隔,elapsed参数是  原超时的总和,加上先前通过这种方法添加的任何补充, length参数是 读操作到目前为止已读取的字节数, 注意,如果返回正数的话,这个方法可能被一个单独的读取多次调用
  70. -(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutWriteWithTag:(long)tag elapsed:(NSTimeInterval)elapsed bytesDone:(NSUInteger)length;
  71. 如果一个写操作已达到其超时但还没完成时调用,同上
  72. -(void)onSocketDidSecure:(AsyncSocket *)sock;
  73. 在socket成功完成ssl/tls协商时调用,此方法除非你使用提供startTLS方法时候才调用,
  74. 如果ssl/tls是无效的证书,socket将会立即关闭,onSocket:willDisconnectWithError:代理方法竟会与特定的ssl错误代码一起调用
  75. -(BOOL)canSafelySetDelegate
  76. 用来查看在改变它之前,是否带有与当前的委托有悬而未决的业务(读/写)。当然,应在安全连接或接受委托之前改变委托
  77. 一旦接收或连接方法之一被调用,AsyncSocket实例会被锁定,其他接收/连接方法在没有先断开socket不会被调用
  78. 如果尝试失败或超时,这些方法要么返回NO 要么调用 onSocket:willDisconnectWithError: 或 onSockedDidDisconnect
  79. 当传入的连接被接受,AsyncSocket调用多个委托方法。这些方法按照时间顺序排列:
  80. 1.onSocket:didAcceptNewSocket:
  81. 2.onSocket:wantsRunLoopForNewSocket:
  82. 3. onSocketWillConnect:
  83. 你的服务器的代码将需要保留公认的socket(如果要接受它),最好的地方是要做到这一点可能在onSocket:didAcceptNewSocket:方法
  84. 在读和写流已经为新接受的socket设置,onSocket:didConnectToHost:port 方法将在适当的运行循环调用
  85. 多线程注意,如果要想通过实施onSocket:wantsRunLoopForNewSocket:,移动另一个新接受的socket去到另一个循环的socket。然后,应该在调用读和写或者startTLS方法前,等待直到onSocket:didConnectToHost:port:方法。否则读和写时间原定于不正确的runloop,混乱可能会随之而来
  86. -(BOOL)acceptOnPort:(UInit16)port error:(NSError **)errPtr;
  87. 告诉socket开始听取和接受制定端口上的连接,当一个连接到来的时候,AsyncSocket实例将调用各种委托方法,socket将听取所有可用的接口(wifi,以太网等)
  88. -(BOOL)connectToHost:(NSString *)hostname onPort:(UInt16)port error :(NSError **)errPtr;
  89. 连接给定的主机和端口,主机hostname可以是域名或者是Ip地址
  90. -(BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError *)errPtr;
  91. 连接到一个给定的地址,制定一个sockaddr结构包裹住一个NSData对象,例如,NSData对象从NSNetService的地址方法返回,如果有一个现有的sockaddr结构,可以将它转换到一个NSData对象,像这样:
  92. struct sockaddr sa  -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len];
  93. struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len];
  94. -(void)disconnect;
  95. 立即断开,任何未处理的读或写都将被丢弃
  96. 如果socket还没有断开,在这个方法返回之前,onSocketDidDisconnect 委托方法将会被立即调用
  97. 注意推荐释放AsyncSocket实例的方式:
  98. [asyncSocket setDelegate:nil];
  99. [asyncSocket disconnect];
  100. [asyncSocket release];
  101. -(void)disconnectAfterReading;
  102. 在已经完成了所有悬而未决的读取时 断开,在调用之后,读取和写入方法将无用,socket将断开 即使仍有待写入
  103. - (NSString *)connectedHost;
  104. - (UInt16)connectedPort;
  105. - (NSString *)localHost;
  106. - (UInt16)localPort;
  107. 返回本地和远程主机和端口给连接的socket,如果没有连接会返回nil或0,主机将会是一个IP地址
  108. -(NSData *)connectedAddress
  109. -(NSData *)localAddresss
  110. 返回本地和远程的地址给连接的socket,指定一个socketaddr结构包裹在一个NSData对象
  111. readData和writeData方法不会是block(它们是异步的)
  112. 当读完成 onSocket:didReadData:withTag: 委托方法时调用
  113. 当写完成 onSocket:didWriteDataWithTag: 委托方法时调用
  114. 可以选择任何读/写操作的超时设置(为了不超时,使用负时间间隔。)
  115. 如果读/写操作超时,相应的 onSocket:shouldTimeout...委托方法被调用去选择性地允许我们去延长超时
  116. 超时后,onSocket:willDisconnectWithError: 方法被调用,紧接着是 onSocketDidDisconnect
  117. tag是为了方便,可以使用它作为数组的索引、步数、state id 、指针等
  118. -(void)readDataWithTimeout:(NSTimeInterval)tiemout tag:(long)tag;
  119. 读取socket上第一次成为可用的字节,如果timeout值是负数的,读操作将不使用timeout
  120. - (void)readDataWithTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInterger)offset tag:(long)tag;
  121. 读取socket上第一次成为可用的字节
  122. 字节将被追加到给定的字节缓冲区,从给定的偏移量开始
  123. 如果需要,给定的缓冲区大小将会自动增加
  124. 如果timeout值是负数的,读操作将不使用timeout
  125. 如果缓冲区为空,socket会为我们创建一个缓冲区
  126. 如果bufferOffset是大于给定的缓冲区的长度,该方法将无用,委托将不会被调用
  127. 如果你传递一个缓冲区,当AsyncSocket在使用它的时候你不能以任何方式改变它
  128. 完成之后,onSocket:didReadData:withTag 返回的数据将是一个给定的缓冲区的子集
  129. 也就是说,它将会被引用到被追加的给定的缓冲区的字节
  130. -(void)readDataToLength:(NSUInterger)length withTimeout:(NSTimeInterval)timeout tag:(long)tag;
  131. 读取给定的字节数,如果length为0,方法将无用,委托将不会被调用
  132. -(void)readDataToLength:(NSUInteger)length withTimeout:(NSTimeInterval)tiemout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
  133. 读取给定的字节数,在给定的偏移开始,字节将被追加到给定的字节缓冲区
  134. -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
  135. 读取字节直到(包括)传入的作为分隔的"data"参数
  136. 如果传递0或者0长度的数据,"data"参数,该方法将无用,委托将不会被调用
  137. 从socket读取一行,使用"data"参数作为行的分隔符 (如HTTP的CRLF)
  138. 注意,此方法不是字符集,因此,如果一个分隔符出现,它自然可以作为进行编码的一部分,读取将提前结束
  139. -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
  140. 读取字节直到(包括)传入的作为分隔的“data”参数,在给定的偏移量开始,字节将被追加到给定的字节缓冲区。
  141. 从socket读取一行,使用"data"参数作为行的分隔符(如HTTP的CRLF)
  142. -(void)writeData:(NSData *)data withTimeout:(NSTimeInterval) timeout tag:(long)tag;
  143. 将data写入socket,当完成的时候委托被调用
  144. - (float)progressOfReadReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
  145. - (float)progressOfWriteReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
  146. 返回当前读或写的进度,从0.0 到 1.0 或者 如果没有读/写的时候返回Nan(使用isNan来检查)
  147. tag、done、total如果不为空的话,它们将会被填补
  148. - (void)startTLS:(NSDictionary *)tlsSettings;
  149. 确保使用ssl/tls连接
  150. 这方法可被随时调用,tls握手将会发生在所有悬而未决的读/写完成之后。这紧跟着一个发送依赖 StartTLS消息的协议选项,在排队升级到TLS的同一时间,而不必等待写入完成。在这个方法被调用后,任何读写计划 将会发生在安全链接
  151. 对于可能的keys和TLS设置的值是有据可查的
  152. 一些可能的keys是:
  153. * - kCFStreamSSLLevel
  154. * - kCFStreamSSLAllowsExpiredCertificates
  155. * - kCFStreamSSLAllowsExpiredRoots
  156. * - kCFStreamSSLAllowsAnyRoot
  157. * - kCFStreamSSLValidatesCertificateChain
  158. * - kCFStreamSSLPeerName
  159. * - kCFStreamSSLCertificates
  160. * - kCFStreamSSLIsServer
  161. 如果你传递空或者空字典,将使用默认的字典
  162. 默认设置将检查以确保由签署可信的第三方证书机构和没有过期的远程连接的证书
  163. 然而,它不会验证证书上的名字,除非你给它一个名字,通过kCFStreamSSLPeerName键去验证
  164. 这对安全的影响是重要的理解
  165. 想象一下你正试图创建一个到MySecureServer.com的安全连接,但因为一个被攻击的DNS服务器,所以你的socket被定向到MaliciousServer.com
  166. 如果你只是使用默认设置,MaliciousServer.com 有一个有效的证书
  167. 默认设置将无法监测到任何问题,因为证书是有效的
  168. 在这个特殊的情况下,要妥善保护你的连接,应设置kCFStreamSSLPeerName性质为MySecureServer.com.
  169. 如果事前你不知道对等的名字的远程主机(例如,你不确认它是domain.com" or "www.domain.com"),那么你可以使用默认设置来验证证书,然后在获得验证的发行后使用X509Certificate类来验证,X509Certificate类的CocoaAsyncSocket开源项目的一部分
  170. -(void)enablePrebuffering
  171. 对于处理readDataToData请求,数据是必须从socket以小增量的方式读取出来的
  172. 性能通过允许AsyncSocket去一次性读大块的数据和存储任何一个小的内部缓冲区溢出的东西来大大提高
  173. 这被称为预缓冲,就好像一些数据在你要求它之前就可能被读取出来
  174. 如果你经常使用readDataToData,使用预缓冲会有更好的性能,尤其是在iphone上
  175. 默认的预缓冲状态是由DEFAULT_PREBUFFERING 定义控制的,强烈建议设置其为yes
  176. 这方法存在一些预缓冲需要一些不可预见的原因被默认禁用的情况,这时,这种方法存在允许当就绪时,可轻松启用预缓冲
  177. -(BOOL)moveToRunLoop:(NSRunLoop *)runLoop;
  178. 当你创建一个AsyncSocket,它被添加到当前线程runloop
  179. 对于手动创建的socket,在线程上你打算使用它,它是最容易简单的创建的线程上的socket
  180. 当一个新的socket被接受,委托方法 onSocket:wantsRunLoopForNewSocket 会被调用 允许你在一个单独的线程上放置socket,这个工作最好结合在同一个线程池设计
  181. 如果,但是,在一个单独的线程上,在之后的时间,你需要移动一个socket,这个方法可以用来完成任务
  182. 此方法必须从 当前运行的 线程/runloop 的socket 调用
  183. 注意:此方法调用后,所有进一步的方法应该从给定的runloop上调用这个对象
  184. 此外,所有委托调用将会发送到给定的runloop
  185. - (BOOL)setRunLoopModes:(NSArray *)runLoopModes;
  186. - (BOOL)addRunLoopMode:(NSString *)runLoopMode;
  187. - (BOOL)removeRunLoopMode:(NSString *)runLoopMode;
  188. 允许你配置 socket 使用的 运行循环模式
  189. 运行循环模式设置默认是NSRunLoopCommonModes
  190. 如果你想你的socket 在其他模式下继续操作,你可能需要添加模式 NSModalPanelRunLoopMode 或者 NSEventTrackingRunLoopMode ,或者你可能只想使用 NSRunLoopCommonModes
  191. 可接受的socket将自动 继承相同的运行循环模式就像侦听socket
  192. 注意:NSRunLoopCommonModes 定义在10.5,对于之前的版本可使用 kCFRunLoopCommonModes
  193. -(NSArray *)runLoopModes
  194. 返回当前正在运行的循环模式的AsyncSocket实例, run loop modes的默认设置是NSDefaultRunLoopMode
  195. -(NSData *)unreadData;
  196. 一个错误的事件,在 onSocket:willDisconnectWithError: 将会被调用 去读取留在socket上的任何数据
  197. + (NSData *)CRLFData;   // 0x0D0A
  198. 各方法的解析
  199. -(void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err;
  200. 发生错误,socket关闭,可以在call-back过程调用"unreadData"去取得socket的最后的数据字节,当连接的时候,该委托方法在    onSocket:didAcceptNewSocket: 或者 onSocket:didConnectToHost: 之前调用
  201. -(void)onSocketDidDisconnect:(ASyncSocket *)sock;
  202. 当socket由于或没有错误而断开连接,如果你想要在断开连接后release socket,在此方法工作,而在onSocket:willDisconnectWithError 释放则不安全
  203. -(void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket;
  204. 当产生一个socket去处理连接时调用,此方法会返回 线程上的run-loop 的新的socket和其应处理的委托,如果省略,则使用[NSRunLoop cunrrentRunLoop]
  205. -(BOOL)onSocketWillConnect:(AsyncSocket *)sock;
  206. -(void)onSocket:(AsyncSocket *)sock didConnectToHost :(NSString *)host port:(UINt16)port;
  207. 当socket连接正准备读和写的时候调用,host属性是一个IP地址,而不是一个DNS 名称
  208. -(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long) tag;
  209. 当socket已完成所要求的数据读入内存时调用,如果有错误则不调用
  210. -(void)onSocket:(Asyncsocket *)sock didReadPartialDataOfLength:(NSUInteger)partiaLength tag:(long)tag;
  211. 当一个socket读取数据,但尚未完成读操作的时候调用,如果使用 readToData: or readToLength: 方法 会发生,可以被用来更新进度条等东西
  212. -(void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag;
  213. 当一个socket已完成请求数据的写入时候调用
  214. -(void)onSocket:(AsyncSocket *)sock didWritePartialDataOfLength:(NSUInteger)partialLength tag:(long)tag;
  215. 当一个socket写入一些数据,但还没有完成整个写入时调用,它可以用来更新进度条等东西
  216. -(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutReadWithTag:(long)tag elapsed:(NSTimeInterval)exapsed bytesDone:(NSUInteger)length
  217. 使用读操作已超时但还没完成时调用,此方法允许随意延迟超时,如果返回一个正的时间间隔,读取的超时将有一定量的扩展,如果不实现这个方法,或会像往常一样返回一个负的时间间隔,elapsed参数是  原超时的总和,加上先前通过这种方法添加的任何补充, length参数是 读操作到目前为止已读取的字节数, 注意,如果返回正数的话,这个方法可能被一个单独的读取多次调用
  218. -(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutWriteWithTag:(long)tag elapsed:(NSTimeInterval)elapsed bytesDone:(NSUInteger)length;
  219. 如果一个写操作已达到其超时但还没完成时调用,同上
  220. -(void)onSocketDidSecure:(AsyncSocket *)sock;
  221. 在socket成功完成ssl/tls协商时调用,此方法除非你使用提供startTLS方法时候才调用,
  222. 如果ssl/tls是无效的证书,socket将会立即关闭,onSocket:willDisconnectWithError:代理方法竟会与特定的ssl错误代码一起调用
  223. -(BOOL)canSafelySetDelegate
  224. 用来查看在改变它之前,是否带有与当前的委托有悬而未决的业务(读/写)。当然,应在安全连接或接受委托之前改变委托
  225. 一旦接收或连接方法之一被调用,AsyncSocket实例会被锁定,其他接收/连接方法在没有先断开socket不会被调用
  226. 如果尝试失败或超时,这些方法要么返回NO 要么调用 onSocket:willDisconnectWithError: 或 onSockedDidDisconnect
  227. 当传入的连接被接受,AsyncSocket调用多个委托方法。这些方法按照时间顺序排列:
  228. 1.onSocket:didAcceptNewSocket:
  229. 2.onSocket:wantsRunLoopForNewSocket:
  230. 3. onSocketWillConnect:
  231. 你的服务器的代码将需要保留公认的socket(如果要接受它),最好的地方是要做到这一点可能在onSocket:didAcceptNewSocket:方法
  232. 在读和写流已经为新接受的socket设置,onSocket:didConnectToHost:port 方法将在适当的运行循环调用
  233. 多线程注意,如果要想通过实施onSocket:wantsRunLoopForNewSocket:,移动另一个新接受的socket去到另一个循环的socket。然后,应该在调用读和写或者startTLS方法前,等待直到onSocket:didConnectToHost:port:方法。否则读和写时间原定于不正确的runloop,混乱可能会随之而来
  234. -(BOOL)acceptOnPort:(UInit16)port error:(NSError **)errPtr;
  235. 告诉socket开始听取和接受制定端口上的连接,当一个连接到来的时候,AsyncSocket实例将调用各种委托方法,socket将听取所有可用的接口(wifi,以太网等)
  236. -(BOOL)connectToHost:(NSString *)hostname onPort:(UInt16)port error :(NSError **)errPtr;
  237. 连接给定的主机和端口,主机hostname可以是域名或者是Ip地址
  238. -(BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError *)errPtr;
  239. 连接到一个给定的地址,制定一个sockaddr结构包裹住一个NSData对象,例如,NSData对象从NSNetService的地址方法返回,如果有一个现有的sockaddr结构,可以将它转换到一个NSData对象,像这样:
  240. struct sockaddr sa  -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len];
  241. struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len];
  242. -(void)disconnect;
  243. 立即断开,任何未处理的读或写都将被丢弃
  244. 如果socket还没有断开,在这个方法返回之前,onSocketDidDisconnect 委托方法将会被立即调用
  245. 注意推荐释放AsyncSocket实例的方式:
  246. [asyncSocket setDelegate:nil];
  247. [asyncSocket disconnect];
  248. [asyncSocket release];
  249. -(void)disconnectAfterReading;
  250. 在已经完成了所有悬而未决的读取时 断开,在调用之后,读取和写入方法将无用,socket将断开 即使仍有待写入
  251. - (NSString *)connectedHost;
  252. - (UInt16)connectedPort;
  253. - (NSString *)localHost;
  254. - (UInt16)localPort;
  255. 返回本地和远程主机和端口给连接的socket,如果没有连接会返回nil或0,主机将会是一个IP地址
  256. -(NSData *)connectedAddress
  257. -(NSData *)localAddresss
  258. 返回本地和远程的地址给连接的socket,指定一个socketaddr结构包裹在一个NSData对象
  259. readData和writeData方法不会是block(它们是异步的)
  260. 当读完成 onSocket:didReadData:withTag: 委托方法时调用
  261. 当写完成 onSocket:didWriteDataWithTag: 委托方法时调用
  262. 可以选择任何读/写操作的超时设置(为了不超时,使用负时间间隔。)
  263. 如果读/写操作超时,相应的 onSocket:shouldTimeout...委托方法被调用去选择性地允许我们去延长超时
  264. 超时后,onSocket:willDisconnectWithError: 方法被调用,紧接着是 onSocketDidDisconnect
  265. tag是为了方便,可以使用它作为数组的索引、步数、state id 、指针等
  266. -(void)readDataWithTimeout:(NSTimeInterval)tiemout tag:(long)tag;
  267. 读取socket上第一次成为可用的字节,如果timeout值是负数的,读操作将不使用timeout
  268. - (void)readDataWithTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInterger)offset tag:(long)tag;
  269. 读取socket上第一次成为可用的字节
  270. 字节将被追加到给定的字节缓冲区,从给定的偏移量开始
  271. 如果需要,给定的缓冲区大小将会自动增加
  272. 如果timeout值是负数的,读操作将不使用timeout
  273. 如果缓冲区为空,socket会为我们创建一个缓冲区
  274. 如果bufferOffset是大于给定的缓冲区的长度,该方法将无用,委托将不会被调用
  275. 如果你传递一个缓冲区,当AsyncSocket在使用它的时候你不能以任何方式改变它
  276. 完成之后,onSocket:didReadData:withTag 返回的数据将是一个给定的缓冲区的子集
  277. 也就是说,它将会被引用到被追加的给定的缓冲区的字节
  278. -(void)readDataToLength:(NSUInterger)length withTimeout:(NSTimeInterval)timeout tag:(long)tag;
  279. 读取给定的字节数,如果length为0,方法将无用,委托将不会被调用
  280. -(void)readDataToLength:(NSUInteger)length withTimeout:(NSTimeInterval)tiemout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
  281. 读取给定的字节数,在给定的偏移开始,字节将被追加到给定的字节缓冲区
  282. -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
  283. 读取字节直到(包括)传入的作为分隔的"data"参数
  284. 如果传递0或者0长度的数据,"data"参数,该方法将无用,委托将不会被调用
  285. 从socket读取一行,使用"data"参数作为行的分隔符 (如HTTP的CRLF)
  286. 注意,此方法不是字符集,因此,如果一个分隔符出现,它自然可以作为进行编码的一部分,读取将提前结束
  287. -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
  288. 读取字节直到(包括)传入的作为分隔的“data”参数,在给定的偏移量开始,字节将被追加到给定的字节缓冲区。
  289. 从socket读取一行,使用"data"参数作为行的分隔符(如HTTP的CRLF)
  290. -(void)writeData:(NSData *)data withTimeout:(NSTimeInterval) timeout tag:(long)tag;
  291. 将data写入socket,当完成的时候委托被调用
  292. - (float)progressOfReadReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
  293. - (float)progressOfWriteReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
  294. 返回当前读或写的进度,从0.0 到 1.0 或者 如果没有读/写的时候返回Nan(使用isNan来检查)
  295. tag、done、total如果不为空的话,它们将会被填补
  296. - (void)startTLS:(NSDictionary *)tlsSettings;
  297. 确保使用ssl/tls连接
  298. 这方法可被随时调用,tls握手将会发生在所有悬而未决的读/写完成之后。这紧跟着一个发送依赖 StartTLS消息的协议选项,在排队升级到TLS的同一时间,而不必等待写入完成。在这个方法被调用后,任何读写计划 将会发生在安全链接
  299. 对于可能的keys和TLS设置的值是有据可查的
  300. 一些可能的keys是:
  301. * - kCFStreamSSLLevel
  302. * - kCFStreamSSLAllowsExpiredCertificates
  303. * - kCFStreamSSLAllowsExpiredRoots
  304. * - kCFStreamSSLAllowsAnyRoot
  305. * - kCFStreamSSLValidatesCertificateChain
  306. * - kCFStreamSSLPeerName
  307. * - kCFStreamSSLCertificates
  308. * - kCFStreamSSLIsServer
  309. 如果你传递空或者空字典,将使用默认的字典
  310. 默认设置将检查以确保由签署可信的第三方证书机构和没有过期的远程连接的证书
  311. 然而,它不会验证证书上的名字,除非你给它一个名字,通过kCFStreamSSLPeerName键去验证
  312. 这对安全的影响是重要的理解
  313. 想象一下你正试图创建一个到MySecureServer.com的安全连接,但因为一个被攻击的DNS服务器,所以你的socket被定向到MaliciousServer.com
  314. 如果你只是使用默认设置,MaliciousServer.com 有一个有效的证书
  315. 默认设置将无法监测到任何问题,因为证书是有效的
  316. 在这个特殊的情况下,要妥善保护你的连接,应设置kCFStreamSSLPeerName性质为MySecureServer.com.
  317. 如果事前你不知道对等的名字的远程主机(例如,你不确认它是domain.com" or "www.domain.com"),那么你可以使用默认设置来验证证书,然后在获得验证的发行后使用X509Certificate类来验证,X509Certificate类的CocoaAsyncSocket开源项目的一部分
  318. -(void)enablePrebuffering
  319. 对于处理readDataToData请求,数据是必须从socket以小增量的方式读取出来的
  320. 性能通过允许AsyncSocket去一次性读大块的数据和存储任何一个小的内部缓冲区溢出的东西来大大提高
  321. 这被称为预缓冲,就好像一些数据在你要求它之前就可能被读取出来
  322. 如果你经常使用readDataToData,使用预缓冲会有更好的性能,尤其是在iphone上
  323. 默认的预缓冲状态是由DEFAULT_PREBUFFERING 定义控制的,强烈建议设置其为yes
  324. 这方法存在一些预缓冲需要一些不可预见的原因被默认禁用的情况,这时,这种方法存在允许当就绪时,可轻松启用预缓冲
  325. -(BOOL)moveToRunLoop:(NSRunLoop *)runLoop;
  326. 当你创建一个AsyncSocket,它被添加到当前线程runloop
  327. 对于手动创建的socket,在线程上你打算使用它,它是最容易简单的创建的线程上的socket
  328. 当一个新的socket被接受,委托方法 onSocket:wantsRunLoopForNewSocket 会被调用 允许你在一个单独的线程上放置socket,这个工作最好结合在同一个线程池设计
  329. 如果,但是,在一个单独的线程上,在之后的时间,你需要移动一个socket,这个方法可以用来完成任务
  330. 此方法必须从 当前运行的 线程/runloop 的socket 调用
  331. 注意:此方法调用后,所有进一步的方法应该从给定的runloop上调用这个对象
  332. 此外,所有委托调用将会发送到给定的runloop
  333. - (BOOL)setRunLoopModes:(NSArray *)runLoopModes;
  334. - (BOOL)addRunLoopMode:(NSString *)runLoopMode;
  335. - (BOOL)removeRunLoopMode:(NSString *)runLoopMode;
  336. 允许你配置 socket 使用的 运行循环模式
  337. 运行循环模式设置默认是NSRunLoopCommonModes
  338. 如果你想你的socket 在其他模式下继续操作,你可能需要添加模式 NSModalPanelRunLoopMode 或者 NSEventTrackingRunLoopMode ,或者你可能只想使用 NSRunLoopCommonModes
  339. 可接受的socket将自动 继承相同的运行循环模式就像侦听socket
  340. 注意:NSRunLoopCommonModes 定义在10.5,对于之前的版本可使用 kCFRunLoopCommonModes
  341. -(NSArray *)runLoopModes
  342. 返回当前正在运行的循环模式的AsyncSocket实例, run loop modes的默认设置是NSDefaultRunLoopMode
  343. -(NSData *)unreadData;
  344. 一个错误的事件,在 onSocket:willDisconnectWithError: 将会被调用 去读取留在socket上的任何数据
  345. + (NSData *)CRLFData;   // 0x0D0A
  346. 各方法的解析
  347. -(void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err;
  348. 发生错误,socket关闭,可以在call-back过程调用"unreadData"去取得socket的最后的数据字节,当连接的时候,该委托方法在    onSocket:didAcceptNewSocket: 或者 onSocket:didConnectToHost: 之前调用
  349. -(void)onSocketDidDisconnect:(ASyncSocket *)sock;
  350. 当socket由于或没有错误而断开连接,如果你想要在断开连接后release socket,在此方法工作,而在onSocket:willDisconnectWithError 释放则不安全
  351. -(void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket;
  352. 当产生一个socket去处理连接时调用,此方法会返回 线程上的run-loop 的新的socket和其应处理的委托,如果省略,则使用[NSRunLoop cunrrentRunLoop]
  353. -(BOOL)onSocketWillConnect:(AsyncSocket *)sock;
  354. -(void)onSocket:(AsyncSocket *)sock didConnectToHost :(NSString *)host port:(UINt16)port;
  355. 当socket连接正准备读和写的时候调用,host属性是一个IP地址,而不是一个DNS 名称
  356. -(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long) tag;
  357. 当socket已完成所要求的数据读入内存时调用,如果有错误则不调用
  358. -(void)onSocket:(Asyncsocket *)sock didReadPartialDataOfLength:(NSUInteger)partiaLength tag:(long)tag;
  359. 当一个socket读取数据,但尚未完成读操作的时候调用,如果使用 readToData: or readToLength: 方法 会发生,可以被用来更新进度条等东西
  360. -(void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag;
  361. 当一个socket已完成请求数据的写入时候调用
  362. -(void)onSocket:(AsyncSocket *)sock didWritePartialDataOfLength:(NSUInteger)partialLength tag:(long)tag;
  363. 当一个socket写入一些数据,但还没有完成整个写入时调用,它可以用来更新进度条等东西
  364. -(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutReadWithTag:(long)tag elapsed:(NSTimeInterval)exapsed bytesDone:(NSUInteger)length
  365. 使用读操作已超时但还没完成时调用,此方法允许随意延迟超时,如果返回一个正的时间间隔,读取的超时将有一定量的扩展,如果不实现这个方法,或会像往常一样返回一个负的时间间隔,elapsed参数是  原超时的总和,加上先前通过这种方法添加的任何补充, length参数是 读操作到目前为止已读取的字节数, 注意,如果返回正数的话,这个方法可能被一个单独的读取多次调用
  366. -(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutWriteWithTag:(long)tag elapsed:(NSTimeInterval)elapsed bytesDone:(NSUInteger)length;
  367. 如果一个写操作已达到其超时但还没完成时调用,同上
  368. -(void)onSocketDidSecure:(AsyncSocket *)sock;
  369. 在socket成功完成ssl/tls协商时调用,此方法除非你使用提供startTLS方法时候才调用,
  370. 如果ssl/tls是无效的证书,socket将会立即关闭,onSocket:willDisconnectWithError:代理方法竟会与特定的ssl错误代码一起调用
  371. -(BOOL)canSafelySetDelegate
  372. 用来查看在改变它之前,是否带有与当前的委托有悬而未决的业务(读/写)。当然,应在安全连接或接受委托之前改变委托
  373. 一旦接收或连接方法之一被调用,AsyncSocket实例会被锁定,其他接收/连接方法在没有先断开socket不会被调用
  374. 如果尝试失败或超时,这些方法要么返回NO 要么调用 onSocket:willDisconnectWithError: 或 onSockedDidDisconnect
  375. 当传入的连接被接受,AsyncSocket调用多个委托方法。这些方法按照时间顺序排列:
  376. 1.onSocket:didAcceptNewSocket:
  377. 2.onSocket:wantsRunLoopForNewSocket:
  378. 3. onSocketWillConnect:
  379. 你的服务器的代码将需要保留公认的socket(如果要接受它),最好的地方是要做到这一点可能在onSocket:didAcceptNewSocket:方法
  380. 在读和写流已经为新接受的socket设置,onSocket:didConnectToHost:port 方法将在适当的运行循环调用
  381. 多线程注意,如果要想通过实施onSocket:wantsRunLoopForNewSocket:,移动另一个新接受的socket去到另一个循环的socket。然后,应该在调用读和写或者startTLS方法前,等待直到onSocket:didConnectToHost:port:方法。否则读和写时间原定于不正确的runloop,混乱可能会随之而来
  382. -(BOOL)acceptOnPort:(UInit16)port error:(NSError **)errPtr;
  383. 告诉socket开始听取和接受制定端口上的连接,当一个连接到来的时候,AsyncSocket实例将调用各种委托方法,socket将听取所有可用的接口(wifi,以太网等)
  384. -(BOOL)connectToHost:(NSString *)hostname onPort:(UInt16)port error :(NSError **)errPtr;
  385. 连接给定的主机和端口,主机hostname可以是域名或者是Ip地址
  386. -(BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError *)errPtr;
  387. 连接到一个给定的地址,制定一个sockaddr结构包裹住一个NSData对象,例如,NSData对象从NSNetService的地址方法返回,如果有一个现有的sockaddr结构,可以将它转换到一个NSData对象,像这样:
  388. struct sockaddr sa  -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len];
  389. struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len];
  390. -(void)disconnect;
  391. 立即断开,任何未处理的读或写都将被丢弃
  392. 如果socket还没有断开,在这个方法返回之前,onSocketDidDisconnect 委托方法将会被立即调用
  393. 注意推荐释放AsyncSocket实例的方式:
  394. [asyncSocket setDelegate:nil];
  395. [asyncSocket disconnect];
  396. [asyncSocket release];
  397. -(void)disconnectAfterReading;
  398. 在已经完成了所有悬而未决的读取时 断开,在调用之后,读取和写入方法将无用,socket将断开 即使仍有待写入
  399. - (NSString *)connectedHost;
  400. - (UInt16)connectedPort;
  401. - (NSString *)localHost;
  402. - (UInt16)localPort;
  403. 返回本地和远程主机和端口给连接的socket,如果没有连接会返回nil或0,主机将会是一个IP地址
  404. -(NSData *)connectedAddress
  405. -(NSData *)localAddresss
  406. 返回本地和远程的地址给连接的socket,指定一个socketaddr结构包裹在一个NSData对象
  407. readData和writeData方法不会是block(它们是异步的)
  408. 当读完成 onSocket:didReadData:withTag: 委托方法时调用
  409. 当写完成 onSocket:didWriteDataWithTag: 委托方法时调用
  410. 可以选择任何读/写操作的超时设置(为了不超时,使用负时间间隔。)
  411. 如果读/写操作超时,相应的 onSocket:shouldTimeout...委托方法被调用去选择性地允许我们去延长超时
  412. 超时后,onSocket:willDisconnectWithError: 方法被调用,紧接着是 onSocketDidDisconnect
  413. tag是为了方便,可以使用它作为数组的索引、步数、state id 、指针等
  414. -(void)readDataWithTimeout:(NSTimeInterval)tiemout tag:(long)tag;
  415. 读取socket上第一次成为可用的字节,如果timeout值是负数的,读操作将不使用timeout
  416. - (void)readDataWithTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInterger)offset tag:(long)tag;
  417. 读取socket上第一次成为可用的字节
  418. 字节将被追加到给定的字节缓冲区,从给定的偏移量开始
  419. 如果需要,给定的缓冲区大小将会自动增加
  420. 如果timeout值是负数的,读操作将不使用timeout
  421. 如果缓冲区为空,socket会为我们创建一个缓冲区
  422. 如果bufferOffset是大于给定的缓冲区的长度,该方法将无用,委托将不会被调用
  423. 如果你传递一个缓冲区,当AsyncSocket在使用它的时候你不能以任何方式改变它
  424. 完成之后,onSocket:didReadData:withTag 返回的数据将是一个给定的缓冲区的子集
  425. 也就是说,它将会被引用到被追加的给定的缓冲区的字节
  426. -(void)readDataToLength:(NSUInterger)length withTimeout:(NSTimeInterval)timeout tag:(long)tag;
  427. 读取给定的字节数,如果length为0,方法将无用,委托将不会被调用
  428. -(void)readDataToLength:(NSUInteger)length withTimeout:(NSTimeInterval)tiemout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
  429. 读取给定的字节数,在给定的偏移开始,字节将被追加到给定的字节缓冲区
  430. -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
  431. 读取字节直到(包括)传入的作为分隔的"data"参数
  432. 如果传递0或者0长度的数据,"data"参数,该方法将无用,委托将不会被调用
  433. 从socket读取一行,使用"data"参数作为行的分隔符 (如HTTP的CRLF)
  434. 注意,此方法不是字符集,因此,如果一个分隔符出现,它自然可以作为进行编码的一部分,读取将提前结束
  435. -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
  436. 读取字节直到(包括)传入的作为分隔的“data”参数,在给定的偏移量开始,字节将被追加到给定的字节缓冲区。
  437. 从socket读取一行,使用"data"参数作为行的分隔符(如HTTP的CRLF)
  438. -(void)writeData:(NSData *)data withTimeout:(NSTimeInterval) timeout tag:(long)tag;
  439. 将data写入socket,当完成的时候委托被调用
  440. - (float)progressOfReadReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
  441. - (float)progressOfWriteReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
  442. 返回当前读或写的进度,从0.0 到 1.0 或者 如果没有读/写的时候返回Nan(使用isNan来检查)
  443. tag、done、total如果不为空的话,它们将会被填补
  444. - (void)startTLS:(NSDictionary *)tlsSettings;
  445. 确保使用ssl/tls连接
  446. 这方法可被随时调用,tls握手将会发生在所有悬而未决的读/写完成之后。这紧跟着一个发送依赖 StartTLS消息的协议选项,在排队升级到TLS的同一时间,而不必等待写入完成。在这个方法被调用后,任何读写计划 将会发生在安全链接
  447. 对于可能的keys和TLS设置的值是有据可查的
  448. 一些可能的keys是:
  449. * - kCFStreamSSLLevel
  450. * - kCFStreamSSLAllowsExpiredCertificates
  451. * - kCFStreamSSLAllowsExpiredRoots
  452. * - kCFStreamSSLAllowsAnyRoot
  453. * - kCFStreamSSLValidatesCertificateChain
  454. * - kCFStreamSSLPeerName
  455. * - kCFStreamSSLCertificates
  456. * - kCFStreamSSLIsServer
  457. 如果你传递空或者空字典,将使用默认的字典
  458. 默认设置将检查以确保由签署可信的第三方证书机构和没有过期的远程连接的证书
  459. 然而,它不会验证证书上的名字,除非你给它一个名字,通过kCFStreamSSLPeerName键去验证
  460. 这对安全的影响是重要的理解
  461. 想象一下你正试图创建一个到MySecureServer.com的安全连接,但因为一个被攻击的DNS服务器,所以你的socket被定向到MaliciousServer.com
  462. 如果你只是使用默认设置,MaliciousServer.com 有一个有效的证书
  463. 默认设置将无法监测到任何问题,因为证书是有效的
  464. 在这个特殊的情况下,要妥善保护你的连接,应设置kCFStreamSSLPeerName性质为MySecureServer.com.
  465. 如果事前你不知道对等的名字的远程主机(例如,你不确认它是domain.com" or "www.domain.com"),那么你可以使用默认设置来验证证书,然后在获得验证的发行后使用X509Certificate类来验证,X509Certificate类的CocoaAsyncSocket开源项目的一部分
  466. -(void)enablePrebuffering
  467. 对于处理readDataToData请求,数据是必须从socket以小增量的方式读取出来的
  468. 性能通过允许AsyncSocket去一次性读大块的数据和存储任何一个小的内部缓冲区溢出的东西来大大提高
  469. 这被称为预缓冲,就好像一些数据在你要求它之前就可能被读取出来
  470. 如果你经常使用readDataToData,使用预缓冲会有更好的性能,尤其是在iphone上
  471. 默认的预缓冲状态是由DEFAULT_PREBUFFERING 定义控制的,强烈建议设置其为yes
  472. 这方法存在一些预缓冲需要一些不可预见的原因被默认禁用的情况,这时,这种方法存在允许当就绪时,可轻松启用预缓冲
  473. -(BOOL)moveToRunLoop:(NSRunLoop *)runLoop;
  474. 当你创建一个AsyncSocket,它被添加到当前线程runloop
  475. 对于手动创建的socket,在线程上你打算使用它,它是最容易简单的创建的线程上的socket
  476. 当一个新的socket被接受,委托方法 onSocket:wantsRunLoopForNewSocket 会被调用 允许你在一个单独的线程上放置socket,这个工作最好结合在同一个线程池设计
  477. 如果,但是,在一个单独的线程上,在之后的时间,你需要移动一个socket,这个方法可以用来完成任务
  478. 此方法必须从 当前运行的 线程/runloop 的socket 调用
  479. 注意:此方法调用后,所有进一步的方法应该从给定的runloop上调用这个对象
  480. 此外,所有委托调用将会发送到给定的runloop
  481. - (BOOL)setRunLoopModes:(NSArray *)runLoopModes;
  482. - (BOOL)addRunLoopMode:(NSString *)runLoopMode;
  483. - (BOOL)removeRunLoopMode:(NSString *)runLoopMode;
  484. 允许你配置 socket 使用的 运行循环模式
  485. 运行循环模式设置默认是NSRunLoopCommonModes
  486. 如果你想你的socket 在其他模式下继续操作,你可能需要添加模式 NSModalPanelRunLoopMode 或者 NSEventTrackingRunLoopMode ,或者你可能只想使用 NSRunLoopCommonModes
  487. 可接受的socket将自动 继承相同的运行循环模式就像侦听socket
  488. 注意:NSRunLoopCommonModes 定义在10.5,对于之前的版本可使用 kCFRunLoopCommonModes
  489. -(NSArray *)runLoopModes
  490. 返回当前正在运行的循环模式的AsyncSocket实例, run loop modes的默认设置是NSDefaultRunLoopMode
  491. -(NSData *)unreadData;
  492. 一个错误的事件,在 onSocket:willDisconnectWithError: 将会被调用 去读取留在socket上的任何数据
  493. + (NSData *)CRLFData;   // 0x0D0A
  494. 各方法的解析
  495. -(void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err;
  496. 发生错误,socket关闭,可以在call-back过程调用"unreadData"去取得socket的最后的数据字节,当连接的时候,该委托方法在    onSocket:didAcceptNewSocket: 或者 onSocket:didConnectToHost: 之前调用
  497. -(void)onSocketDidDisconnect:(ASyncSocket *)sock;
  498. 当socket由于或没有错误而断开连接,如果你想要在断开连接后release socket,在此方法工作,而在onSocket:willDisconnectWithError 释放则不安全
  499. -(void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket;
  500. 当产生一个socket去处理连接时调用,此方法会返回 线程上的run-loop 的新的socket和其应处理的委托,如果省略,则使用[NSRunLoop cunrrentRunLoop]
  501. -(BOOL)onSocketWillConnect:(AsyncSocket *)sock;
  502. -(void)onSocket:(AsyncSocket *)sock didConnectToHost :(NSString *)host port:(UINt16)port;
  503. 当socket连接正准备读和写的时候调用,host属性是一个IP地址,而不是一个DNS 名称
  504. -(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long) tag;
  505. 当socket已完成所要求的数据读入内存时调用,如果有错误则不调用
  506. -(void)onSocket:(Asyncsocket *)sock didReadPartialDataOfLength:(NSUInteger)partiaLength tag:(long)tag;
  507. 当一个socket读取数据,但尚未完成读操作的时候调用,如果使用 readToData: or readToLength: 方法 会发生,可以被用来更新进度条等东西
  508. -(void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag;
  509. 当一个socket已完成请求数据的写入时候调用
  510. -(void)onSocket:(AsyncSocket *)sock didWritePartialDataOfLength:(NSUInteger)partialLength tag:(long)tag;
  511. 当一个socket写入一些数据,但还没有完成整个写入时调用,它可以用来更新进度条等东西
  512. -(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutReadWithTag:(long)tag elapsed:(NSTimeInterval)exapsed bytesDone:(NSUInteger)length
  513. 使用读操作已超时但还没完成时调用,此方法允许随意延迟超时,如果返回一个正的时间间隔,读取的超时将有一定量的扩展,如果不实现这个方法,或会像往常一样返回一个负的时间间隔,elapsed参数是  原超时的总和,加上先前通过这种方法添加的任何补充, length参数是 读操作到目前为止已读取的字节数, 注意,如果返回正数的话,这个方法可能被一个单独的读取多次调用
  514. -(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutWriteWithTag:(long)tag elapsed:(NSTimeInterval)elapsed bytesDone:(NSUInteger)length;
  515. 如果一个写操作已达到其超时但还没完成时调用,同上
  516. -(void)onSocketDidSecure:(AsyncSocket *)sock;
  517. 在socket成功完成ssl/tls协商时调用,此方法除非你使用提供startTLS方法时候才调用,
  518. 如果ssl/tls是无效的证书,socket将会立即关闭,onSocket:willDisconnectWithError:代理方法竟会与特定的ssl错误代码一起调用
  519. -(BOOL)canSafelySetDelegate
  520. 用来查看在改变它之前,是否带有与当前的委托有悬而未决的业务(读/写)。当然,应在安全连接或接受委托之前改变委托
  521. 一旦接收或连接方法之一被调用,AsyncSocket实例会被锁定,其他接收/连接方法在没有先断开socket不会被调用
  522. 如果尝试失败或超时,这些方法要么返回NO 要么调用 onSocket:willDisconnectWithError: 或 onSockedDidDisconnect
  523. 当传入的连接被接受,AsyncSocket调用多个委托方法。这些方法按照时间顺序排列:
  524. 1.onSocket:didAcceptNewSocket:
  525. 2.onSocket:wantsRunLoopForNewSocket:
  526. 3. onSocketWillConnect:
  527. 你的服务器的代码将需要保留公认的socket(如果要接受它),最好的地方是要做到这一点可能在onSocket:didAcceptNewSocket:方法
  528. 在读和写流已经为新接受的socket设置,onSocket:didConnectToHost:port 方法将在适当的运行循环调用
  529. 多线程注意,如果要想通过实施onSocket:wantsRunLoopForNewSocket:,移动另一个新接受的socket去到另一个循环的socket。然后,应该在调用读和写或者startTLS方法前,等待直到onSocket:didConnectToHost:port:方法。否则读和写时间原定于不正确的runloop,混乱可能会随之而来
  530. -(BOOL)acceptOnPort:(UInit16)port error:(NSError **)errPtr;
  531. 告诉socket开始听取和接受制定端口上的连接,当一个连接到来的时候,AsyncSocket实例将调用各种委托方法,socket将听取所有可用的接口(wifi,以太网等)
  532. -(BOOL)connectToHost:(NSString *)hostname onPort:(UInt16)port error :(NSError **)errPtr;
  533. 连接给定的主机和端口,主机hostname可以是域名或者是Ip地址
  534. -(BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError *)errPtr;
  535. 连接到一个给定的地址,制定一个sockaddr结构包裹住一个NSData对象,例如,NSData对象从NSNetService的地址方法返回,如果有一个现有的sockaddr结构,可以将它转换到一个NSData对象,像这样:
  536. struct sockaddr sa  -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len];
  537. struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len];
  538. -(void)disconnect;
  539. 立即断开,任何未处理的读或写都将被丢弃
  540. 如果socket还没有断开,在这个方法返回之前,onSocketDidDisconnect 委托方法将会被立即调用
  541. 注意推荐释放AsyncSocket实例的方式:
  542. [asyncSocket setDelegate:nil];
  543. [asyncSocket disconnect];
  544. [asyncSocket release];
  545. -(void)disconnectAfterReading;
  546. 在已经完成了所有悬而未决的读取时 断开,在调用之后,读取和写入方法将无用,socket将断开 即使仍有待写入
  547. - (NSString *)connectedHost;
  548. - (UInt16)connectedPort;
  549. - (NSString *)localHost;
  550. - (UInt16)localPort;
  551. 返回本地和远程主机和端口给连接的socket,如果没有连接会返回nil或0,主机将会是一个IP地址
  552. -(NSData *)connectedAddress
  553. -(NSData *)localAddresss
  554. 返回本地和远程的地址给连接的socket,指定一个socketaddr结构包裹在一个NSData对象
  555. readData和writeData方法不会是block(它们是异步的)
  556. 当读完成 onSocket:didReadData:withTag: 委托方法时调用
  557. 当写完成 onSocket:didWriteDataWithTag: 委托方法时调用
  558. 可以选择任何读/写操作的超时设置(为了不超时,使用负时间间隔。)
  559. 如果读/写操作超时,相应的 onSocket:shouldTimeout...委托方法被调用去选择性地允许我们去延长超时
  560. 超时后,onSocket:willDisconnectWithError: 方法被调用,紧接着是 onSocketDidDisconnect
  561. tag是为了方便,可以使用它作为数组的索引、步数、state id 、指针等
  562. -(void)readDataWithTimeout:(NSTimeInterval)tiemout tag:(long)tag;
  563. 读取socket上第一次成为可用的字节,如果timeout值是负数的,读操作将不使用timeout
  564. - (void)readDataWithTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInterger)offset tag:(long)tag;
  565. 读取socket上第一次成为可用的字节
  566. 字节将被追加到给定的字节缓冲区,从给定的偏移量开始
  567. 如果需要,给定的缓冲区大小将会自动增加
  568. 如果timeout值是负数的,读操作将不使用timeout
  569. 如果缓冲区为空,socket会为我们创建一个缓冲区
  570. 如果bufferOffset是大于给定的缓冲区的长度,该方法将无用,委托将不会被调用
  571. 如果你传递一个缓冲区,当AsyncSocket在使用它的时候你不能以任何方式改变它
  572. 完成之后,onSocket:didReadData:withTag 返回的数据将是一个给定的缓冲区的子集
  573. 也就是说,它将会被引用到被追加的给定的缓冲区的字节
  574. -(void)readDataToLength:(NSUInterger)length withTimeout:(NSTimeInterval)timeout tag:(long)tag;
  575. 读取给定的字节数,如果length为0,方法将无用,委托将不会被调用
  576. -(void)readDataToLength:(NSUInteger)length withTimeout:(NSTimeInterval)tiemout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
  577. 读取给定的字节数,在给定的偏移开始,字节将被追加到给定的字节缓冲区
  578. -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
  579. 读取字节直到(包括)传入的作为分隔的"data"参数
  580. 如果传递0或者0长度的数据,"data"参数,该方法将无用,委托将不会被调用
  581. 从socket读取一行,使用"data"参数作为行的分隔符 (如HTTP的CRLF)
  582. 注意,此方法不是字符集,因此,如果一个分隔符出现,它自然可以作为进行编码的一部分,读取将提前结束
  583. -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
  584. 读取字节直到(包括)传入的作为分隔的“data”参数,在给定的偏移量开始,字节将被追加到给定的字节缓冲区。
  585. 从socket读取一行,使用"data"参数作为行的分隔符(如HTTP的CRLF)
  586. -(void)writeData:(NSData *)data withTimeout:(NSTimeInterval) timeout tag:(long)tag;
  587. 将data写入socket,当完成的时候委托被调用
  588. - (float)progressOfReadReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
  589. - (float)progressOfWriteReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
  590. 返回当前读或写的进度,从0.0 到 1.0 或者 如果没有读/写的时候返回Nan(使用isNan来检查)
  591. tag、done、total如果不为空的话,它们将会被填补
  592. - (void)startTLS:(NSDictionary *)tlsSettings;
  593. 确保使用ssl/tls连接
  594. 这方法可被随时调用,tls握手将会发生在所有悬而未决的读/写完成之后。这紧跟着一个发送依赖 StartTLS消息的协议选项,在排队升级到TLS的同一时间,而不必等待写入完成。在这个方法被调用后,任何读写计划 将会发生在安全链接
  595. 对于可能的keys和TLS设置的值是有据可查的
  596. 一些可能的keys是:
  597. * - kCFStreamSSLLevel
  598. * - kCFStreamSSLAllowsExpiredCertificates
  599. * - kCFStreamSSLAllowsExpiredRoots
  600. * - kCFStreamSSLAllowsAnyRoot
  601. * - kCFStreamSSLValidatesCertificateChain
  602. * - kCFStreamSSLPeerName
  603. * - kCFStreamSSLCertificates
  604. * - kCFStreamSSLIsServer
  605. 如果你传递空或者空字典,将使用默认的字典
  606. 默认设置将检查以确保由签署可信的第三方证书机构和没有过期的远程连接的证书
  607. 然而,它不会验证证书上的名字,除非你给它一个名字,通过kCFStreamSSLPeerName键去验证
  608. 这对安全的影响是重要的理解
  609. 想象一下你正试图创建一个到MySecureServer.com的安全连接,但因为一个被攻击的DNS服务器,所以你的socket被定向到MaliciousServer.com
  610. 如果你只是使用默认设置,MaliciousServer.com 有一个有效的证书
  611. 默认设置将无法监测到任何问题,因为证书是有效的
  612. 在这个特殊的情况下,要妥善保护你的连接,应设置kCFStreamSSLPeerName性质为MySecureServer.com.
  613. 如果事前你不知道对等的名字的远程主机(例如,你不确认它是domain.com" or "www.domain.com"),那么你可以使用默认设置来验证证书,然后在获得验证的发行后使用X509Certificate类来验证,X509Certificate类的CocoaAsyncSocket开源项目的一部分
  614. -(void)enablePrebuffering
  615. 对于处理readDataToData请求,数据是必须从socket以小增量的方式读取出来的
  616. 性能通过允许AsyncSocket去一次性读大块的数据和存储任何一个小的内部缓冲区溢出的东西来大大提高
  617. 这被称为预缓冲,就好像一些数据在你要求它之前就可能被读取出来
  618. 如果你经常使用readDataToData,使用预缓冲会有更好的性能,尤其是在iphone上
  619. 默认的预缓冲状态是由DEFAULT_PREBUFFERING 定义控制的,强烈建议设置其为yes
  620. 这方法存在一些预缓冲需要一些不可预见的原因被默认禁用的情况,这时,这种方法存在允许当就绪时,可轻松启用预缓冲
  621. -(BOOL)moveToRunLoop:(NSRunLoop *)runLoop;
  622. 当你创建一个AsyncSocket,它被添加到当前线程runloop
  623. 对于手动创建的socket,在线程上你打算使用它,它是最容易简单的创建的线程上的socket
  624. 当一个新的socket被接受,委托方法 onSocket:wantsRunLoopForNewSocket 会被调用 允许你在一个单独的线程上放置socket,这个工作最好结合在同一个线程池设计
  625. 如果,但是,在一个单独的线程上,在之后的时间,你需要移动一个socket,这个方法可以用来完成任务
  626. 此方法必须从 当前运行的 线程/runloop 的socket 调用
  627. 注意:此方法调用后,所有进一步的方法应该从给定的runloop上调用这个对象
  628. 此外,所有委托调用将会发送到给定的runloop
  629. - (BOOL)setRunLoopModes:(NSArray *)runLoopModes;
  630. - (BOOL)addRunLoopMode:(NSString *)runLoopMode;
  631. - (BOOL)removeRunLoopMode:(NSString *)runLoopMode;
  632. 允许你配置 socket 使用的 运行循环模式
  633. 运行循环模式设置默认是NSRunLoopCommonModes
  634. 如果你想你的socket 在其他模式下继续操作,你可能需要添加模式 NSModalPanelRunLoopMode 或者 NSEventTrackingRunLoopMode ,或者你可能只想使用 NSRunLoopCommonModes
  635. 可接受的socket将自动 继承相同的运行循环模式就像侦听socket
  636. 注意:NSRunLoopCommonModes 定义在10.5,对于之前的版本可使用 kCFRunLoopCommonModes
  637. -(NSArray *)runLoopModes
  638. 返回当前正在运行的循环模式的AsyncSocket实例, run loop modes的默认设置是NSDefaultRunLoopMode
  639. -(NSData *)unreadData;
  640. 一个错误的事件,在 onSocket:willDisconnectWithError: 将会被调用 去读取留在socket上的任何数据
  641. + (NSData *)CRLFData;   // 0x0D0A
  642. 各方法的解析
  643. -(void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err;
  644. 发生错误,socket关闭,可以在call-back过程调用"unreadData"去取得socket的最后的数据字节,当连接的时候,该委托方法在    onSocket:didAcceptNewSocket: 或者 onSocket:didConnectToHost: 之前调用
  645. -(void)onSocketDidDisconnect:(ASyncSocket *)sock;
  646. 当socket由于或没有错误而断开连接,如果你想要在断开连接后release socket,在此方法工作,而在onSocket:willDisconnectWithError 释放则不安全
  647. -(void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket;
  648. 当产生一个socket去处理连接时调用,此方法会返回 线程上的run-loop 的新的socket和其应处理的委托,如果省略,则使用[NSRunLoop cunrrentRunLoop]
  649. -(BOOL)onSocketWillConnect:(AsyncSocket *)sock;
  650. -(void)onSocket:(AsyncSocket *)sock didConnectToHost :(NSString *)host port:(UINt16)port;
  651. 当socket连接正准备读和写的时候调用,host属性是一个IP地址,而不是一个DNS 名称
  652. -(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long) tag;
  653. 当socket已完成所要求的数据读入内存时调用,如果有错误则不调用
  654. -(void)onSocket:(Asyncsocket *)sock didReadPartialDataOfLength:(NSUInteger)partiaLength tag:(long)tag;
  655. 当一个socket读取数据,但尚未完成读操作的时候调用,如果使用 readToData: or readToLength: 方法 会发生,可以被用来更新进度条等东西
  656. -(void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag;
  657. 当一个socket已完成请求数据的写入时候调用
  658. -(void)onSocket:(AsyncSocket *)sock didWritePartialDataOfLength:(NSUInteger)partialLength tag:(long)tag;
  659. 当一个socket写入一些数据,但还没有完成整个写入时调用,它可以用来更新进度条等东西
  660. -(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutReadWithTag:(long)tag elapsed:(NSTimeInterval)exapsed bytesDone:(NSUInteger)length
  661. 使用读操作已超时但还没完成时调用,此方法允许随意延迟超时,如果返回一个正的时间间隔,读取的超时将有一定量的扩展,如果不实现这个方法,或会像往常一样返回一个负的时间间隔,elapsed参数是  原超时的总和,加上先前通过这种方法添加的任何补充, length参数是 读操作到目前为止已读取的字节数, 注意,如果返回正数的话,这个方法可能被一个单独的读取多次调用
  662. -(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutWriteWithTag:(long)tag elapsed:(NSTimeInterval)elapsed bytesDone:(NSUInteger)length;
  663. 如果一个写操作已达到其超时但还没完成时调用,同上
  664. -(void)onSocketDidSecure:(AsyncSocket *)sock;
  665. 在socket成功完成ssl/tls协商时调用,此方法除非你使用提供startTLS方法时候才调用,
  666. 如果ssl/tls是无效的证书,socket将会立即关闭,onSocket:willDisconnectWithError:代理方法竟会与特定的ssl错误代码一起调用
  667. -(BOOL)canSafelySetDelegate
  668. 用来查看在改变它之前,是否带有与当前的委托有悬而未决的业务(读/写)。当然,应在安全连接或接受委托之前改变委托
  669. 一旦接收或连接方法之一被调用,AsyncSocket实例会被锁定,其他接收/连接方法在没有先断开socket不会被调用
  670. 如果尝试失败或超时,这些方法要么返回NO 要么调用 onSocket:willDisconnectWithError: 或 onSockedDidDisconnect
  671. 当传入的连接被接受,AsyncSocket调用多个委托方法。这些方法按照时间顺序排列:
  672. 1.onSocket:didAcceptNewSocket:
  673. 2.onSocket:wantsRunLoopForNewSocket:
  674. 3. onSocketWillConnect:
  675. 你的服务器的代码将需要保留公认的socket(如果要接受它),最好的地方是要做到这一点可能在onSocket:didAcceptNewSocket:方法
  676. 在读和写流已经为新接受的socket设置,onSocket:didConnectToHost:port 方法将在适当的运行循环调用
  677. 多线程注意,如果要想通过实施onSocket:wantsRunLoopForNewSocket:,移动另一个新接受的socket去到另一个循环的socket。然后,应该在调用读和写或者startTLS方法前,等待直到onSocket:didConnectToHost:port:方法。否则读和写时间原定于不正确的runloop,混乱可能会随之而来
  678. -(BOOL)acceptOnPort:(UInit16)port error:(NSError **)errPtr;
  679. 告诉socket开始听取和接受制定端口上的连接,当一个连接到来的时候,AsyncSocket实例将调用各种委托方法,socket将听取所有可用的接口(wifi,以太网等)
  680. -(BOOL)connectToHost:(NSString *)hostname onPort:(UInt16)port error :(NSError **)errPtr;
  681. 连接给定的主机和端口,主机hostname可以是域名或者是Ip地址
  682. -(BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError *)errPtr;
  683. 连接到一个给定的地址,制定一个sockaddr结构包裹住一个NSData对象,例如,NSData对象从NSNetService的地址方法返回,如果有一个现有的sockaddr结构,可以将它转换到一个NSData对象,像这样:
  684. struct sockaddr sa  -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len];
  685. struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len];
  686. -(void)disconnect;
  687. 立即断开,任何未处理的读或写都将被丢弃
  688. 如果socket还没有断开,在这个方法返回之前,onSocketDidDisconnect 委托方法将会被立即调用
  689. 注意推荐释放AsyncSocket实例的方式:
  690. [asyncSocket setDelegate:nil];
  691. [asyncSocket disconnect];
  692. [asyncSocket release];
  693. -(void)disconnectAfterReading;
  694. 在已经完成了所有悬而未决的读取时 断开,在调用之后,读取和写入方法将无用,socket将断开 即使仍有待写入
  695. - (NSString *)connectedHost;
  696. - (UInt16)connectedPort;
  697. - (NSString *)localHost;
  698. - (UInt16)localPort;
  699. 返回本地和远程主机和端口给连接的socket,如果没有连接会返回nil或0,主机将会是一个IP地址
  700. -(NSData *)connectedAddress
  701. -(NSData *)localAddresss
  702. 返回本地和远程的地址给连接的socket,指定一个socketaddr结构包裹在一个NSData对象
  703. readData和writeData方法不会是block(它们是异步的)
  704. 当读完成 onSocket:didReadData:withTag: 委托方法时调用
  705. 当写完成 onSocket:didWriteDataWithTag: 委托方法时调用
  706. 可以选择任何读/写操作的超时设置(为了不超时,使用负时间间隔。)
  707. 如果读/写操作超时,相应的 onSocket:shouldTimeout...委托方法被调用去选择性地允许我们去延长超时
  708. 超时后,onSocket:willDisconnectWithError: 方法被调用,紧接着是 onSocketDidDisconnect
  709. tag是为了方便,可以使用它作为数组的索引、步数、state id 、指针等
  710. -(void)readDataWithTimeout:(NSTimeInterval)tiemout tag:(long)tag;
  711. 读取socket上第一次成为可用的字节,如果timeout值是负数的,读操作将不使用timeout
  712. - (void)readDataWithTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInterger)offset tag:(long)tag;
  713. 读取socket上第一次成为可用的字节
  714. 字节将被追加到给定的字节缓冲区,从给定的偏移量开始
  715. 如果需要,给定的缓冲区大小将会自动增加
  716. 如果timeout值是负数的,读操作将不使用timeout
  717. 如果缓冲区为空,socket会为我们创建一个缓冲区
  718. 如果bufferOffset是大于给定的缓冲区的长度,该方法将无用,委托将不会被调用
  719. 如果你传递一个缓冲区,当AsyncSocket在使用它的时候你不能以任何方式改变它
  720. 完成之后,onSocket:didReadData:withTag 返回的数据将是一个给定的缓冲区的子集
  721. 也就是说,它将会被引用到被追加的给定的缓冲区的字节
  722. -(void)readDataToLength:(NSUInterger)length withTimeout:(NSTimeInterval)timeout tag:(long)tag;
  723. 读取给定的字节数,如果length为0,方法将无用,委托将不会被调用
  724. -(void)readDataToLength:(NSUInteger)length withTimeout:(NSTimeInterval)tiemout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
  725. 读取给定的字节数,在给定的偏移开始,字节将被追加到给定的字节缓冲区
  726. -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
  727. 读取字节直到(包括)传入的作为分隔的"data"参数
  728. 如果传递0或者0长度的数据,"data"参数,该方法将无用,委托将不会被调用
  729. 从socket读取一行,使用"data"参数作为行的分隔符 (如HTTP的CRLF)
  730. 注意,此方法不是字符集,因此,如果一个分隔符出现,它自然可以作为进行编码的一部分,读取将提前结束
  731. -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
  732. 读取字节直到(包括)传入的作为分隔的“data”参数,在给定的偏移量开始,字节将被追加到给定的字节缓冲区。
  733. 从socket读取一行,使用"data"参数作为行的分隔符(如HTTP的CRLF)
  734. -(void)writeData:(NSData *)data withTimeout:(NSTimeInterval) timeout tag:(long)tag;
  735. 将data写入socket,当完成的时候委托被调用
  736. - (float)progressOfReadReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
  737. - (float)progressOfWriteReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
  738. 返回当前读或写的进度,从0.0 到 1.0 或者 如果没有读/写的时候返回Nan(使用isNan来检查)
  739. tag、done、total如果不为空的话,它们将会被填补
  740. - (void)startTLS:(NSDictionary *)tlsSettings;
  741. 确保使用ssl/tls连接
  742. 这方法可被随时调用,tls握手将会发生在所有悬而未决的读/写完成之后。这紧跟着一个发送依赖 StartTLS消息的协议选项,在排队升级到TLS的同一时间,而不必等待写入完成。在这个方法被调用后,任何读写计划 将会发生在安全链接
  743. 对于可能的keys和TLS设置的值是有据可查的
  744. 一些可能的keys是:
  745. * - kCFStreamSSLLevel
  746. * - kCFStreamSSLAllowsExpiredCertificates
  747. * - kCFStreamSSLAllowsExpiredRoots
  748. * - kCFStreamSSLAllowsAnyRoot
  749. * - kCFStreamSSLValidatesCertificateChain
  750. * - kCFStreamSSLPeerName
  751. * - kCFStreamSSLCertificates
  752. * - kCFStreamSSLIsServer
  753. 如果你传递空或者空字典,将使用默认的字典
  754. 默认设置将检查以确保由签署可信的第三方证书机构和没有过期的远程连接的证书
  755. 然而,它不会验证证书上的名字,除非你给它一个名字,通过kCFStreamSSLPeerName键去验证
  756. 这对安全的影响是重要的理解
  757. 想象一下你正试图创建一个到MySecureServer.com的安全连接,但因为一个被攻击的DNS服务器,所以你的socket被定向到MaliciousServer.com
  758. 如果你只是使用默认设置,MaliciousServer.com 有一个有效的证书
  759. 默认设置将无法监测到任何问题,因为证书是有效的
  760. 在这个特殊的情况下,要妥善保护你的连接,应设置kCFStreamSSLPeerName性质为MySecureServer.com.
  761. 如果事前你不知道对等的名字的远程主机(例如,你不确认它是domain.com" or "www.domain.com"),那么你可以使用默认设置来验证证书,然后在获得验证的发行后使用X509Certificate类来验证,X509Certificate类的CocoaAsyncSocket开源项目的一部分
  762. -(void)enablePrebuffering
  763. 对于处理readDataToData请求,数据是必须从socket以小增量的方式读取出来的
  764. 性能通过允许AsyncSocket去一次性读大块的数据和存储任何一个小的内部缓冲区溢出的东西来大大提高
  765. 这被称为预缓冲,就好像一些数据在你要求它之前就可能被读取出来
  766. 如果你经常使用readDataToData,使用预缓冲会有更好的性能,尤其是在iphone上
  767. 默认的预缓冲状态是由DEFAULT_PREBUFFERING 定义控制的,强烈建议设置其为yes
  768. 这方法存在一些预缓冲需要一些不可预见的原因被默认禁用的情况,这时,这种方法存在允许当就绪时,可轻松启用预缓冲
  769. -(BOOL)moveToRunLoop:(NSRunLoop *)runLoop;
  770. 当你创建一个AsyncSocket,它被添加到当前线程runloop
  771. 对于手动创建的socket,在线程上你打算使用它,它是最容易简单的创建的线程上的socket
  772. 当一个新的socket被接受,委托方法 onSocket:wantsRunLoopForNewSocket 会被调用 允许你在一个单独的线程上放置socket,这个工作最好结合在同一个线程池设计
  773. 如果,但是,在一个单独的线程上,在之后的时间,你需要移动一个socket,这个方法可以用来完成任务
  774. 此方法必须从 当前运行的 线程/runloop 的socket 调用
  775. 注意:此方法调用后,所有进一步的方法应该从给定的runloop上调用这个对象
  776. 此外,所有委托调用将会发送到给定的runloop
  777. - (BOOL)setRunLoopModes:(NSArray *)runLoopModes;
  778. - (BOOL)addRunLoopMode:(NSString *)runLoopMode;
  779. - (BOOL)removeRunLoopMode:(NSString *)runLoopMode;
  780. 允许你配置 socket 使用的 运行循环模式
  781. 运行循环模式设置默认是NSRunLoopCommonModes
  782. 如果你想你的socket 在其他模式下继续操作,你可能需要添加模式 NSModalPanelRunLoopMode 或者 NSEventTrackingRunLoopMode ,或者你可能只想使用 NSRunLoopCommonModes
  783. 可接受的socket将自动 继承相同的运行循环模式就像侦听socket
  784. 注意:NSRunLoopCommonModes 定义在10.5,对于之前的版本可使用 kCFRunLoopCommonModes
  785. -(NSArray *)runLoopModes
  786. 返回当前正在运行的循环模式的AsyncSocket实例, run loop modes的默认设置是NSDefaultRunLoopMode
  787. -(NSData *)unreadData;
  788. 一个错误的事件,在 onSocket:willDisconnectWithError: 将会被调用 去读取留在socket上的任何数据
  789. + (NSData *)CRLFData;   // 0x0D0A
  790. 各方法的解析
  791. -(void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err;
  792. 发生错误,socket关闭,可以在call-back过程调用"unreadData"去取得socket的最后的数据字节,当连接的时候,该委托方法在    onSocket:didAcceptNewSocket: 或者 onSocket:didConnectToHost: 之前调用
  793. 发生错误,socket关闭,可以在call-back过程调用"unreadData"去取得socket的最后的数据字节,当连接的时候,该委托方法在    onSocket:didAcceptNewSocket: 或者 onSocket:didConnectToHost: 之前调用
  794. -(void)onSocketDidDisconnect:(ASyncSocket *)sock;
  795. 当socket由于或没有错误而断开连接,如果你想要在断开连接后release socket,在此方法工作,而在onSocket:willDisconnectWithError 释放则不安全
  796. -(void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket;
  797. 当产生一个socket去处理连接时调用,此方法会返回 线程上的run-loop 的新的socket和其应处理的委托,如果省略,则使用[NSRunLoop cunrrentRunLoop]
  798. 当产生一个socket去处理连接时调用,此方法会返回 线程上的run-loop 的新的socket和其应处理的委托,如果省略,则使用[NSRunLoop cunrrentRunLoop]
  799. -(BOOL)onSocketWillConnect:(AsyncSocket *)sock;
  800. -(void)onSocket:(AsyncSocket *)sock didConnectToHost :(NSString *)host port:(UINt16)port;
  801. 当socket连接正准备读和写的时候调用,host属性是一个IP地址,而不是一个DNS 名称
  802. -(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long) tag;
  803. 当socket已完成所要求的数据读入内存时调用,如果有错误则不调用
  804. -(void)onSocket:(Asyncsocket *)sock didReadPartialDataOfLength:(NSUInteger)partiaLength tag:(long)tag;
  805. 当一个socket读取数据,但尚未完成读操作的时候调用,如果使用 readToData: or readToLength: 方法 会发生,可以被用来更新进度条等东西
  806. -(void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag;
  807. 当一个socket已完成请求数据的写入时候调用
  808. -(void)onSocket:(AsyncSocket *)sock didWritePartialDataOfLength:(NSUInteger)partialLength tag:(long)tag;
  809. 当一个socket写入一些数据,但还没有完成整个写入时调用,它可以用来更新进度条等东西
  810. -(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutReadWithTag:(long)tag elapsed:(NSTimeInterval)exapsed bytesDone:(NSUInteger)length
  811. 使用读操作已超时但还没完成时调用,此方法允许随意延迟超时,如果返回一个正的时间间隔,读取的超时将有一定量的扩展,如果不实现这个方法,或会像往常一样返回一个负的时间间隔,elapsed参数是  原超时的总和,加上先前通过这种方法添加的任何补充, length参数是 读操作到目前为止已读取的字节数, 注意,如果返回正数的话,这个方法可能被一个单独的读取多次调用
  812. -(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutWriteWithTag:(long)tag elapsed:(NSTimeInterval)elapsed bytesDone:(NSUInteger)length;
  813. 如果一个写操作已达到其超时但还没完成时调用,同上
  814. -(void)onSocketDidSecure:(AsyncSocket *)sock;
  815. 在socket成功完成ssl/tls协商时调用,此方法除非你使用提供startTLS方法时候才调用,
  816. 如果ssl/tls是无效的证书,socket将会立即关闭,onSocket:willDisconnectWithError:代理方法竟会与特定的ssl错误代码一起调用
  817. -(BOOL)canSafelySetDelegate
  818. 用来查看在改变它之前,是否带有与当前的委托有悬而未决的业务(读/写)。当然,应在安全连接或接受委托之前改变委托
  819. 一旦接收或连接方法之一被调用,AsyncSocket实例会被锁定,其他接收/连接方法在没有先断开socket不会被调用
  820. 如果尝试失败或超时,这些方法要么返回NO 要么调用 onSocket:willDisconnectWithError: 或 onSockedDidDisconnect
  821. 当传入的连接被接受,AsyncSocket调用多个委托方法。这些方法按照时间顺序排列:
  822. 1.onSocket:didAcceptNewSocket:
  823. 2.onSocket:wantsRunLoopForNewSocket:
  824. 3. onSocketWillConnect:
  825. 你的服务器的代码将需要保留公认的socket(如果要接受它),最好的地方是要做到这一点可能在onSocket:didAcceptNewSocket:方法
  826. 在读和写流已经为新接受的socket设置,onSocket:didConnectToHost:port 方法将在适当的运行循环调用
  827. 多线程注意,如果要想通过实施onSocket:wantsRunLoopForNewSocket:,移动另一个新接受的socket去到另一个循环的socket。然后,应该在调用读和写或者startTLS方法前,等待直到onSocket:didConnectToHost:port:方法。否则读和写时间原定于不正确的runloop,混乱可能会随之而来
  828. -(BOOL)acceptOnPort:(UInit16)port error:(NSError **)errPtr;
  829. 告诉socket开始听取和接受制定端口上的连接,当一个连接到来的时候,AsyncSocket实例将调用各种委托方法,socket将听取所有可用的接口(wifi,以太网等)
  830. -(BOOL)connectToHost:(NSString *)hostname onPort:(UInt16)port error :(NSError **)errPtr;
  831. 连接给定的主机和端口,主机hostname可以是域名或者是Ip地址
  832. -(BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError *)errPtr;
  833. 连接到一个给定的地址,制定一个sockaddr结构包裹住一个NSData对象,例如,NSData对象从NSNetService的地址方法返回,如果有一个现有的sockaddr结构,可以将它转换到一个NSData对象,像这样:
  834. struct sockaddr sa  -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len];
  835. struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len];
  836. -(void)disconnect;
  837. 立即断开,任何未处理的读或写都将被丢弃
  838. 如果socket还没有断开,在这个方法返回之前,onSocketDidDisconnect 委托方法将会被立即调用
  839. 注意推荐释放AsyncSocket实例的方式:
  840. [asyncSocket setDelegate:nil];
  841. [asyncSocket disconnect];
  842. [asyncSocket release];
  843. -(void)disconnectAfterReading;
  844. 在已经完成了所有悬而未决的读取时 断开,在调用之后,读取和写入方法将无用,socket将断开 即使仍有待写入
  845. - (NSString *)connectedHost;
  846. - (UInt16)connectedPort;
  847. - (NSString *)localHost;
  848. - (UInt16)localPort;
  849. 返回本地和远程主机和端口给连接的socket,如果没有连接会返回nil或0,主机将会是一个IP地址
  850. -(NSData *)connectedAddress
  851. -(NSData *)localAddresss
  852. 返回本地和远程的地址给连接的socket,指定一个socketaddr结构包裹在一个NSData对象
  853. readData和writeData方法不会是block(它们是异步的)
  854. 当读完成 onSocket:didReadData:withTag: 委托方法时调用
  855. 当写完成 onSocket:didWriteDataWithTag: 委托方法时调用
  856. 可以选择任何读/写操作的超时设置(为了不超时,使用负时间间隔。)
  857. 如果读/写操作超时,相应的 onSocket:shouldTimeout...委托方法被调用去选择性地允许我们去延长超时
  858. 超时后,onSocket:willDisconnectWithError: 方法被调用,紧接着是 onSocketDidDisconnect
  859. tag是为了方便,可以使用它作为数组的索引、步数、state id 、指针等
  860. -(void)readDataWithTimeout:(NSTimeInterval)tiemout tag:(long)tag;
  861. 读取socket上第一次成为可用的字节,如果timeout值是负数的,读操作将不使用timeout
  862. - (void)readDataWithTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInterger)offset tag:(long)tag;
  863. 读取socket上第一次成为可用的字节
  864. 字节将被追加到给定的字节缓冲区,从给定的偏移量开始
  865. 如果需要,给定的缓冲区大小将会自动增加
  866. 如果timeout值是负数的,读操作将不使用timeout
  867. 如果缓冲区为空,socket会为我们创建一个缓冲区
  868. 如果bufferOffset是大于给定的缓冲区的长度,该方法将无用,委托将不会被调用
  869. 如果你传递一个缓冲区,当AsyncSocket在使用它的时候你不能以任何方式改变它
  870. 完成之后,onSocket:didReadData:withTag 返回的数据将是一个给定的缓冲区的子集
  871. 也就是说,它将会被引用到被追加的给定的缓冲区的字节
  872. -(void)readDataToLength:(NSUInterger)length withTimeout:(NSTimeInterval)timeout tag:(long)tag;
  873. 读取给定的字节数,如果length为0,方法将无用,委托将不会被调用
  874. -(void)readDataToLength:(NSUInteger)length withTimeout:(NSTimeInterval)tiemout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
  875. 读取给定的字节数,在给定的偏移开始,字节将被追加到给定的字节缓冲区
  876. -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
  877. 读取字节直到(包括)传入的作为分隔的"data"参数
  878. 如果传递0或者0长度的数据,"data"参数,该方法将无用,委托将不会被调用
  879. 从socket读取一行,使用"data"参数作为行的分隔符 (如HTTP的CRLF)
  880. 注意,此方法不是字符集,因此,如果一个分隔符出现,它自然可以作为进行编码的一部分,读取将提前结束
  881. -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
  882. 读取字节直到(包括)传入的作为分隔的“data”参数,在给定的偏移量开始,字节将被追加到给定的字节缓冲区。
  883. 从socket读取一行,使用"data"参数作为行的分隔符(如HTTP的CRLF)
  884. -(void)writeData:(NSData *)data withTimeout:(NSTimeInterval) timeout tag:(long)tag;
  885. 将data写入socket,当完成的时候委托被调用
  886. - (float)progressOfReadReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
  887. - (float)progressOfWriteReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
  888. 返回当前读或写的进度,从0.0 到 1.0 或者 如果没有读/写的时候返回Nan(使用isNan来检查)
  889. tag、done、total如果不为空的话,它们将会被填补
  890. - (void)startTLS:(NSDictionary *)tlsSettings;
  891. 确保使用ssl/tls连接
  892. 这方法可被随时调用,tls握手将会发生在所有悬而未决的读/写完成之后。这紧跟着一个发送依赖 StartTLS消息的协议选项,在排队升级到TLS的同一时间,而不必等待写入完成。在这个方法被调用后,任何读写计划 将会发生在安全链接
  893. 对于可能的keys和TLS设置的值是有据可查的
  894. 一些可能的keys是:
  895. * - kCFStreamSSLLevel
  896. * - kCFStreamSSLAllowsExpiredCertificates
  897. * - kCFStreamSSLAllowsExpiredRoots
  898. * - kCFStreamSSLAllowsAnyRoot
  899. * - kCFStreamSSLValidatesCertificateChain
  900. * - kCFStreamSSLPeerName
  901. * - kCFStreamSSLCertificates
  902. * - kCFStreamSSLIsServer
  903. 如果你传递空或者空字典,将使用默认的字典
  904. 默认设置将检查以确保由签署可信的第三方证书机构和没有过期的远程连接的证书
  905. 然而,它不会验证证书上的名字,除非你给它一个名字,通过kCFStreamSSLPeerName键去验证
  906. 这对安全的影响是重要的理解
  907. 想象一下你正试图创建一个到MySecureServer.com的安全连接,但因为一个被攻击的DNS服务器,所以你的socket被定向到MaliciousServer.com
  908. 如果你只是使用默认设置,MaliciousServer.com 有一个有效的证书
  909. 默认设置将无法监测到任何问题,因为证书是有效的
  910. 在这个特殊的情况下,要妥善保护你的连接,应设置kCFStreamSSLPeerName性质为MySecureServer.com.
  911. 如果事前你不知道对等的名字的远程主机(例如,你不确认它是domain.com" or "www.domain.com"),那么你可以使用默认设置来验证证书,然后在获得验证的发行后使用X509Certificate类来验证,X509Certificate类的CocoaAsyncSocket开源项目的一部分
  912. -(void)enablePrebuffering
  913. 对于处理readDataToData请求,数据是必须从socket以小增量的方式读取出来的
  914. 性能通过允许AsyncSocket去一次性读大块的数据和存储任何一个小的内部缓冲区溢出的东西来大大提高
  915. 这被称为预缓冲,就好像一些数据在你要求它之前就可能被读取出来
  916. 如果你经常使用readDataToData,使用预缓冲会有更好的性能,尤其是在iphone上
  917. 默认的预缓冲状态是由DEFAULT_PREBUFFERING 定义控制的,强烈建议设置其为yes
  918. 这方法存在一些预缓冲需要一些不可预见的原因被默认禁用的情况,这时,这种方法存在允许当就绪时,可轻松启用预缓冲
  919. -(BOOL)moveToRunLoop:(NSRunLoop *)runLoop;
  920. 当你创建一个AsyncSocket,它被添加到当前线程runloop
  921. 对于手动创建的socket,在线程上你打算使用它,它是最容易简单的创建的线程上的socket
  922. 当一个新的socket被接受,委托方法 onSocket:wantsRunLoopForNewSocket 会被调用 允许你在一个单独的线程上放置socket,这个工作最好结合在同一个线程池设计
  923. 如果,但是,在一个单独的线程上,在之后的时间,你需要移动一个socket,这个方法可以用来完成任务
  924. 此方法必须从 当前运行的 线程/runloop 的socket 调用
  925. 注意:此方法调用后,所有进一步的方法应该从给定的runloop上调用这个对象
  926. 此外,所有委托调用将会发送到给定的runloop
  927. - (BOOL)setRunLoopModes:(NSArray *)runLoopModes;
  928. - (BOOL)addRunLoopMode:(NSString *)runLoopMode;
  929. - (BOOL)removeRunLoopMode:(NSString *)runLoopMode;
  930. 允许你配置 socket 使用的 运行循环模式
  931. 运行循环模式设置默认是NSRunLoopCommonModes
  932. 如果你想你的socket 在其他模式下继续操作,你可能需要添加模式 NSModalPanelRunLoopMode 或者 NSEventTrackingRunLoopMode ,或者你可能只想使用 NSRunLoopCommonModes
  933. 可接受的socket将自动 继承相同的运行循环模式就像侦听socket
  934. 注意:NSRunLoopCommonModes 定义在10.5,对于之前的版本可使用 kCFRunLoopCommonModes
  935. -(NSArray *)runLoopModes
  936. 返回当前正在运行的循环模式的AsyncSocket实例, run loop modes的默认设置是NSDefaultRunLoopMode
  937. -(NSData *)unreadData;
  938. 一个错误的事件,在 onSocket:willDisconnectWithError: 将会被调用 去读取留在socket上的任何数据
  939. + (NSData *)CRLFData;   // 0x0D0A

IOS socket编程--Asyncsocket,布布扣,bubuko.com

时间: 2024-11-03 21:21:33

IOS socket编程--Asyncsocket的相关文章

02-【IOS网络编程】socket编程 - Asyncsocket

socket编程Asyncsocket iPhone的标准推荐是CFNetwork 库编程,其封装好的开源库是 cocoa AsyncSocket库,用它来简化CFNetwork的调用,它提供了异步操作 主要特性有: 队列的非阻塞的读和写,而且可选超时.你可以调用它读取和写入,它会当完成后告知你 自动的socket接收.如果你调用它接收连接,它将为每个连接启动新的实例,当然,也可以立即关闭这些连接 委托(delegate)支持.错误.连接.接收.完整的读取.完整的写入.进度以及断开连接,都可以通

iOS socket编程

// // ViewController.m // socket // // Created by emerys on 16/3/2. // Copyright © 2016年 Emerys. All rights reserved. // #import "ViewController.h" #warning 0000前面四位为消息长度,后接消息,最后以#结束 @interface ViewController ()<NSStreamDelegate,UITableViewDa

iOS socket编程(入门)

1.基于 C 的 BSD socket(UNIX系统中通用的网络接口) 感觉BSD socket 最容易理解,最容易入门,最为灵活     但是最难用,尤其对于大型项目 需要导入头文件 #import <sys/socket.h> #import <netdb.h> 服务器端 int listenfd, connfd; struct sockaddr_in servaddr; char buff[4096]; long n; int i=100; //创建 socket if( (

iOS项目开发之Socket编程

有一段时间没有认真总结和写博客了 前段时间找工作.进入工作阶段.比较少静下来认真总结,现在静下心来总结一下最近的一些心得 前言 AsyncSocket介绍 AsyncSocket详解 AsyncSocket示例 一.前言 公司的项目用到了Socket编程,之前在学习的过程当中,用到的更多的还是http请求的方式.但是既然用到了就必须学习一下,所以就在网上找一些例子,然后想自己写一个demo.可是发现很多写iOS Socket的博客并没有很详细的说明,也可能是大神们觉得其他东西都浅显易懂. 自己专

总结一下前两天刚尝试的socket编程-使用AsyncSocket

说来惭愧,搞了两年ios居然木有用过socket...初学ios的时候倒是了解过,但是两年不用,之前学的内容已经完全忘光光.于是又开始网上各种查. 用cf的socket貌似显得很拽的样子,但是实在不适合我这种领导紧逼着出项目的情况.搜了下发现目前最常用的socket库应该就是AsyncSocket了.嗯,看起来很简单,搞it~ 这个库有基于runloop和GCD两种,据我一哥们说runloop版本是基于timer机制实现异步处理,会跟scroller的滚动动画冲突.我暂时还没有验证他的说法,不过

iOS从零开始学习socket编程——HTTP1.0服务器端

在前一篇文章<iOS从零开始学习socket编程--HTTP1.0客户端>中已经简单的介绍过了Socket编程和一些基本原理.并且实现了简单的iOS客户端(原文地址:http://blog.csdn.net/abc649395594/article/details/45081567) 这里再简单介绍一下如何使用OC搭建socket的服务器端.虽然这并不是一个好的解决方案,通常我们使用Java或者PHP抑或NodeJS来搭建服务器后台.但是还是有必要了解一下OC的做法,顺便加深对Socket编程

iOS从零开始学习socket编程——高并发多线程服务器

在上一篇文章<iOS从零开始学习socket编程--HTTP1.0服务器端>中我们已经简单的接触了OC搭建的HTTP服务器. (地址http://blog.csdn.net/abc649395594/article/details/45131373) 出于用户体验和鲁棒性考虑,这里把这个HTTP服务器改进成多线程的. 首先,AnsycSocket这个类是基于OC的Runloop实现的,Runloop实现了方法的异步调用但并不支持多线程. 在这里首先简单区分一下多线程和方法异步调用的区别.他们都

iOS从零开始学习socket编程——HTTP1.0客户端

在开始socket编程之前,首先需要明确几个概念: 1.网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. 2.socket中文名为"套接字",是基于TCP/IP协议通信机制. 3.客户端的socket连接需要指定主机的ip地址和端口,ip地址类似于家庭地址,用于唯一确认一台主机,而端口类似于门牌号,用于唯一确认主机上的某一个程序. 我们模拟一次HTTP的请求.首先在终端中输入 telnet 202.118.1.7 80 我们会得到这样的提示 T

iOS开发 socket编程

二.AsyncSocket介绍 1)iOS中Socket编程的方式有哪些? -BSD Socket BSD Socket 是UNIX系统中通用的网络接口,它不仅支持各种不同的网络类型,而且也是一种内部进程之间的通信机制.而iOS系统其实本质就是UNIX,所以可以用,但是比较复杂. -CFSocket CFSocket是苹果提供给我们的使用Socket的方式,但是用起来还是会不太顺手.当然想使用的话,可以细细研究一下. -AsyncSocket 这次博客的主讲内容,也是我们在开发项目中经常会用到的