ios开发之iOS Socket 开发.docx

上传人:b****7 文档编号:24041358 上传时间:2023-05-23 格式:DOCX 页数:16 大小:20.59KB
下载 相关 举报
ios开发之iOS Socket 开发.docx_第1页
第1页 / 共16页
ios开发之iOS Socket 开发.docx_第2页
第2页 / 共16页
ios开发之iOS Socket 开发.docx_第3页
第3页 / 共16页
ios开发之iOS Socket 开发.docx_第4页
第4页 / 共16页
ios开发之iOS Socket 开发.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

ios开发之iOS Socket 开发.docx

《ios开发之iOS Socket 开发.docx》由会员分享,可在线阅读,更多相关《ios开发之iOS Socket 开发.docx(16页珍藏版)》请在冰豆网上搜索。

ios开发之iOS Socket 开发.docx

ios开发之iOSSocket开发

ios开发之iOSSocket开发

 

这个类使用了Singleton,因此永远只有一个实例。

没有实例时会自动生成实例,可以在程序中的任何位置调用它。

 

一般来说,只要跟服务器建立一次连接即可,产生一对stream,分别是outStream和inStream,所有的数据都通过它们不断地发送和接收。

stream的end意味着连接中断,如果还需要访问服务器的话,得重新连接stream。

(也就是重新实例化一下我这个类)

每次发送和接受的数据包大小需要自己控制,而不是等stream来告诉你这个数据包有多大,因为stream不会告诉你……

控制方法之一:

通过添加一个特殊的后缀来判断,比如“”,每次读到这个组合就认为数据读完。

但是问题很明显,这个只能用于string。

控制方法之二:

通过添加一个4字节的前缀来判断长度。

这4个byte的byte[]数组,是当前数据包的长度信息,根据这个信息来读取一定长度的数据。

每次数据收完后,我用了一个取巧的方法来把数据返还给调用stream的函数……这个部分需要改进。

SynthesizeSingleton.h,实现singleton的类

1.//

2.//  SynthesizeSingleton.h

3.//  CocoaWithLove

4.//

5.//  CreatedbyMattGallagheron20/10/08.

6.//  Copyright2009MattGallagher.Allrightsreserved.

7.//

8.//  Permissionisgiventousethissourcecodefilewithoutchargeinany

9.//  project,commercialorotherwise,entirelyatyourrisk,withthecondition

10.//  thatanyredistribution(inpartorwhole)ofsourcecodemustretain

11.//  thiscopyrightandpermissionnotice.Attributionincompiledprojectsis

12.//  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.h

1.#import  

2.#import

3.#import

4.#import

5.#import

6. 

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.  uint        remainingToRead;

18.}

19. 

20.+(Stream*)sharedStream;

21.-(void)requestData:

(NSString*)requestStringwhoRequest:

(id)currentObjectcondition:

(int)numCondition;

22.-(void)manageData:

(NSData*)receivedData;

23.@end

Stream.m

1.#import"Stream.h"

2.#import"SynthesizeSingleton.h"

3. 

4.@implementationStream

5. 

6.SYNTHESIZE_SINGLETON_FOR_CLASS(Stream);

7. 

8.-(void)startClient

9.{

10.  _hasEstablished=NO;

11.  CFReadStreamRef      readStream=NULL;

12.  CFWriteStreamRef  writeStream=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.  else

30.  {

31.      //ErrorControl

32.  }

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)eventCode 

65.{

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.          else

78.          {

79.              [selfcloseStreams];

80.              //ErrorControl

81.          }

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.              //ErrorControl

95.          }elseif(actuallyRead==0){

96.              //Dosomethingifyouwant

97.          }else{

98.              [dataBufferappendBytes:

bufferlength:

actuallyRead];

99.              remainingToRead-=actuallyRead;

100.          }

101. 

102.          if(remainingToRead==0)

103.          {

104.              _isFirstFourBytes=YES;

105.              [selfmanageData:

dataBuffer];//数据接收完毕,把数据送回调用sream的函数

106.              [dataBufferrelease];

107.              dataBuffer=nil;

108.          }

109.        }

110.        break;

111.      }

112.      caseNSStreamEventEndEncountered:

//连接断开或结束

113.      {

114.        [selfcloseStreams];

115.        break;

116.      }

117.      caseNSStreamEventErrorOccurred:

//无法连接或断开连接

118.      {

119.        if([[aStreamstreamError]code])//确定code不是0……有时候正常使用时会跳出code为0的错误,但其实一点问题都没有,可以继续使用,很奇怪……

120.        {

121.          [selfcloseStreams];

122.          break;

123.        }

124.      }

125.      caseNSStreamEventOpenCompleted:

126.      {

127.        _hasEstablished=YES;

128.        break;

129.      }

130.      caseNSStreamEventHasSpaceAvailable:

131.      {

132.        break;

133.      }

134.      caseNSStreamEventNone:

135.      default:

136.        break;

137.  }

138.}

139. 

140.//判断是否能连接到服务器。

这个函数用来判断网络是否连通还好,要真的判断服务器上对应的端口是否可以连接,不是很好用来着……

141.-(BOOL)isServerAvailable{

142.  NSString*addressString=/*你的服务器地址,比如我公司地址[url][/url]*/;

143.  if(!

addressString){

144.      returnNO;

145.  }

146. 

147.  SCNetworkReachabilityRefdefaultRouteReachability=SCNetworkReachabilityCreateWithName(kCFAllocatorDefault,[addressStringUTF8String]);

148.  SCNetworkReachabilityFlagsflags;

149. 

150.  BOOLdidRetrieveFlags=SCNetworkReachabilityGetFlags(defaultRouteReachability,&flags);

151.  CFRelease(defaultRouteReachability);

152. 

153.  if(!

didRetrieveFlags)

154.  {

155.      returnNO;

156.  }

157. 

158.  BOOLisReachable=flags&kSCNetworkFlagsReachable;

159.  BOOLneedsConnection=flags&kSCNetworkFlagsConnectionRequired;

160.  return(isReachable&&!

needsConnection)?

YES:

NO;

161.}

162. 

163.-(void)requestData:

(NSString*)requestStringwhoRequest:

(id)currentObjectcondition:

(int)numCondition

164.{

165.  if(!

[selfisServerAvailable])//如果无法连通到服务器

166.  {

167.      //ErrorControl

168.  }

169.  else

170.  {

171.      if(inStream==nil||outStream==nil)

172.      {

173.        [[StreamsharedStream]startClient];

174.        [[StreamsharedStream]openStreams];

175.        _isFirstFourBytes=YES;

176.      }

177. 

178.      if(inStream!

=nil&&outStream!

=nil)

179.      {

180.        _currentObject=curr

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1