NSString asscii格式(2进制) 转 utf8格式——解决iOS自己处理http socket数据,遇到Transfer-Encoding: chunked时
因为需要实现自己的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时的更多相关文章
- 16进制与utf-8
很多人将数据的存储.传输方式和展现形式混为一谈. 类似的16进制 2进制是讲内容在电脑里面的存储或者传输的一种格式, 而utf-8 gb2312 等是输出的展现的一种格式 不是一回事,另外 gbk包含 ...
- js AES对称加密 16进制和base64格式
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- double四舍五入,商品金额大小写转换,设置货币的小数位数跟格式输出,进制转化
1:计算double值四舍五入的方法 对小数数值进行四舍五入,首先应该确认保留小数位, 如果数值的小数精度大于保留小数位,那么开始四舍五入计算.四舍五入的方法非常简单,在所有要丢失精度的小数位中加 ...
- 颜色16进制转为RGB格式
<script> 2 function getRGB(str){ var arr = str.split(""); var myred = arr[1]+arr[2]; ...
- MFC 中CString 格式16进制转int 十进制
代码:CString v_hex ; int v_dec; v_dec = wcstol(v_hex, NULL, 16);
- 文件重定向,getline()获取一样,屏幕输出流,格式控制符dec,oct,hex,精度控制setprecision(int num),设置填充,cout.width和file(字符),进制输入
1.在window下的命令重定向输出到文件里 2.将内容输入到某个文件里的方式:命令<1.txt (使用1.txt中的命令) 3.读取文件里的名,然后将命令读取最后输出到文件里.命令< ...
- SQL Server进制
在项目中,大家可能都遇到过,需要把十进制转换为其他进制的情况,google上一搜,已经有很多2进制.8进制.16进制和十进制的转换方法.但是在一些项目中,这些可能无法满足要求,可能需要17.18甚至是 ...
- 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 ...
- C# byte[] 转换16进制字符串
1.byte[] 转换16进制字符串 1.1 BitConverter方式 var str = DateTime.Now.ToString(); var encode = Encoding.UTF8; ...
随机推荐
- [转载] 单表60亿记录等大数据场景的MySQL优化和运维之道 | 高可用架构
原文: http://mp.weixin.qq.com/s?__biz=MzAwMDU1MTE1OQ==&mid=209406532&idx=1&sn=2e9b0cc02bdd ...
- Xpert 基础
----------------------- 01 ------------------------------- declare cursor emp_cur is select empname ...
- hdu4717The Moving Points(三分)
链接 需要特判一下n=1的时候 精度调太低会超时 #include <iostream> #include<cstdio> #include<cstring> #i ...
- Monkey学习(3)如何在Android模拟器中安装apk
1.运行SDK Manager,选择模拟器,并运行模拟器,我这里用的是已经配置好的模拟器“RedMI” 2.已启动好的模拟器“RedMI” 3.记住需要安装apk文件的位置,我这里放在了F盘的根目录下 ...
- linux gksu用法
apt-get install gksu gksu是linux下图形化的su/sudo工具 sudo 用来执行命令行(CLI)程序 gksu 用来执行图形的(GUI)程序 GUI = Graphica ...
- (二)程序中的内存&&栈
一.程序运行为什么需要内存?基本概念? 内存是程序运行的立足之地,程序需要用内存来存储一些变量. 内存管理最终是由操作系统完成的,内存在本质上是一个硬件器件,由硬件系统提供:内存由操作系统统一管理,为 ...
- 这个算asp.net的一个bug吗?
asp.net设置按钮Enabled="false"后OnClientClick中添加的验证脚本消失了 下面的确可以 <asp:Button ID="btnRegi ...
- php ajax json jquery 记录
php+jquery+ajax+json简单小例子 <html> <title>php+jquery+ajax+json简单小例子</title> <?php ...
- sass less
CSS 预处理器技术已经非常的成熟,而且也涌现出了越来越多的 CSS 的预处理器框架.本文向你介绍使用最为普遍的三款 CSS 预处理器框架,分别是 Sass.Less CSS.Stylus. 首先我们 ...
- Beautiful Soup教程 转
Python中使用Beautiful Soup库的超详细教程 转 http://www.jb51.net/article/65287.htm 作者:崔庆才 字体:[增加 减小] 类型:转载 时间:20 ...