因为需要实现自己的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. [转载] linux 速查表

    原文: http://www.nixtutor.com/linux/all-the-best-linux-cheat-sheets/ 1. Linux Command Line Linux Refer ...

  2. Codeforces708C Centroids 【树形dp】

    题目链接 题意:给定一棵n个结点的树,问:对于每个结点,能否通过删除一条边并添加一条边使得仍是树,并且删除该结点后得到的各个连通分量结点数 <= n/2? 题解:树形dp,两遍dfs,第一遍df ...

  3. 使用phpmaill发送邮件的例子

    首先,要下载php_mail软件包 核心代码: index.php <?php include "mail.php"; if (!empty($_POST['to']) &a ...

  4. C++——友元、异常和其他

    一.友元 类并非只能拥有友元函数,也可以将类作为友元.在这种情况下,友元类的所有方法都可以访问原始类的私有成员和保护成员.另外,也可以做更严格的限制,只将特定的成员函数指定为另一个类的友元.哪些函数. ...

  5. 反演dp经典

    咋一看,至少要用3^n才能做到. 但. 首先定义: 可以发现只要求出a' b' 那么直接可以得出c' 那么如何求a'呢 //dp求a',其实就是分别用[0,n)来更新a' ; i < n; i+ ...

  6. Java Performance - 优化和分析Garbage Collection/垃圾收集

    随着硬件的不断提升,Java Heap 越来越大,合理的垃圾收集调优变得愈发重要.下面介绍一些最佳实践: 注意: 下面不涉及 IBM AIX Java. 同时不介绍原理,仅仅是建议以及初始配置/最佳实 ...

  7. phalcon: (非官方)简单的多模块

    phalcon: [非官方]多模块 配合router使用 例如:我的模块叫做: home 入口文件增加引入: use Phalcon\Mvc\Router; 在自动引入前面增加,自动引入命名空间: / ...

  8. SQL Server Native Client 安装方法

    在 server 2008 r2 里面搜索到:  sqlncli.msi  安装即可

  9. PhoneGap插件开发流程

    前几天写了一个PhoneGap插件,这个插件的功能很简单,就是开启viewport设置.不过与其它插件相比,有好几个有意思的地方,仔细读了PhoneGap的源码才搞定.这里记录一下PhoneGap插件 ...

  10. 8.3 ContosoMVCWeb官方案例学习

    1. 分页案例学习 2. 排序搜索案例学习 3.使用Configuration.cs中的Seed方法 在数据库迁移过程中,使用update-database,会运行seed方法.seed方法能够将初始 ...