WiFi傳書(shū)
1叶洞、iPhone傳輸文件的幾種方式
- 通過(guò)itunes傳輸文件到documents
- 通過(guò)蘋(píng)果iOS11文件APP->更多->打開(kāi)
- 客戶(hù)端自定義協(xié)議下載(百度閱讀先將文件上傳到服務(wù)器田篇,再下載)
- WiFi傳書(shū)
2、WiFi傳書(shū)的原理
- 將手機(jī)作為服務(wù)器兴革,在同一網(wǎng)絡(luò)下绎晃,可以用過(guò)瀏覽器訪(fǎng)問(wèn)到服務(wù)器,上傳文件后杂曲,服務(wù)器(即手機(jī))將文件存儲(chǔ)到沙盒內(nèi)
3庶艾、技術(shù)選型
- CocoaHTTPServer 是面向Mac OS X和iOS app的輕量級(jí)、可嵌入的HTTP服務(wù)器框架擎勘。
- CocoaHTTPServer是由deusty designs開(kāi)源的一個(gè)項(xiàng)目咱揍,支持異步socket,ipv4和ipv6棚饵,http Authentication和TLS加密
- 瀏覽器上傳本地書(shū)籍煤裙,使用ajax + html上傳文件,表單上傳的方式
4噪漾、HTTPSERVER 技術(shù)要點(diǎn)
1硼砰、初始化HTTPServer,設(shè)置web路徑,需要提供web文件
- (void)setServer {
self.httpServer = [[HTTPServer alloc] init];//初始化
[self.httpServer setType:@"_http._tcp."];//通過(guò)Bonjour服務(wù)發(fā)布的類(lèi)型,允許瀏覽器訪(fǎng)問(wèn)
[self.httpServer setPort:8080];//設(shè)置端口
[self.httpServer setConnectionClass:[MyHTTPConnection class]];//設(shè)置處理連接的自定義類(lèi)文件
NSString *webPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Web"];
DDLogInfo(@"Setting document root: %@", webPath);
[self.httpServer setDocumentRoot:webPath];//設(shè)置服務(wù)器根目錄
NSLog(@"home = %@",NSHomeDirectory());
}
2、 設(shè)置支持的方法
- (BOOL)supportsMethod:(NSString *)method atPath:(NSString *)path
{
HTTPLogTrace();
// Add support for POST
if ([method isEqualToString:@"POST"])
{
return YES;
}
if ([method isEqualToString:@"DELETE"]) {
return YES;
}
if ([method isEqualToString:@"GET"]) {
return YES;
}
return [super supportsMethod:method atPath:path];
}
2欣硼、 處理請(qǐng)求
- (NSObject<HTTPResponse> *)httpResponseForMethod:(NSString *)method URI:(NSString *)path
{
HTTPLogTrace();
if ([method isEqualToString:@"POST"] && [path isEqualToString:@"/upload.html"])
{
// this method will generate response with links to uploaded file
NSMutableString* filesStr = [[NSMutableString alloc] init];
for( NSString* filePath in uploadedFiles ) {
//generate links
[filesStr appendFormat:@"<a href=\"%@\"> %@ </a><br/>",filePath, [filePath lastPathComponent]];
}
NSString* templatePath = [[config documentRoot] stringByAppendingPathComponent:@"upload.html"];
NSDictionary* replacementDict = [NSDictionary dictionaryWithObject:filesStr forKey:@"MyFiles"];
// use dynamic file response to apply our links to response template
return [[HTTPDynamicFileResponse alloc] initWithFilePath:templatePath forConnection:self separator:@"%" replacementDictionary:replacementDict];
}
if( [method isEqualToString:@"GET"] && [path hasPrefix:@"/upload/"] ) {
// let download the uploaded files
return [[HTTPFileResponse alloc] initWithFilePath: [[config documentRoot] stringByAppendingString:path] forConnection:self];
}
return [super httpResponseForMethod:method URI:path];
}
3夺刑、 處理文件上傳內(nèi)容
上次有2個(gè)part:一個(gè)是文件名,另一個(gè)是文件內(nèi)容
- (BOOL)expectsRequestBodyFromMethod:(NSString *)method atPath:(NSString *)path
{
HTTPLogTrace();
// Inform HTTP server that we expect a body to accompany a POST request
if([method isEqualToString:@"POST"] && [path hasPrefix:@"/upload"]) {
// here we need to make sure, boundary is set in header
NSString* contentType = [request headerField:@"Content-Type"];
NSUInteger paramsSeparator = [contentType rangeOfString:@";"].location;
if( NSNotFound == paramsSeparator ) {
return NO;
}
if( paramsSeparator >= contentType.length - 1 ) {
return NO;
}
NSString* type = [contentType substringToIndex:paramsSeparator];
if( ![type isEqualToString:@"multipart/form-data"] ) {
// we expect multipart/form-data content type
return NO;
}
// enumerate all params in content-type, and find boundary there
NSArray* params = [[contentType substringFromIndex:paramsSeparator + 1] componentsSeparatedByString:@";"];
for( NSString* param in params ) {
paramsSeparator = [param rangeOfString:@"="].location;
if( (NSNotFound == paramsSeparator) || paramsSeparator >= param.length - 1 ) {
continue;
}
NSString* paramName = [param substringWithRange:NSMakeRange(1, paramsSeparator-1)];
NSString* paramValue = [param substringFromIndex:paramsSeparator+1];
if( [paramName isEqualToString: @"boundary"] ) {
// let's separate the boundary from content-type, to make it more handy to handle
[request setHeaderField:@"boundary" value:paramValue];
}
}
// check if boundary specified
if( nil == [request headerField:@"boundary"] ) {
return NO;
}
return YES;
}
return [super expectsRequestBodyFromMethod:method atPath:path];
}
4分别、 處理body數(shù)據(jù)
- (void)processBodyData:(NSData *)postDataChunk
{
HTTPLogTrace();
// append data to the parser. It will invoke callbacks to let us handle
// parsed data.
[request appendData:postDataChunk];//post body存儲(chǔ)
[parser appendData:postDataChunk];//文件存儲(chǔ)
}