亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

iOS實現簡單的Http服務

2019-11-14 19:36:11
字體:
來源:轉載
供稿:網友

http 是計算機之間通訊協議的比較簡單的一種。在iphone上,由于沒有同步數據和文件共享,所以實現PC與設備之間的數據傳輸的最佳方式就是在程序中嵌套一個http 服務器。在這篇帖子中,我將簡單的演示第三方的http 服務器的使用。

示例程序運行如下(在PC端輸入設備的IP和端口,便可選取當前PC的文件進行上傳至當前的設備)

該服務器涉及的相關類如下圖所示

代碼實現,創建一個自己需求的HttpConnection類繼承于第三方的HttpConnection,代碼如下

MyHTTPConnection.h

#import "HTTPConnection.h"

 

@class MultipartFormDataParser;

 

@interface MyHTTPConnection : HTTPConnection

{

    MultipartFormDataParser * parser;

    NSFileHandle * storeFile;

    NSMutableArray * uploadedFiles;

}

@end

 MyHTTPConnection.m

#import "MyHTTPConnection.h"

 

#import "HTTPMessage.h"

#import "HTTPDataResponse.h"

#import "DDNumber.h"

#import "HTTPLogging.h"

 

#import "MultipartFormDataParser.h"

#import "MultipartMessageHeaderField.h"

#import "HTTPDynamicFileResponse.h"

#import "HTTPFileResponse.h"

 

static const int httpLogLevel = HTTP_LOG_LEVEL_VERBOSE;

 

 

@interface MyHTTPConnection ()

{

    float totalSize;

    float PRogress;

}

 

 

@end

 

 

 

@implementation MyHTTPConnection

 個人需要,1-8的方法都有實現

1:- (BOOL)supportsMethod:(NSString *)method atPath:(NSString *)path

{

    NSLog(@"%s",__FUNCTION__);

    HTTPLogTrace();

    if (  [ method isEqualToString:@"POST"] ) {

        if ( [path isEqualToString:@"/upload.html"] ) {

            return YES;

        }

    }

    return  [super supportsMethod:method atPath:path];

}

 

2:-(BOOL)expectsRequestBodyFromMethod:(NSString *)method atPath:(NSString *)path{

if([method isEqualToString:@"POST"] && [path isEqualToString:@"/upload.html"]) {

        // 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];

}

3:- (NSObject<HTTPResponse> *)httpResponseForMethod:(NSString *)method URI:(NSString *)path{

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:@"%@<br/><br/>", [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];

}

4:- (void)prepareForBodyWithSize:(UInt64)contentLength{

HTTPLogTrace();

    totalSize = contentLength/1000.0/1000.0;

NSLog(@"%f",contentLength/1000.0/1000.0);

// set up mime parser

    NSString* boundary = [request headerField:@"boundary"];

    parser = [[MultipartFormDataParser alloc] initWithBoundary:boundary formEncoding:NSUTF8StringEncoding];

    parser.delegate = self;

    

uploadedFiles = [[NSMutableArray alloc] init];

}

5:- (void)processBodyData:(NSData *)postDataChunk{

HTTPLogTrace();

    progress += postDataChunk.length/1024.0/1024.0;

    NSLog(@"%f",progress);

    NSString * temp  = [ NSString stringWithFormat:@"上傳進度:%.2fMB/%.2fMB",progress,totalSize ];

    dispatch_async(dispatch_get_main_queue(), ^{

         [SVProgressHUD showProgress:progress/totalSize status:temp maskType:SVProgressHUDMaskTypeBlack];

    });

 

    // append data to the parser. It will invoke callbacks to let us handle

    // parsed data.

    [parser appendData:postDataChunk];

}

6:- (void) processStartOfPartWithHeader:(MultipartMessageHeader*) header{

 NSLog(@"%s",__FUNCTION__);

    MultipartMessageHeaderField* disposition = [header.fields objectForKey:@"Content-Disposition"];

NSString* filename = [[disposition.params objectForKey:@"filename"] lastPathComponent];

    NSLog(@"####filename=%@",filename);

    if ( (nil == filename) || [filename isEqualToString: @""] ) {

        // it's either not a file part, or

// an empty form sent. we won't handle it.

return;

}

     

    NSString* uploadDirPath = [self CreatreTempDir] ;

    

   // NSLog(@"uploadDirPath%@",[self CreatDir]);

BOOL isDir = YES;

if (![[NSFileManager defaultManager]fileExistsAtPath:uploadDirPath isDirectory:&isDir ]) {

[[NSFileManager defaultManager]createDirectoryAtPath:uploadDirPath withIntermediateDirectories:YES attributes:nil error:nil];

}

    NSString * filePath = [uploadDirPath stringByAppendingPathComponent:filename];

    NSFileManager * fileManager = [NSFileManager defaultManager];

if( [[NSFileManager defaultManager] fileExistsAtPath:filePath] ) {

        storeFile = nil;

    }

    else {

HTTPLogVerbose(@"Saving file to %@", filePath);

        NSError *error;

if(![[NSFileManager defaultManager] createDirectoryAtPath:uploadDirPath withIntermediateDirectories:true attributes:nil error:&error]) {

HTTPLogError(@"Could not create directory at path: %@----%@", filePath,error);

}

if(![[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil]) {

HTTPLogError(@"Could not create file at path: %@", filePath);

}

storeFile = [NSFileHandle fileHandleForWritingAtPath:filePath];

[uploadedFiles addObject: [NSString stringWithFormat:@"/upload/%@", filename]];

    }

 

}

7:- (void) processContent:(NSData*) data WithHeader:(MultipartMessageHeader*) header{

 if(!storeFile)

    {

        MultipartMessageHeaderField* disposition = [header.fields objectForKey:@"Content-Disposition"];

        NSString* filename = [[disposition.params objectForKey:@"filename"] lastPathComponent];

        NSLog(@"####filename=%@",filename);

        if ( (nil == filename) || [filename isEqualToString: @""] ) {

            // it's either not a file part, or

            // an empty form sent. we won't handle it.

            return;

        }

        NSString* uploadDirPath = [self CreatreTempDir] ;

        NSString * filePath = [uploadDirPath stringByAppendingPathComponent:filename];

        storeFile = [NSFileHandle fileHandleForWritingAtPath:filePath];

        [uploadedFiles addObject: [NSString stringWithFormat:@"/upload/%@", filename]];

    }

if( storeFile ) {

[storeFile writeData:data];

}

 

}

8:- (void) processEndOfPartWithHeader:(MultipartMessageHeader*) header{

dispatch_async(dispatch_get_main_queue(), ^{

        [SVProgressHUD dismiss];

    });

    progress = 0.f;

    

    MultipartMessageHeaderField* disposition = [header.fields objectForKey:@"Content-Disposition"];

NSString* filename = [[disposition.params objectForKey:@"filename"] lastPathComponent] ;

   // NSLog(@"####END ---filename=%@",filename);

    NSString * tempFilePath = [[ self CreatreTempDir ] stringByAppendingPathComponent:filename];

    

    NSMutableArray *arraynumber = [NSMutableArray arrayWithContentsOfFile:[Global getChangePathName]];

    NSString *strnumber = [arraynumber lastObject];

    

    NSString * uploadFilePath = [[ self CreatDir ] stringByAppendingPathComponent: [[NSString stringWithFormat:@"%d.",[strnumber intValue] + 1 ] stringByAppendingString:filename]];

    

    [arraynumber addObject:[NSString stringWithFormat:@"%d", [strnumber intValue] + 1]];

    

    [arraynumber writeToFile:[Global getChangePathName] atomically:YES];

 

    BOOL result = [ self copyMissFile:tempFilePath toPath:uploadFilePath ];

    

    if (result) {

        NSLog(@"移動成功");

    }else{

        NSLog(@"移動失敗");

    }

    

[storeFile closeFile];

storeFile = nil;

}

- (BOOL)copyMissFile:(NSString * )sourcePath toPath:(NSString *)toPath{

BOOL retVal ;

    NSLog(@"%s",__FUNCTION__);

//    if ( [fileManger fileExistsAtPath:toPath]  ) {

//        [fileManger removeItemAtPath:toPath error:nil];

//    }

    retVal = [[ NSFileManager defaultManager ] moveItemAtPath:sourcePath toPath:toPath error:nil];

    

    return retVal;

}

下面兩個方法都是創建文件,大家自己可以隨意定義

-(NSString *)CreatDir;

-(NSString *)CreatreTempDir;

下面根據需求實現以下這些方法,我是在全局的類里面實現的

Global.m

+ (BOOL)createiPhoneServer  //創建并設置iPhone的服務器

{

    Global * global = [ Global sharedGlobal ];

    

    global.httpServer = [[HTTPServer alloc] init];

    [global.httpServer setType:@"_http._tcp."];

    NSString *docRoot = [[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"MyResources"] stringByAppendingPathComponent:@"Web"];

 

    BOOL  isDir  = YES ;

    if ( [[NSFileManager defaultManager] fileExistsAtPath:docRoot isDirectory:&isDir  ]  ) {

        NSLog(@"找到Web文件夾");

    }

    [global.httpServer setDocumentRoot:docRoot];

    [global.httpServer setPort:Http_Port];//本地端口

    [global.httpServer setConnectionClass:[MyHTTPConnection class]];//設置連接類為我們之前代碼實現的連接類

    

    return YES;

}

//開啟服務器

+ (BOOL)startServer

{

    Global * global = [ Global sharedGlobal];

    NSError * error;

    

    

    if ( [global.httpServer start:&error] ) {

        NSLog(@"開啟成功%u",[global.httpServer listeningPort]);

        return YES;

    }else

    {

        NSLog(@"開啟失敗,%@",error);

        return NO;

 

    }

    

}

+ (BOOL)stopServer

{

    [[Global sharedGlobal].httpServer stop:YES];

    return YES;

}

 //獲得當前設備的IP

+(NSString *)getIPAddress

{

    NSString *address = @"開啟失敗";

    struct ifaddrs *interfaces = NULL;

    struct ifaddrs *temp_addr = NULL;

    int success = 0;

    // retrieve the current interfaces - returns 0 on success

    success = getifaddrs(&interfaces);

    

    

    if (success == 0) {

        // Loop through linked list of interfaces

        temp_addr = interfaces;

        

        

        while(temp_addr != NULL) {

            if(temp_addr->ifa_addr->sa_family == AF_INET) {

                // Check if interface is en0 which is the wifi connection on the iPhone

                if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) {

                    // Get NSString from C String

                    address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];

                }

            }

            temp_addr = temp_addr->ifa_next;

        }

    }

    // Free memory

    freeifaddrs(interfaces);

    

    NSString * str = nil;

    if ( [address isEqualToString:@"開啟失敗"] ) {

        str = @"開啟失敗";

    }else {

        str = [NSString stringWithFormat:@"http://%@:%d",address, Http_Port ];

    }

    return str;

}

 

 

 //獲取當前設備的網絡狀態

+(NSString *) getDeviceSSID

 

{

    

    NSArray *ifs = (__bridge id)CNCopySupportedInterfaces() ;

    

    id info = nil;

    

    for (NSString *ifnam in ifs) {

        

        info = (__bridge id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);

        

        if (info && [info count]) {

            

            break;

            

        }

        

    }

    

    NSDictionary *dctySSID = (NSDictionary *)info;

    

    NSString *ssid = [ dctySSID objectForKey:@"SSID" ];

    

    

    ssid = ssid== nil?@"無網絡":ssid;

    return ssid;

    

}

 然后再你需要的地方開啟這個服務即可,至此http 服務搭建完成,開啟服務之后就可在PC的瀏覽器輸入當前的設備IP地址和端口,如http://192.168.2.155:8088,然后上傳所需的文件即可,根據程序設計,這些文件會存在相應的地方


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
97久久精品人人澡人人爽缅北| 亚洲人成网站色ww在线| 欧美日韩一区二区三区| 青青青国产精品一区二区| 成年人精品视频| 久久久精品久久久| 国产精品中文在线| 91视频国产精品| 国产91ⅴ在线精品免费观看| 91av在线免费观看视频| 久久精品国产成人精品| 高清一区二区三区日本久| 国产一区在线播放| 欧美大片大片在线播放| 26uuu另类亚洲欧美日本老年| 国产精品国产三级国产aⅴ9色| 亚洲精品白浆高清久久久久久| 国产成人拍精品视频午夜网站| 18久久久久久| 久99久在线视频| 亚洲小视频在线| 日韩电影免费观看在线观看| 亚洲国产高清自拍| 国产精品久久久久久一区二区| 欧美最猛黑人xxxx黑人猛叫黄| 亚洲大胆人体av| 不卡在线观看电视剧完整版| 国产精品一区二区三区久久久| 欧美孕妇与黑人孕交| 欧美激情免费观看| 久久亚洲国产精品成人av秋霞| 成人午夜在线影院| 欧美国产第一页| 国产精品美女主播在线观看纯欲| 国产欧美精品在线| 福利二区91精品bt7086| 久久精品电影网| 欧美日韩亚洲精品一区二区三区| 不卡av在线播放| 欧美日韩爱爱视频| 2020久久国产精品| 日韩免费看的电影电视剧大全| 丰满岳妇乱一区二区三区| 欧美大尺度电影在线观看| 日韩美女免费视频| 日韩亚洲精品电影| 国产一区二区久久精品| 国产精品揄拍500视频| 性欧美长视频免费观看不卡| 色偷偷av一区二区三区| 国产精品一区av| 色樱桃影院亚洲精品影院| 日韩在线观看免费全| 97国产在线观看| 欧美精品videos| 中文字幕亚洲欧美一区二区三区| 亚洲男人天堂网| 久久综合久久美利坚合众国| 亚洲图片在线综合| 欧美在线精品免播放器视频| 国模视频一区二区三区| 欧美国产日产韩国视频| 日韩欧美大尺度| 欧美日韩亚洲视频| 亚洲国产免费av| 亚洲免费av电影| 亚洲美女av在线播放| 亚洲а∨天堂久久精品9966| 欧美黄色片免费观看| 日韩毛片中文字幕| 亚洲成人久久网| 国产一区二区三区免费视频| 精品性高朝久久久久久久| 亚洲尤物视频网| 亚洲伊人成综合成人网| 成人福利免费观看| 亚洲精品第一页| 国产精品白丝jk喷水视频一区| 亚洲欧美日韩视频一区| 中文字幕久精品免费视频| 日本在线观看天堂男亚洲| 亚洲免费视频在线观看| 一区二区中文字幕| 国产精品999| 久久综合亚洲社区| 色七七影院综合| 免费91麻豆精品国产自产在线观看| 久久久久久久激情视频| 亚洲一区二区久久| 精品色蜜蜜精品视频在线观看| 欧美黑人xxxⅹ高潮交| 国产精品video| 91精品国产91久久久久久| 精品无人区乱码1区2区3区在线| 78色国产精品| 亚洲精品美女免费| 国产精品一区电影| www.久久色.com| 国产精品99久久久久久人| 国产丝袜一区视频在线观看| 亚洲成人黄色网址| 亚洲最大av在线| 国产日韩欧美日韩| 日韩中文字幕国产| 欧美二区乱c黑人| 国产原创欧美精品| 欧美日韩在线观看视频| 国产亚洲欧洲高清一区| 综合激情国产一区| 91av在线视频观看| 裸体女人亚洲精品一区| 亚洲视频在线观看网站| 成人性生交大片免费观看嘿嘿视频| 成人免费激情视频| 成人信息集中地欧美| 欧美性视频精品| 亚洲国产精品久久久久| 国产精品夜色7777狼人| 疯狂蹂躏欧美一区二区精品| 国产精品入口夜色视频大尺度| 久久视频免费观看| 日韩一区二区三区xxxx| 日韩中文第一页| 成人h视频在线观看播放| 亚洲人成网站777色婷婷| 自拍偷拍亚洲精品| 91丝袜美腿美女视频网站| 久久久女女女女999久久| 欧美激情精品久久久久久变态| 欧美日韩国产成人在线| 日韩精品在线观| 日韩免费中文字幕| 在线不卡国产精品| 久久韩国免费视频| 亚洲综合自拍一区| 91九色视频在线| 91在线视频精品| xxxxx成人.com| 国产精品美女视频网站| 日本久久久久久久久久久| 日韩欧美国产免费播放| 韩国19禁主播vip福利视频| 日韩黄色av网站| 亚洲国产又黄又爽女人高潮的| 亚洲第一天堂无码专区| 日韩av男人的天堂| 国产精品第七影院| 久久久免费av| 亚洲视频网站在线观看| 欧美激情视频网址| 国产精品久久国产精品99gif| 国产丝袜一区视频在线观看| 亚洲影视中文字幕| 伊人久久免费视频| 日韩成人av在线| 亚洲韩国欧洲国产日产av| 视频在线一区二区| 成人久久精品视频| 中文字幕日韩精品有码视频| 亚洲成色999久久网站| 日韩电影中文字幕在线观看| 成人免费视频a| 亚洲欧美制服第一页| 久久久亚洲国产|