ios开发之iOSSocket开发这个类使用了Singleton,因此永远只有一个实例。没有实例时会自动生成实例,可以在程序中的任何位置调用它。一般来说,只要跟服务器建立一次连接即可,产生一对stream,分别是outStream和inStream,所有的数据都通过它们不断地发送和接收。stream的end意味着连接中断,如果还需要访问服务器的话,得重新连接stream。(也就是重新实例化一下我这个类)每次发送和接受的数据包大小需要自己控制,而不是等stream来告诉你这个数据包有多大,因为stream不会告诉你……控制方法之一:通过添加一个特殊的后缀来判断,比如“EOF”,每次读到这个组合就认为数据读完。但是问题很明显,这个只能用于string。控制方法之二:通过添加一个4字节的前缀来判断长度。这4个byte的byte[]数组,是当前数据包的长度信息,根据这个信息来读取一定长度的数据。每次数据收完后,我用了一个取巧的方法来把数据返还给调用stream的函数……这个部分需要改进。SynthesizeSingleton.h,实现singleton的类1.//2.//SynthesizeSingleton.h3.//CocoaWithLove4.//5.//CreatedbyMattGallagheron20/10/08.6.//Copyright2009MattGallagher.Allrightsreserved.7.//8.//Permissionisgiventousethissourcecodefilewithoutchargeinany9.//project,commercialorotherwise,entirelyatyourrisk,withthecondition10.//thatanyredistribution(inpartorwhole)ofsourcecodemustretain11.//thiscopyrightandpermissionnotice.Attributionincompiledprojectsis12.//appreciatedbutnotrequired.13.//14.15.#defineSYNTHESIZE_SINGLETON_FOR_CLASS(classname)\16.\17.staticclassname*shared##classname=nil;\18.\19.+(classname*)shared##classname\20.{\21.@synchronized(self)\22.{\23.if(shared##classname==nil)\24.{\25.shared##classname=[[selfalloc]init];\26.}\27.}\28.\29.returnshared##classname;\30.}\31.\32.+(id)allocWithZone:(NSZone*)zone\33.{\34.@synchronized(self)\35.{\36.if(shared##classname==nil)\37.{\38.shared##classname=[superallocWithZone:zone];\39.returnshared##classname;\40.}\41.}\42.\43.returnnil;\44.}\45.\46.-(id)copyWithZone:(NSZone*)zone\47.{\48.returnself;\49.}\50.\51.-(id)retain\52.{\53.returnself;\54.}\55.\56.-(NSUInteger)retainCount\57.{\58.returnNSUIntegerMax;\59.}\60.\61.-(void)release\62.{\63.}\64.\65.-(id)autorelease\66.{\67.returnself;\68.}复制代码Stream.h1.#importFoundation/Foundation.h2.#importCFNetwork/CFNetwork.h3.#importSystemConfiguration/SystemConfiguration.h4.#importnetinet/in.h5.#importarpa/inet.h6.7.@interfaceStream:NSObject{8.NSInputStream*inStream;9.NSOutputStream*outStream;10.NSMutableData*dataBuffer;11.12.BOOL_hasEstablished;13.id_currentObject;14.int_numCondition;15.16.BOOL_isFirstFourBytes;17.uintremainingToRead;18.}19.20.+(Stream*)sharedStream;21.-(void)requestData:(NSString*)requestStringwhoRequest:(id)currentObjectcondition:(int)numCondition;22.-(void)manageData:(NSData*)receivedData;23.@endStream.m1.#importStream.h2.#importSynthesizeSingleton.h3.4.@implementationStream5.6.SYNTHESIZE_SINGLETON_FOR_CLASS(Stream);7.8.-(void)startClient9.{10._hasEstablished=NO;11.CFReadStreamRefreadStream=NULL;12.CFWriteStreamRefwriteStream=NULL;13.NSString*server=/*你的服务器地址,比如我公司服务器地址[url][/url]*/;14.//这里没有用NSStream的getStreamsToHost,是因为真机编译时有黄色提示说不存在这个函数。15.//虽然真机能用,但我担心上传到APPStore时会被reject,所以就用了更底层的CFStreamCreatePairWithSocketToHost。16.//其实一点都不难,一样用的~17.CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault,18.(CFStringRef)server,19.1234,//服务器接收数据的端口20.&readStream,21.&writeStream);22.23.24.if(readStream&&writeStream)25.{26.inStream=(NSInputStream*)readStream;27.outStream=(NSOutputStream*)writeStream;28.}29.else30.{31.//ErrorControl32.}33.}34.35.-(void)closeStreams{36.[[PromptViewsharedPromptView]dismissPromptView];37.[inStreamclose];38.[outStreamclose];39.[inStreamremoveFromRunLoop:[NSRunLoopcurrentRunLoop]forMode:NSDefaultRunLoopMode];40.[outStreamremoveFromRunLoop:[NSRunLoopcurrentRunLoop]forMode:NSDefaultRunLoopMode];41.[inStreamsetDelegate:nil];42.[outStreamsetDelegate:nil];43.[inStreamrelease];44.[outStreamrelease];45.inStream=nil;46.outStream=nil;47.}48.49.-(void)openStreams{50.[inStreamretain];51.[outStreamretain];52.[inStreamsetProperty:NSStreamSocketSecurityLevelSSLv3forKey:NSStreamSocketSecurityLevelKey];53.[outStreamsetProperty:NSStreamSocketSecurityLevelSSLv3forKey:NSStreamSocketSecurityLevelKey];54.//不需要SSL的话,下面这行可以去掉。55.CFWriteStreamSetProperty((CFWriteStreamRef)outStream,kCFStreamPropertySSLSettings,[NSMutableDictionarydictionaryWithObjectsAndKeys:(id)kCFBooleanFalse,kCFStreamSSLValidatesCertificateChain,kCFBooleanFalse,kCFStreamSSLIsServer,nil]);56.[inStreamsetDelegate:self];57.[outStreamsetDelegate:self];58.[inStreamscheduleInRunLoop:[NSRunLoopcurrentRunLoop]forMode:NSDefaultRunLoopMode];59.[outStreamscheduleInRunLoop:[NSRunLoopcurrentRunLoop]forMode:NSDefaultRunLoopMode];60.[inStreamopen];61.[outStreamopen];62.}63.64.-(void)stream:(NSStream*)aStreamhandleEvent:(NSStreamEvent)eventCode65.{66.switch(eventCode){67.caseNSStreamEventHasBytesAvailable:68.{69.if(_isFirstFourBytes)//读取前4个字节,算出数据包大小70.{71.uint8_tbufferLen[4];72.if([inStreamread:bufferLenmaxLength:4]==4)73.{74.remainingToRead=((bufferLen[0]24)&0xff000000)+((bufferLen[1]16)&0xff0000)+((bufferLen[2]8)&0xff00)+(bufferLen[3]&0xff);75._isFirstFourBytes=NO;76.}77.else78.{79.[selfcloseStreams];80.//ErrorControl81.}82.}83.else//根据数据包大小读取数据84.{85.intactuallyRead;86.uint8_tbuffer[32768];//32KB的缓冲区,缓冲区太小的话会明显影响真机上的通信速度87.if(!dataBuffer){88.dataBuffer=[[NSMutableDataalloc]init];89.}90.91.actuallyRead=[inStreamread:buffermaxLength:sizeof(buffer)];92.if(actuallyRead==-1){93.[selfcloseStreams];94.//Err