IOS程序猿阵线联盟-汇总各类技术干货iOS

WiFi传书

2018-03-14  本文已影响28人  浮海_2015

WiFi传书

1、iPhone传输文件的几种方式

  1. 通过itunes传输文件到documents
  2. 通过苹果iOS11文件APP->更多->打开
  3. 客户端自定义协议下载(百度阅读先将文件上传到服务器,再下载)
  4. WiFi传书

2、WiFi传书的原理

3、技术选型

4、HTTPSERVER 技术要点

1、初始化HTTPServer,设置web路径,需要提供web文件

- (void)setServer {
    self.httpServer = [[HTTPServer alloc] init];//初始化
    [self.httpServer setType:@"_http._tcp."];//通过Bonjour服务发布的类型,允许浏览器访问
    [self.httpServer setPort:8080];//设置端口
    [self.httpServer setConnectionClass:[MyHTTPConnection class]];//设置处理连接的自定义类文件
    NSString *webPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Web"];
    DDLogInfo(@"Setting document root: %@", webPath);
    [self.httpServer setDocumentRoot:webPath];//设置服务器根目录
    NSLog(@"home = %@",NSHomeDirectory());
}

2、 设置支持的方法

- (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、 处理请求

- (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、 处理文件上传内容

上次有2个part:一个是文件名,另一个是文件内容

- (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数据

- (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存储
    [parser appendData:postDataChunk];//文件存储
}

上一篇下一篇

猜你喜欢

热点阅读