Socket调用HTTP接口

1.首先你需要用CocoaPods导入这个库:

pod'CocoaAsyncSocket'

2.而后我们新建一个DCSocketManager类来管理这个类的一些代理方法,并生成一个本类的单例:

@interfaceDCSocketManager() {

NSString*_serverHost;//IP或者域名

int_serverPort;//端口,https一般是443

GCDAsyncSocket *_asyncSocket;//一个全局的对象

}

@property(nonatomic,strong)NSMutableData*sendData;//最终拼接好的需要发送出去的数据

@property(nonatomic,copy)NSString*uriString;//具体请求哪个接口,比如https://xxx.xxxxx.com/verificationCode里的verificationCode

@property(nonatomic,strong)NSDictionary*paramters;//Body里面需要传递的参数

@property(nonatomic,copy) CompletionHandler completeHandler;//收到返回数据后的回调Block

@property(nonatomic,strong)NSMutableArray*dcNetArr;//网络请求参数的暂存数组,后面会用到

@end


3.用socket连接http接口的域名与端口:

[_asyncSocket connectToHost:_serverHost onPort:_serverPort error:nil];

4.组装要发送的报文NSData:

- (NSMutableData*)sendData {

NSMutableData*packetData = [[NSMutableDataalloc] init];

NSData*crlfData = [@"\r\n"dataUsingEncoding:NSUTF8StringEncoding];//回车换行是http协议中每个字段的分隔符

[packetData appendData:[[NSStringstringWithFormat:@"GET /%@ HTTP/1.1",self.uriString] dataUsingEncoding:NSUTF8StringEncoding]];//拼接的请求行

[packetData appendData:crlfData];//每个字段后面都要跟一个回车换行

[packetData appendData:[@"DCVer: 1"dataUsingEncoding:NSUTF8StringEncoding]];//拼接的请求头字段,这个键值对和服务器协商内容,一般不止一个

[packetData appendData:crlfData];

 [packetData appendData:[@"DCAid: test"dataUsingEncoding:NSUTF8StringEncoding]];//拼接的请求头字段,这个键值对和服务器协商内容,一般不止一个

[packetData appendData:crlfData]; 

 [packetData appendData:[@"Content-Type: application/json; charset=utf-8"dataUsingEncoding:NSUTF8StringEncoding]];//发送数据的格式

[packetData appendData:crlfData];

 [packetData appendData:[@"User-Agent: GCDAsyncSocket8.0"dataUsingEncoding:NSUTF8StringEncoding]];//代理类型,用来识别用户的操作系统及版本等信息,这里我随便填的,一般情况没什么用

[packetData appendData:crlfData]; 

 [packetData appendData:[@"Host: xxx.xxxxxx.com"dataUsingEncoding:NSUTF8StringEncoding]];//IP或者域名

[packetData appendData:crlfData];

NSError*error;

NSData*bodyData = [NSJSONSerializationdataWithJSONObject:self.paramters options:0error:&error];

NSString*bodyString = [[NSStringalloc] initWithData:bodyData encoding:NSUTF8StringEncoding];//生成请求体的内容

[packetData appendData:[[NSStringstringWithFormat:@"Content-Length: %ld", bodyString.length] dataUsingEncoding:NSUTF8StringEncoding]];//说明请求体内容的长度

[packetData appendData:crlfData];

 [packetData appendData:[@"Connection:close"dataUsingEncoding:NSUTF8StringEncoding]];

 [packetData appendData:crlfData]; 

 [packetData appendData:crlfData];//注意这里请求头拼接完成要加两个回车换行//以上http头信息就拼接完成,下面继续拼接上body信息

NSString*encodeBodyStr = [NSStringstringWithFormat:@"%@\r\n\r\n", bodyString];//请求体最后也要加上两个回车换行说明数据已经发送完毕

[packetData appendData:[encodeBodyStr dataUsingEncoding:NSUTF8StringEncoding]];

returnpacketData;

}

5.若想支持https接口,则需要加下面一个方法:

- (void)doTLSConnect:(GCDAsyncSocket *)sock {//HTTPS

NSMutableDictionary*sslSettings = [[NSMutableDictionaryalloc] init];

NSData*pkcs12data = [[NSDataalloc] initWithContentsOfFile:[[NSBundlemainBundle] pathForResource:@"xxx.xxxxxxx.com"ofType:@"p12"]];//已经支持https的网站会有CA证书,给服务器要一个导出的p12格式证书

CFDataRefinPKCS12Data = (CFDataRef)CFBridgingRetain(pkcs12data);

CFStringRefpassword =CFSTR("xxxxxx");//这里填写上面p12文件的密码

constvoid*keys[] = { kSecImportExportPassphrase };

constvoid*values[] = { password };

CFDictionaryRefoptions =CFDictionaryCreate(NULL, keys, values,1,NULL,NULL);

CFArrayRefitems =CFArrayCreate(NULL,0,0,NULL);

 OSStatus securityError = SecPKCS12Import(inPKCS12Data, options, &items);

CFRelease(options);

CFRelease(password);

if(securityError == errSecSuccess) {

NSLog(@"Success opening p12 certificate.");

 }

CFDictionaryRefidentityDict =CFArrayGetValueAtIndex(items,0); 

 SecIdentityRef myIdent = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity); 

 SecIdentityRef certArray[1] = { myIdent };

CFArrayRefmyCerts =CFArrayCreate(NULL, (void*)certArray,1,NULL); 

 [sslSettings setObject:(id)CFBridgingRelease(myCerts) forKey:(NSString*)kCFStreamSSLCertificates]; 

 [sslSettings setObject:@"api.pandaworker.com"forKey:(NSString*)kCFStreamSSLPeerName]; [sock startTLS:sslSettings];//最后调用一下GCDAsyncSocket这个方法进行ssl设置就Ok了

}

6.至此用socket调用http接口的方法已经写完了,那么我们调用之后怎么获取返回数据呢,请往下看:

- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData*)data withTag:(long)tag

{//读取到返回数据时会调用

NSLog(@"didReadData length: %lu, tag: %ld", (unsignedlong)data.length, tag);

if(nil!=self.completeHandler) {

//如果请求成功,读取到服务器返回的data数据一般是一串字符串,需要根据返回数据格式做相应处理解析出来

NSString*string = [[NSStringalloc] initWithData:data encoding:NSUTF8StringEncoding];//

NSLog(@"%@", string);

NSRangestart = [string rangeOfString:@"{"];

NSRangeend = [string rangeOfString:@"}\r\n"];

NSString*sub;

if(end.location !=NSNotFound&& start.location !=NSNotFound) {

//如果返回的数据中不包含以上符号,会崩溃

sub = [string substringWithRange:NSMakeRange(start.location, end.location-start.location+1)];//这就是服务器返回的body体里的数据

NSData*subData = [sub dataUsingEncoding:NSUTF8StringEncoding];

NSDictionary*subDic = [NSJSONSerializationJSONObjectWithData:subData options:0error:nil];

self.completeHandler(subDic);

 } 

 }

 [sock readDataWithTimeout:-1tag:0];

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345