因为需要实现自己的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. [转载] 单表60亿记录等大数据场景的MySQL优化和运维之道 | 高可用架构

    原文: http://mp.weixin.qq.com/s?__biz=MzAwMDU1MTE1OQ==&mid=209406532&idx=1&sn=2e9b0cc02bdd ...

  2. Xpert 基础

    ----------------------- 01 ------------------------------- declare cursor emp_cur is select empname ...

  3. hdu4717The Moving Points(三分)

    链接 需要特判一下n=1的时候 精度调太低会超时 #include <iostream> #include<cstdio> #include<cstring> #i ...

  4. Monkey学习(3)如何在Android模拟器中安装apk

    1.运行SDK Manager,选择模拟器,并运行模拟器,我这里用的是已经配置好的模拟器“RedMI” 2.已启动好的模拟器“RedMI” 3.记住需要安装apk文件的位置,我这里放在了F盘的根目录下 ...

  5. linux gksu用法

    apt-get install gksu gksu是linux下图形化的su/sudo工具 sudo 用来执行命令行(CLI)程序 gksu 用来执行图形的(GUI)程序 GUI = Graphica ...

  6. (二)程序中的内存&&栈

    一.程序运行为什么需要内存?基本概念? 内存是程序运行的立足之地,程序需要用内存来存储一些变量. 内存管理最终是由操作系统完成的,内存在本质上是一个硬件器件,由硬件系统提供:内存由操作系统统一管理,为 ...

  7. 这个算asp.net的一个bug吗?

    asp.net设置按钮Enabled="false"后OnClientClick中添加的验证脚本消失了 下面的确可以 <asp:Button ID="btnRegi ...

  8. php ajax json jquery 记录

    php+jquery+ajax+json简单小例子 <html> <title>php+jquery+ajax+json简单小例子</title> <?php ...

  9. sass less

    CSS 预处理器技术已经非常的成熟,而且也涌现出了越来越多的 CSS 的预处理器框架.本文向你介绍使用最为普遍的三款 CSS 预处理器框架,分别是 Sass.Less CSS.Stylus. 首先我们 ...

  10. Beautiful Soup教程 转

    Python中使用Beautiful Soup库的超详细教程 转 http://www.jb51.net/article/65287.htm 作者:崔庆才 字体:[增加 减小] 类型:转载 时间:20 ...