使用NSStream来实现Socket
- 格式:doc
- 大小:310.00 KB
- 文档页数:44
iOS开发教程Socket的原理和使用1. iOS网络编程层次结构iOS网络编程层次结构分为三层,从上往下依次为:- Cocoa层:NSURL,Bonjour,Game Kit,WebKit- Core Foundation层:基于C 的CFNetwork 和CFNetServices- OS层:基于C 的BSD SocketCocoa层:是最上层的基于Objective-C 的API,比如URL访问,NSStream,Bonjour,GameKit等,这是大多数情况下我们常用的API。
Cocoa 层是基于Core Foundation 实现的。
Core Foundation层:因为直接使用socket 需要更多的编程工作,所以苹果对OS 层的socket 进行简单的封装以简化编程任务。
该层提供了CFNetwork 和CFNetServices,其中CFNetwork 又是基于CFStream 和CFSocket。
OS层:最底层的BSD Socket 提供了对网络编程最大程度的控制,但是编程工作也是最多的。
因此,苹果建议我们使用Core Foundation 及以上层的API 进行编程。
本文将介绍如何在iOS 系统下使用最底层的Socket 进行编程。
2. 什么是SocketSocket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。
2.1 TCP和UDP的区别TCP:面向连接、传输可靠(保证数据正确性,保证数据顺序)、用于传输大量数据(流模式)、速度慢,建立连接需要开销较多(时间,系统资源)。
UDP:面向非连接、传输不可靠、用于传输少量数据(数据包模式)、速度快。
关于TCP是一种流模式的协议,UDP是一种数据包模式的协议,这里要说明一下,TCP 是面向连接的,也就是说,在连接持续的过程中,Socket中收到的数据都是由同一台主机发出的(劫持什么的不考虑),因此,知道保证数据是有序的到达就行了,至于每次读取多少数据自己看着办。
socket流程Socket流程是指在计算机网络中,通过Socket套接字进行网络通信的流程。
Socket是一种网络编程中用于实现通信的一种应用编程接口(API),它提供了底层数据传输的功能,使得应用程序能够在网络中进行数据传输和通信。
Socket流程主要包括四个步骤:创建Socket、建立连接、数据传输和断开连接。
第一步,创建Socket。
在进行Socket编程时,首先需要创建一个Socket对象,这个对象可以用来进行后续的网络通信。
在创建Socket时,需要指定网络协议、IP地址和端口号。
一般来说,TCP协议使用的是IP地址,UDP协议使用的是主机名或者IP地址,端口号是用来区分不同应用程序的标识。
第二步,建立连接。
在进行网络通信之前,需要建立连接。
建立连接的过程可以分为客户端和服务器端两个部分。
对于客户端来说,需要指定服务器的IP地址和端口号,通过Socket对象中的connect()方法来建立连接。
对于服务器端来说,需要指定监听的端口号,通过Socket对象中的bind()方法和listen()方法来监听网络连接请求,然后通过accept()方法接受客户端的连接请求。
第三步,数据传输。
在建立连接之后,可以进行数据的传输。
数据的传输可以分为两种方式:TCP协议是面向连接的,使用InputStream和OutputStream进行数据读写;UDP协议是无连接的,使用DatagramPacket和DatagramSocket进行数据的发送和接收。
无论是TCP还是UDP,都可以通过输入输出流进行数据的读写操作。
第四步,断开连接。
在网络通信结束之后,需要断开连接。
对于客户端和服务器端来说,都需要调用Socket对象中的close()方法来关闭连接。
关闭连接的过程将会释放套接字资源,同时也会让连接的另一方得知连接已经断开。
总结起来,Socket流程是通过创建Socket对象来建立网络连接,然后进行数据传输,最后通过关闭Socket对象来断开连接。
socket函数的三个参数标题:socket函数的使用方法导语:在计算机网络中,socket函数是一种用于实现网络通信的编程接口。
它是网络应用程序与网络之间的通信端点,通过socket函数可以实现进程间的通信和数据传输。
本文将详细介绍socket函数的三个参数的使用方法,帮助读者理解并能够灵活应用socket函数。
一、参数一:domain(套接字的协议域)在socket函数中,参数domain指定了套接字的协议域。
协议域是一组协议的集合,它定义了套接字可以用于通信的协议类型。
常用的协议域包括AF_INET(IPv4协议)、AF_INET6(IPv6协议)、AF_UNIX(本地通信协议)等。
1. AF_INET(IPv4协议)在使用IPv4协议进行通信时,可以使用AF_INET作为套接字的协议域。
IPv4协议是当前广泛应用的网络协议,它使用32位地址来标识网络中的主机。
2. AF_INET6(IPv6协议)当需要使用IPv6协议进行通信时,可以选择AF_INET6作为套接字的协议域。
IPv6协议是IPv4协议的升级版,它使用128位地址来标识网络中的主机,解决了IPv4地址不足的问题。
3. AF_UNIX(本地通信协议)如果需要在同一台主机上的进程之间进行通信,可以选择AF_UNIX 作为套接字的协议域。
AF_UNIX提供了一种本地通信的方式,不需要通过网络传输数据。
二、参数二:type(套接字的类型)在socket函数中,参数type指定了套接字的类型。
套接字的类型决定了套接字的工作方式和特性。
常用的套接字类型包括SOCK_STREAM(流式套接字)和SOCK_DGRAM(数据报套接字)。
1. SOCK_STREAM(流式套接字)当需要建立可靠的、面向连接的通信时,可以选择SOCK_STREAM作为套接字的类型。
流式套接字提供了一种面向连接的、可靠的通信方式,数据按照顺序传输,不会丢失和重复。
2. SOCK_DGRAM(数据报套接字)如果需要进行无连接的、不可靠的通信,可以选择SOCK_DGRAM作为套接字的类型。
java中socket的用法Java中的Socket是一种网络通信协议,它可以在不同的计算机之间进行数据传输。
Socket是一种基于TCP/IP协议的网络通信协议,它可以在不同的计算机之间进行数据传输。
在Java中,Socket是一个类,它提供了一种简单的方式来实现网络通信。
Socket的用法在Java中,Socket的用法非常简单。
首先,我们需要创建一个Socket对象。
这个对象可以用来连接到另一个计算机上的Socket 对象。
在创建Socket对象时,我们需要指定要连接的计算机的IP 地址和端口号。
例如,下面的代码创建了一个Socket对象,它连接到IP地址为192.168.1.100,端口号为8080的计算机上:```Socket socket = new Socket("192.168.1.100", 8080);```一旦我们创建了Socket对象,我们就可以使用它来进行数据传输。
在Java中,Socket提供了两个流来进行数据传输:InputStream 和OutputStream。
InputStream用于从Socket中读取数据,而OutputStream用于向Socket中写入数据。
例如,下面的代码从Socket中读取数据:```InputStream inputStream = socket.getInputStream();byte[] buffer = new byte[1024];int len = inputStream.read(buffer);String data = new String(buffer, 0, len);```这个代码片段首先获取了Socket的InputStream对象,然后创建了一个1024字节的缓冲区。
接下来,它调用了InputStream的read()方法来读取数据,并将读取的数据存储在缓冲区中。
最后,它将缓冲区中的数据转换为字符串。
socket的实现原理Socket是实现网络通信的一种机制,它允许不同计算机之间的进程通过网络进行交互。
Socket的实现原理基于传输层协议(如TCP或UDP),它将网络通信抽象为一种文件系统操作,使得进程可以通过读写文件的方式进行网络通信。
在Socket的实现中,一般包含服务器端和客户端两部分。
服务器端创建一个监听Socket,并指定一个本地地址和端口。
客户端通过创建一个Socket,并指定目标服务器的地址和端口来与服务器建立连接。
在具体实现中,Server Socket会将指定的地址和端口与底层操作系统的网络协议栈绑定,从而监听来自客户端的连接请求。
当有客户端发起连接请求时,服务器端的操作系统会生成一个新的Socket以响应此请求,并将该Socket与客户端的地址和端口关联。
对于实现Socket通信的具体过程,可以分为以下几个步骤:1. 服务器端创建一个Server Socket,并指定要监听的地址和端口。
2. 服务器端使用Server Socket的accept()方法等待客户端的连接请求。
3. 客户端创建一个Socket,并指定目标服务器的地址和端口。
4. 客户端使用Socket的connect()方法与服务器建立连接。
5. 服务器端accept()方法返回一个新的Socket,表示客户端的连接。
6. 服务器端使用返回的Socket与客户端进行通信。
7. 客户端和服务器端之间可以通过Socket的输入输出流进行数据的读写。
在以上步骤中,底层的网络协议栈会负责实际的数据传输,通过封装和解封装数据包来实现数据的可靠传输或无连接传输。
而Socket本身则提供了一组高级的接口,使得程序员可以更方便地进行网络通信的编程。
需要注意的是,Socket通信的具体实现可能会根据不同的网络协议或编程语言有所差异,但其基本原理是相通的。
通过使用Socket,我们可以方便地实现各种网络应用,如网页浏览、文件传输、聊天等。
`stream_socket` 是 PHP 中用于操作网络套接字的一系列函数。
这些函数提供了一种相对低级别的网络编程接口,允许开发者创建和操作网络连接,包括TCP、UDP 连接等。
使用 `stream_socket` 系列函数,可以实现服务器和客户端之间的数据通信。
### 基本用法#### 创建服务器 (TCP)```php// 创建一个服务器端套接字$server = stream_socket_server(");if ($server === false) {throw new UnexpectedValueException("Could not bind to socket: $errorMessage");}while ($client = @stream_socket_accept($server)) {fwrite($client, 'Hello World!' . PHP_EOL);fclose($client);}fclose($server);```这段代码创建了一个监听在本机 8000 端口的 TCP 服务器。
当客户端连接时,它发送"Hello World!" 给客户端,然后关闭连接。
#### 创建客户端 (TCP)```php// 连接到服务器$client = stream_socket_client(");if ($client === false) {throw new UnexpectedValueException("Failed to connect: $errorMessage");}echo stream_get_contents($client);fclose($client);```这段代码尝试连接到本机的 8000 端口上的服务器,并读取从服务器接收到的数据。
SocketGCDAsyncSocket(异步Socket)Socket*********************************************简单理解Socket 就是⽹络连接,可以实现两个点之间的数据通讯。
•Socket允许使⽤长连接,允许应⽤程序运⾏在异步模式(提⾼效率),只有在需要的时候才接收数据•使⽤Socket,可以只传送数据本⾝⽽不⽤进⾏XML封装,⼤⼤降低数据传输的开销在(JSON)之前出现的iOS中常⽤的两种Socket类型Ø流式Socket(SOCK_STREAM):流式是⼀种⾯向连接的Socket,针对于⾯向连接的TCP服务应⽤Ø数据报式Socket(SOCK_DGRAM):数据报式Socket是⼀种⽆连接的Socket,对应于⽆连接的UDP服务应⽤•在iOS中以NSStream(流)来发送和接收数据开发步骤{⽹络连接设置 1.设置⽹络连接,绑定到主机和端⼝ 2.设置输⼊流和输出流的代理,监听数据流的状态 3.将输⼊输出流添加⾄运⾏循环 4.打开输⼊流和输出流发送消息给服务器有可读取字节时,读取服务器返回的内容到达流末尾时,关闭流,同时并从主运⾏循环中删除}通过Scoket可以实现所有的⽹络功能:包括:GET、POST、PUT、DELETE⽂件读取、写⼊(I/O)⽅式是以(⼆进制)流的⽅式读取的最主要的应⽤场景是:⾃定义的协议,编写⾃由的⽹络应⽤!Socket 的难点:1. 因为所有的(I/O)输⼊输出都是在⼀个代理⽅法中调⽤,随着⾃定义协议的复杂度的提⾼,程序编写难度势必要⼤幅度提升。
2. 多线程的处理!输⼊流和输出流都添加到了主运⾏循环,如果应⽤过于复杂,将影响主线程程序的性能因此,需要使⽤另外⼀个运⾏循环,专门管理输⼊输出流。
代理⽅法的⼯作是对数据的输⼊输出流进⾏“解析”,解析⼯作同样不需要影响到主线程的⼯作。
3.多线程⽅⾯的处理,是Socket的⼀⼤难点!可以使⽤第三⽅框架GCDAsyncSocket来解决多线程问题。
socket使用中读取响应消息的3种方法在网络通信中,socket是一种常用的通信工具,可以用于实现客户端和服务器之间的数据交互。
在使用socket进行通信时,通常会发送请求消息给服务器,并从服务器获取响应消息。
本文将介绍socket使用中读取响应消息的三种常用方法。
一、使用recv方法读取响应消息socket对象的recv方法是最常用的读取响应消息的方法之一。
该方法用于从socket接收数据,并返回接收到的数据。
在读取响应消息时,可以通过设置缓冲区的大小来控制每次读取的数据量。
以下是使用recv方法读取响应消息的示例代码:```python# 创建socket对象import sockets = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 连接服务器s.connect(('server_ip', server_port))# 发送请求消息request = 'GET / HTTP/1.1\r\nHost: server_ip\r\n\r\n's.send(request.encode())# 读取响应消息response = b''while True:data = s.recv(1024)if not data:breakresponse += data# 关闭socket连接s.close()# 打印响应消息print(response.decode())```二、使用makefile方法读取响应消息socket对象的makefile方法可以将socket对象封装为一个文件对象,从而可以使用文件对象的相关方法进行数据读取。
通过调用makefile方法,可以简化读取响应消息的过程。
以下是使用makefile方法读取响应消息的示例代码:```python# 创建socket对象import sockets = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 连接服务器s.connect(('server_ip', server_port))# 发送请求消息request = 'GET / HTTP/1.1\r\nHost: server_ip\r\n\r\n's.send(request.encode())# 转换为文件对象f = s.makefile('r')# 读取响应消息response = f.read()# 关闭socket连接s.close()# 打印响应消息print(response)```三、使用iter方法读取响应消息socket对象的iter方法可以将socket对象封装为一个可迭代对象,从而可以通过遍历的方式逐行读取响应消息。
socket原理及使用方式Socket原理及使用方式一、Socket原理Socket(套接字)是计算机网络中用于实现网络通信的一种机制。
它允许应用程序通过网络发送和接收数据,实现进程之间的通信。
Socket通信基于客户端-服务器模型,其中一个进程充当服务器,另一个进程充当客户端。
Socket通信的实现依赖于TCP/IP协议栈。
TCP/IP协议栈是一组协议的集合,包括网络层、传输层、应用层等多个层级。
其中,网络层负责将数据包从源地址传输到目的地址,传输层负责将数据可靠地传输给目的进程。
在Socket通信中,服务器端通过创建一个Socket对象并绑定到一个特定的IP地址和端口号上,来监听客户端的连接请求。
当客户端发起连接请求时,服务器端会接受该请求并与客户端建立一个连接。
连接建立后,服务器端和客户端就可以通过Socket对象进行双向的数据传输。
二、Socket使用方式1. 创建Socket对象:在服务器端,使用ServerSocket类的实例来创建一个Socket对象,指定IP地址和端口号。
在客户端,使用Socket类的实例来创建一个Socket对象,指定服务器的IP地址和端口号。
2. 绑定Socket对象:在服务器端,使用ServerSocket类的bind()方法将Socket对象绑定到一个特定的IP地址和端口号上。
在客户端,无需绑定Socket对象。
3. 监听连接请求:在服务器端,使用ServerSocket类的listen()方法开始监听客户端的连接请求。
4. 接受连接请求:在服务器端,使用ServerSocket类的accept()方法接受客户端的连接请求,并返回一个新的Socket对象,用于与客户端进行通信。
5. 建立连接:在客户端,使用Socket类的connect()方法与服务器端建立连接。
6. 数据传输:在建立连接后,服务器端和客户端可以通过Socket 对象的输入流和输出流进行数据的读写操作。
linux创建socket收发链路层报文的c语言代码引言概述:在Linux操作系统中,使用C语言编写代码可以创建socket并进行收发链路层报文的操作。
本文将详细介绍如何使用C语言编写代码来实现这一功能。
正文内容:1. socket的创建1.1. 引入必要的头文件:在C语言代码中,需要引入一些必要的头文件,如<sys/types.h>、<sys/socket.h>和<netinet/in.h>等,以便使用相关的函数和数据结构。
1.2. 创建socket:使用socket()函数可以创建一个socket,该函数需要指定协议族、套接字类型和协议类型等参数。
常用的协议族有AF_PACKET(链路层协议族)、AF_INET(IPv4协议族)和AF_INET6(IPv6协议族)等。
1.3. 设置socket选项:可以使用setsockopt()函数来设置socket的选项,如设置接收和发送缓冲区的大小等。
2. 绑定socket2.1. 创建一个用于绑定的结构体:使用struct sockaddr_ll结构体来保存链路层地址信息,包括接口索引、协议类型和目标MAC地址等。
2.2. 绑定socket:使用bind()函数将socket与特定的链路层地址绑定,以便接收和发送链路层报文。
3. 发送链路层报文3.1. 构建报文:使用C语言的数据结构和函数来构建链路层报文,包括设置目标MAC地址、源MAC地址、协议类型和数据等。
3.2. 发送报文:使用sendto()函数发送链路层报文,该函数需要指定socket、报文数据和报文长度等参数。
4. 接收链路层报文4.1. 创建一个接收缓冲区:使用malloc()函数动态分配一个足够大的缓冲区来接收链路层报文。
4.2. 接收报文:使用recvfrom()函数接收链路层报文,该函数需要指定socket、接收缓冲区和缓冲区大小等参数。
5. 关闭socket5.1. 关闭socket:使用close()函数关闭已创建的socket,释放相关资源。
使用NSStream 来实现Socket这玩意儿已经折腾我小半年了,因为没有socket 开发方面的经验,跌跌撞撞遇到了不少麻烦。
以下是目前应用在我程序中的Stream 类,真机真网络使用正常,3G 和wifi 都可以用。
只是回调部分写的比较外行……应该还有更好的回调方式。
以下代码除了SynthesizeSingleton.h 外,都是从我自己的代码里一行一行挑出来的,没有测试,可能会有一些错误。
但关键部分都在了,应该问题不大。
先说一下理论。
这个类使用了Singleton ,因此永远只有一个实例。
没有实例时会自动生成实例,可以在程序中的任何位置调用它。
一般来说,只要跟服务器建立一次连接即可,产生一对stream ,分别是outStream 和inStream ,所有的数据都通过它们不断地发送和接收。
stream 的end 意味着连接中断,如果还需要访问服务器的话,得重新连接stream 。
(也就是重新实例化一下我这个类)每次发送和接受的数据包大小需要自己控制,而不是等stream 来告诉你这个数据包有多大,因为stream 不会告诉你……控制方法之一:通过添加一个特殊的后缀来判断,比如“<EOF>”,每次读到这个组合就认为数据读完。
但是问题很明显,这个只能用于string 。
控制方法之二:通过添加一个4字节的前缀来判断长度。
这4个byte 的byte[]数组,是当前数据包的长度信息,根据这个信息来读取一定长度的数据。
每次数据收完后,我用了一个取巧的方法来把数据返还给调用stream 的函数……这个部分需要改进。
代码SynthesizeSingleton.h ,实现singleton 的类?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 //// SynthesizeSingleton.h// CocoaWithLove//// Created by Matt Gallagher on 20/10/08.// Copyright 2009 Matt Gallagher. All rights reserved.//// Permission is given to use this source code file without charge in any// project, commercial or otherwise, entirely at your risk, with the condition// that any redistribution (in part or whole) of source code must retain// this copyright and permission notice. Attribution in compiled projects is// appreciated but not required.//#define SYNTHESIZE_SINGLETON_FOR_CLASS(classname) \17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 static classname *shared##classname = nil; \\+ (classname *)shared##classname \{ \@synchronized(self) \{ \if (shared##classname == nil) \{ \shared##classname = [[self alloc] init]; \} \} \\return shared##classname; \} \\+ (id)allocWithZone:(NSZone *)zone \{ \@synchronized(self) \{ \if (shared##classname == nil) \{ \shared##classname = [super allocWithZone:zone]; \return shared##classname; \} \} \\return nil; \} \\- (id)copyWithZone:(NSZone *)zone \{ \return self; \} \\- (id)retain \{ \return self; \} \\- (NSUInteger)retainCount \{ \return NSUIntegerMax; \} \61 62 63 64 65 66 67 68 - (void)release \{ \} \\- (id)autorelease \{ \return self; \}Stream.h?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #import <FOUNDA TION Foundation.h> #import <CFNETWORK CFNetwork.h> #import <SYSTEMCONFIGURA TION SystemConfiguration.h> #import <NETINET in.h> #import <ARPA inet.h> @interface Stream : NSObject { NSInputStream *inStream; NSOutputStream *outStream; NSMutableData *dataBuffer; BOOL _hasEstablished; id _currentObject; int _numCondition; BOOL _isFirstFourBytes; uint remainingToRead; } + (Stream *)sharedStream; -(void)requestData:(NSString *)requestString whoRequest:(id)currentObject condition:(int)numCondition; -(void)manageData:(NSData *)receivedData; @endStream.m?1 2 3 #import "Stream.h"#import "SynthesizeSingleton.h"4 5 6 7 8 9 10 11 12 1314 151617181920 21 2223 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 @implementation StreamSYNTHESIZE_SINGLETON_FOR_CLASS(Stream);-(void)startClient{_hasEstablished = NO;CFReadStreamRef readStream = NULL;CFWriteStreamRef writeStream = NULL;NSString *server = /*你的服务器地址,比如我公司服务器地址[url][/url]*/;//这里没有用NSStream 的getStreamsToHost ,是因为真机编译时有黄色提示说不存在这个函数。
//虽然真机能用,但我担心上传到APP Store 时会被reject ,所以就用了更底层的CFStreamCreatePairWithSocketToHost 。
//其实一点都不难,一样用的~ CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault,(CFStringRef)server,1234,//服务器接收数据的端口 &readStream,&writeStream);if(readStream && writeStream){inStream = (NSInputStream *)readStream;outStream = (NSOutputStream *)writeStream;}else{//Error Control}}-(void)closeStreams{[[PromptV iew sharedPromptView] dismissPromptV iew];[inStream close];[outStream close];[inStreamremoveFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [outStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];[inStream setDelegate:nil];[outStream setDelegate:nil];48 49 50 51 52 53 54 55 56 57 58 59 60 6162 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 8182 83 84 85 86 87 88 89 90 91 [inStream release];[outStream release];inStream = nil;outStream = nil;}-(void)openStreams{[inStream retain];[outStream retain];[inStream setProperty:NSStreamSocketSecurityLevelSSLv3 forKey:NSStreamSocketSecurityLevelKey];[outStream setProperty:NSStreamSocketSecurityLevelSSLv3 forKey:NSStreamSocketSecurityLevelKey];//不需要SSL 的话,下面这行可以去掉。
CFWriteStreamSetProperty((CFWriteStreamRef)outStream, kCFStreamPropertySSLSettings, [NSMutableDictionarydictionaryWithObjectsAndKeys:(id)kCFBooleanFalse,kCFStreamSSLV alidatesCertificateChain ,kCFBooleanFalse,kCFStreamSSLIsServer,nil]);[inStream setDelegate:self];[outStream setDelegate:self];[inStream scheduleInRunLoop:[NSRunLoop currentRunLoop]forMode:NSDefaultRunLoopMode]; [outStream scheduleInRunLoop:[NSRunLoopcurrentRunLoop] forMode:NSDefaultRunLoopMode];[inStream open];[outStream open];}- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{switch(eventCode) {case NSStreamEventHasBytesA vailable:{if(_isFirstFourBytes)//读取前4个字节,算出数据包大小 {uint8_t bufferLen[4];if([inStream read:bufferLen maxLength:4] == 4){remainingToRead= ((bufferLen[0]<<24)&0xff000000)+((bufferLen[1]<<16)&0xff0000)+((bufferLen[2]<<8)&0xff 00)+(bufferLen[3] & 0xff);_isFirstFourBytes = NO;}else93 94 95 96 9798 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 [self closeStreams];//Error Control}}else//根据数据包大小读取数据 {int actuallyRead;uint8_t buffer[32768];//32KB 的缓冲区,缓冲区太小的话会明显影响真机上的通信速度if (!dataBuffer) {dataBuffer = [[NSMutableData alloc] init];}actuallyRead = [inStream read:buffer maxLength:sizeof(buffer)];if(actuallyRead == -1){[self closeStreams];//Error Control}else if(actuallyRead == 0){//Do something if you want}else{[dataBuffer appendBytes:buffer length:actuallyRead];remainingToRead -= actuallyRead;}if(remainingToRead == 0){_isFirstFourBytes = YES;[self manageData:dataBuffer];//数据接收完毕,把数据送回调用sream 的函数 [dataBuffer release];dataBuffer = nil;}}break;}case NSStreamEventEndEncountered://连接断开或结束{[self closeStreams];break;}case NSStreamEventErrorOccurred://无法连接或断开连接{if([[aStream streamError] code])//确定code 不是0……有时候正常使用时会跳出code 为0的错误,但其实一点问题都没有,可以继续使用,很奇怪……8 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 [self closeStreams];break;}}case NSStreamEventOpenCompleted:{_hasEstablished = YES;break;}case NSStreamEventHasSpaceA vailable:{break;}case NSStreamEventNone:default:break;}}//判断是否能连接到服务器。