因为需要实现自己的http客户端,就要自己模拟http 的socket通讯;

上行不难,自己处理好http即可。

但下行时,服务器端的动态语言返回数据有可能会是这种格式:

http头

16进制表示的数据长度1

数据1

16进制表示的数据长度2

数据2

……16进制表示的数据长度n

数据n

0

是这种格式时,返回头信息里面会有:

Transfer-Encoding: chunked

这么一个头;数据里面表示每次发送的数据长度的16进制字符并不是html的一部分,需要去掉,如果数据直接使用utf8编码,那么就会出问题:

如果 数据1 里面有中文,则“16进制表示的数据长度1”要比 数据1.length大,因为“16进制表示的数据长度1”是取的2进制长度,但“数据1.length”是以utf8编码来算的

所以不能默认使用utf8编码,得这样:

-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
NSString *newMessage = [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding]; NSLog(@"\r\n=================HTTP RESPONSE START=================\r\nData get length: %lu,\r\n%@\r\n=================HTTP RESPONSE END=================\r\n ", (unsigned long)data.length, newMessage);
[sock readDataWithTimeout:-1 tag:0];
if(httpStatus<3 && [newMessage rangeOfString:@"Transfer-Encoding: chunked"].length>0){
isChunked = YES;
httpStatus = 3 ;
} dataGot = [dataGot stringByAppendingString:newMessage]; httpStatus = 3;
}

最后处理去处长度字符,然后转换为utf8编码:

- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
NSLog(@"Disconnected %@", err);
if(httpStatus<3)
[delegate httpDataGot:@"" rs:NO];
else{
if(isChunked){
NSRange range = [dataGot rangeOfString:@"\r\n\r\n"];
int len = range.length+range.location;
dataGot =[dataGot substringFromIndex:len]; NSString* rs = @"";
NSString* lenStr; //NSLog(@"data len=%d---\n%@\n", dataGot.length,dataGot); while(YES){
range = [dataGot rangeOfString:@"\r\n"];
if(range.length==0)
break;
lenStr = [dataGot substringToIndex:range.location];
firstChunkedLen = strtoul([lenStr UTF8String], 0, 16);
if(firstChunkedLen==0)
break;
dataGot = [dataGot substringFromIndex:range.location+range.length];
rs = [rs stringByAppendingString:[dataGot substringToIndex:firstChunkedLen]];
dataGot = [dataGot substringFromIndex:firstChunkedLen];
}
/*
NSString *s1 = [NSString stringWithCString:[rs cStringUsingEncoding:NSISOLatin1StringEncoding] encoding:NSUTF8StringEncoding];
*/ [delegate httpDataGot:[NSString stringWithCString:[rs cStringUsingEncoding:NSISOLatin1StringEncoding] encoding:NSUTF8StringEncoding] rs:YES];
}
else
[delegate httpDataGot:[NSString stringWithCString:[dataGot cStringUsingEncoding:NSISOLatin1StringEncoding] encoding:NSUTF8StringEncoding] rs:YES]; }
isChunked = NO;
httpStatus = 0;
}

NSString asscii格式(2进制) 转 utf8格式——解决iOS自己处理http socket数据,遇到Transfer-Encoding: chunked时的更多相关文章

  1. 16进制与utf-8

    很多人将数据的存储.传输方式和展现形式混为一谈. 类似的16进制 2进制是讲内容在电脑里面的存储或者传输的一种格式, 而utf-8 gb2312 等是输出的展现的一种格式 不是一回事,另外 gbk包含 ...

  2. js AES对称加密 16进制和base64格式

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  3. double四舍五入,商品金额大小写转换,设置货币的小数位数跟格式输出,进制转化

      1:计算double值四舍五入的方法 对小数数值进行四舍五入,首先应该确认保留小数位, 如果数值的小数精度大于保留小数位,那么开始四舍五入计算.四舍五入的方法非常简单,在所有要丢失精度的小数位中加 ...

  4. 颜色16进制转为RGB格式

    <script> 2 function getRGB(str){ var arr = str.split(""); var myred = arr[1]+arr[2]; ...

  5. MFC 中CString 格式16进制转int 十进制

    代码:CString  v_hex ; int v_dec; v_dec = wcstol(v_hex, NULL, 16);

  6. 文件重定向,getline()获取一样,屏幕输出流,格式控制符dec,oct,hex,精度控制setprecision(int num),设置填充,cout.width和file(字符),进制输入

     1.在window下的命令重定向输出到文件里 2.将内容输入到某个文件里的方式:命令<1.txt (使用1.txt中的命令) 3.读取文件里的名,然后将命令读取最后输出到文件里.命令< ...

  7. SQL Server进制

    在项目中,大家可能都遇到过,需要把十进制转换为其他进制的情况,google上一搜,已经有很多2进制.8进制.16进制和十进制的转换方法.但是在一些项目中,这些可能无法满足要求,可能需要17.18甚至是 ...

  8. noip 1998 洛谷P1013 进制位

    题目描述 著名科学家卢斯为了检查学生对进位制的理解,他给出了如下的一张加法表,表中的字母代表数字. 例如: L K V E L L K V E K K V E KL V V E KL KK E E K ...

  9. C# byte[] 转换16进制字符串

    1.byte[] 转换16进制字符串 1.1 BitConverter方式 var str = DateTime.Now.ToString(); var encode = Encoding.UTF8; ...

随机推荐

  1. springmvc企业级开发实战

    一.用eclipse插件搭建项目 二.pom文件 1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi ...

  2. chrome离线安装包_下载

    ZC: 如何下载的文章 参考:“https://www.tekrevue.com/tip/download-chrome-offline-installer/” 1. f/q 2.下载网址: 2.1. ...

  3. amd64_or_ia64?

    amd64 网上资料: 1. IA64是intel推出的架构,AMD64是AMD推出的.IA64不兼容原有的32位x86架构指令集,后来被证明这种做法是不成功的,于是Intel发展处IA64e架构,对 ...

  4. 06 SQL执行计划

    解释计划 与 执行计划的 区别 随着可以得到解释计划输出的开发工具, 比如 toad 的普遍使用, 生成解释计划就变的相当简单. 而不简单的是得到执行计划. 解释计划 EXPLAIN PLAN 用来显 ...

  5. JQuery $()后面的括号里的内容什么时候加引号,什么时候不加

    一.如果是已经声明存在的变量或者对象,就不用加引号. 比如var name=document.getElementById("name"); $(name)或者$(this). 二 ...

  6. Android 热修复Nuwa的原理及Gradle插件源码解析

    现在,热修复的具体实现方案开源的也有很多,原理也大同小异,本篇文章以Nuwa为例,深入剖析.  Nuwa的github地址 https://github.com/jasonross/Nuwa 以及用于 ...

  7. UML中类之间的几种关系

    类之间可能存在以下几种关系:关联(association).依赖(dependency).聚合(Aggregation,也有的称聚集).组合(Composition).泛化(generalizatio ...

  8. python int与str转换

    string -> int 1. 10进制string 转换为 int  int("12") 2. 16进制string 转换为 int  int("12" ...

  9. 任务栏右键工具栏里的语言栏没有的修复.reg

    任务栏右键工具栏里的语言栏没有的修复.reg Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\CLSID\{540D8A8B-1C3F- ...

  10. windows+tomcat 7配置二级域名访问其他web程序

    1.在域名管理中做好二级域名的解析 2.在tomcat的server.xml中增加如下: <Host name="wx.ai77.cn" debug="0" ...