使用NSStream来实现SocketWord下载.docx
- 文档编号:8678207
- 上传时间:2023-05-12
- 格式:DOCX
- 页数:51
- 大小:45.58KB
使用NSStream来实现SocketWord下载.docx
《使用NSStream来实现SocketWord下载.docx》由会员分享,可在线阅读,更多相关《使用NSStream来实现SocketWord下载.docx(51页珍藏版)》请在冰点文库上搜索。
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
60
61
62
63
64
65
66
67
68
//
//
SynthesizeSingleton.h
CocoaWithLove
CreatedbyMattGallagheron20/10/08.
Copyright2009MattGallagher.Allrightsreserved.
Permissionisgiventousethissourcecodefilewithoutchargeinany
project,commercialorotherwise,entirelyatyourrisk,withthecondition
thatanyredistribution(inpartorwhole)ofsourcecodemustretain
thiscopyrightandpermissionnotice.Attributionincompiledprojectsis
appreciatedbutnotrequired.
#defineSYNTHESIZE_SINGLETON_FOR_CLASS(classname)\
\
staticclassname*shared##classname=nil;
\
+(classname*)shared##classname\
{\
@synchronized(self)\
if(shared##classname==nil)\
shared##classname=[[selfalloc]init];
}\
returnshared##classname;
+(id)allocWithZone:
(NSZone*)zone\
shared##classname=[superallocWithZone:
zone];
returnnil;
-(id)copyWithZone:
returnself;
-(id)retain\
-(NSUInteger)retainCount\
returnNSUIntegerMax;
-(void)release\
-(id)autorelease\
}
Stream.h
#import<
FOUNDATIONFoundation.h>
CFNETWORKCFNetwork.h>
SYSTEMCONFIGURATIONSystemConfiguration.h>
NETINETin.h>
ARPAinet.h>
@interfaceStream:
NSObject{
NSInputStream
*inStream;
NSOutputStream
*outStream;
NSMutableData
*dataBuffer;
BOOL
_hasEstablished;
id
_currentObject;
int
_numCondition;
_isFirstFourBytes;
uint
remainingToRead;
}
+(Stream*)sharedStream;
-(void)requestData:
(NSString*)requestStringwhoRequest:
(id)currentObjectcondition:
(int)numCondition;
-(void)manageData:
(NSData*)receivedData;
@end
Stream.m
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
#import"
Stream.h"
SynthesizeSingleton.h"
@implementationStream
SYNTHESIZE_SINGLETON_FOR_CLASS(Stream);
-(void)startClient
{
_hasEstablished=NO;
CFReadStreamRef
readStream=NULL;
CFWriteStreamRef
writeStream=NULL;
NSString
*server=/*你的服务器地址,比如我公司服务器地址[url][/url]*/;
//这里没有用NSStream的getStreamsToHost,是因为真机编译时有黄色提示说不存在这个函数。
//虽然真机能用,但我担心上传到APPStore时会被reject,所以就用了更底层的CFStreamCreatePairWithSocketToHost。
//其实一点都不难,一样用的~
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault,
(CFStringRef)server,
1234,//服务器接收数据的端口
&
readStream,
writeStream);
if(readStream&
writeStream)
inStream=(NSInputStream*)readStream;
outStream=(NSOutputStream*)writeStream;
else
//ErrorControl
-(void)closeStreams{
[[PromptViewsharedPromptView]dismissPromptView];
[inStreamclose];
[outStreamclose];
[inStreamremoveFromRunLoop:
[NSRunLoopcurrentRunLoop]forMode:
NSDefaultRunLoopMode];
[outStreamremoveFromRunLoop:
[inStreamsetDelegate:
nil];
[outStreamsetDelegate:
[inStreamrelease];
[outStreamrelease];
inStream=nil;
outStream=nil;
-(void)openStreams{
[inStreamretain];
[outStreamretain];
[inStreamsetProperty:
NSStreamSocketSecurityLevelSSLv3forKey:
NSStreamSocketSecurityLevelKey];
[outStreamsetProperty:
//不需要SSL的话,下面这行可以去掉。
CFWriteStreamSetProperty((CFWriteStreamRef)outStream,kCFStreamPropertySSLSettings,[NSMutableDictionarydictionaryWithObjectsAndKeys:
(id)kCFBooleanFalse,kCFStreamSSLValidatesCertificateChain,kCFBooleanFalse,kCFStreamSSLIsServer,nil]);
self];
[inStreamscheduleInRunLoop:
[outStreamscheduleInRunLoop:
[inStreamopen];
[outStreamopen];
-(void)stream:
(NSStream*)aStreamhandleEvent:
(NSStreamEvent)eventCode
switch(eventCode){
caseNSStreamEventHasBytesAvailable:
if(_isFirstFourBytes)//读取前4个字节,算出数据包大小
uint8_tbufferLen[4];
if([inStreamread:
bufferLenmaxLength:
4]==4)
remainingToRead=((bufferLen[0]<
<
24)&
0xff000000)+((bufferLen[1]<
16)&
0xff0000)+((bufferLen[2]<
8)&
0xff00)+(bufferLen[3]&
0xff);
_isFirstFourBytes=NO;
[selfcloseStreams];
else//根据数据包大小读取数据
intactuallyRead;
uint8_tbuffer[32768];
//32KB的缓冲区,缓冲区太小的话会明显影响真机上的通信速度
if(!
dataBuffer){
dataBuffer=[[NSMutableDataalloc]init];
actuallyRead=[inStreamread:
buffermaxLength:
sizeof(buffer)];
if(actuallyRead==-1){
}elseif(actuallyRead==0){
//Dosomethingifyouwant
}else{
[dataBufferappendBytes:
bufferlength:
actuallyRead];
remainingToRead-=actuallyRead;
if(remainingToRead==0)
_isFirstFourBytes=YES;
[selfmanageData:
dataBuffer];
//数据接收完毕,把数据送回调用sream的函数
[dataBufferrelease];
dataBuffer=nil;
break;
caseNSStreamEventEndEncountered:
//连接断开或结束
caseNSStreamEventErrorOccurred:
//无法连接或断开连接
if([[aStreamstreamError]code])//确定code不是0……有时候正常使用时会跳出code为0的错误,但其实一点问题都没有,可以继续使用,很奇怪……
caseNSStreamEventOpenCompleted:
_hasEstablished=YES;
caseNSStreamEventHasSpaceAvailable:
caseNSStreamEventNone:
default:
//判断是否能连接到服务器。
这个函数用来判断网络是否连通还好,要真的判断服务器上对应的端口是否可以连接,不是很好用来着……
-(BOOL)isServerAvailable{
NSString*addressString=/*你的服务器地址,比如我公司地址[url][/url]*/;
addressString){
returnNO;
SCNetworkReachabilityRefdefaultRouteReachability=SCNetworkReachabilityCreateWithName(kCFAllocatorDefault,[addressStringUTF8String]);
SCNetworkReachabilityFlagsflags;
BOOLdidRetrieveFlags=SCNetworkReachabilityGetFlags(defaultRouteReachability,&
flags);
CF
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 使用 NSStream 实现 Socket