MTK平台用Socket实现

来源:互联网 发布:淘宝店现在卖什么好卖 编辑:程序博客网 时间:2024/05/01 05:10

MTK平台用Socket实现

默认分类2011-05-17 15:57:34 阅读7评论0   字号: 订阅

pobu26MTK平台用Socket实现HTTP请求总结【转载】

公司做了一个小型的wap浏览器的项目,其中涉及到用socket的实现http请求的方法,由于网上相关资料比较少,尤其是详细的资料比较少,所以走了不少弯路。在此仅从实现的角度说明MTK平台用Socket实现HTTP的方法,希望能给后来者一些微小的帮助。

 

一、MTK平台Socket联网过程

熟悉PC机编程的人都知道,Socket编程接口分两套:TCP和UDP;TCP和UDP中又有服务器端和客户端的概念,这里讲的是TCP的客户端编程接口。

MTK平台中Socket创建步骤:

         1、soc_create()  创建Socket;

         2、soc_setsockopt  设置Socket为非阻塞模式;

         3、soc_setsockopt  设置Socket选项为连接,读,写,关闭;不清楚为什么要连续设置两次,如有高人路过,请指点;

        4、如果是CMNET联网并且请求中用到了英文域名还需要解析域名soc_gethostbyname,除非使用ip作为域名,解析出来的IP作为我们建立连接的目标IP;如果是CMWAP联网,直接跳到第5步,直接连接移动或联通的网关:10.0.0.172:80;

        5、soc_connect与服务器建立连接;

        6、soc_send    发送请求;

        7、soc_recv     接收服务器返回的数据;

        8、soc_close    关闭Socket;

        9、如果需要关闭数据账户soc_close_nwk_account

二、CMNET,CMWAP方式下的HTTP请求内容格式

HTTP请求格式:

GET方法

MTK模拟器中wap浏览器发送的请求内容

“GET /go_13596557 HTTP/1.1

Host: kong.net

User-Agent: SQH_D480B_01/LB19504/WAP2.0 Profile

Accept:  application/vnd.wap.wmlc, */*  //(想当长,省去后面部分)

Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, GB2312, windows-1252, us-ascii

Accept-Language: zh-tw, zh-cn, en

Cookie: JSESSIONID=aAQP0FIXp3z7

Connection: Keep-Alive

 

当然模拟器上用的是CMNET,如果是CMWAP,则需要这样:

 “GET /go_13596557 HTTP/1.1

Host:10.0.0.172

X-Online-Host: kong.net

User-Agent: SQH_D480B_01/LB19504/WAP2.0 Profile

Accept:  application/vnd.wap.wmlc, */*  //(想当长,省去后面部分)

Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, GB2312, windows-1252, us-ascii

Accept-Language: zh-tw, zh-cn, en

Cookie: JSESSIONID=aAQP0FIXp3z7

Connection: Keep-Alive

 

 

POST方法

对一些需要向服务器传入参数的请求,按名称搜索等请求。还以空中网天气查询为例,之中的其他城市天气查询,输入其他城市名称或电话区号查询:

 

“POST /weather/search.jsp?setcity=1 HTTP/1.1

Host: kong.net

User-Agent: SQH_D480B_01/LB19504/WAP2.0 Profile

Accept: application/vnd.wap.wmlc, */*  //(想当长,省去后面部分)

Accept-Charset: utf-8, utf-16, iso-8859-1, iso-10646-ucs-2, GB2312, windows-1252, us-ascii

Accept-Language: zh-tw, zh-cn, en

Content-Type: application/x-www-form-urlencoded; charset=utf-8

Cookie: KONG_ACCESS=AWYZhg==; JSESSIONID=a91MDc6qoMYf

Connection: Keep-Alive

Content-Length: 46//get方法没有这一项

 

××××××//传给服务器46字节长的数据(参数)

当然如果是CMWAP联网方式也要和上述的GET方法一样设置Host和X-Online-Host项,Host:10.0.0.172

X-Online-Host: kong.net

以上的内容,可以在调试状态下运行模拟器的wap浏览器,在soc_send方法处插入断点观察。

 

HTTP的其他方法,由于在应用中没有用到,在这里不做介绍。

三、CMNET,CMWAP连接差别

1、GPRS账户:

与pc机上的socket客户端接口不同,手机客户端在soc_create,soc_gethostbyname接口中都多了参数nwt_acount_id,只的是一般在“网络服务”->“数据账户”->“GPRS”下的GPRS数据账户id,一般起始的一个账户id是10,往下递增1,在建立连接过程中,如果是CMWAP方式联网,soc_create,soc_gethostbyname接口就要设置接入点为CMWAP的账户id,CMNET就要设置接入点为CMNET的账户。

 

2、目标服务器:

还以空中网的天气服务为例,CMNET情况下,soc_connect需要连接”221.179.172.2”这个ip,如果请求的url为”http://kong.net/weather/home.jsp”  ,还需要调用soc_gethostbyname接口去解析域名;

如果是CMWAP方式联网,soc_connect只需要连接移动或联动的网关”10.0.0.172:80”。

 

3、HTTP请求内容格式(或称报文):

如第二节所述。

四、SIM1还是SIM2联网

      SIM1还是SIM2联网,MTK平台是通过创建socket时传入的nwt_acount_id区分的,如果是SIM1上网,账号就是指的是一般在“网络服务”->“数据账户”->“GPRS”下的对应的GPRS数据账户id;如果是SIM2,通过在四字节的账户id其他字节设置掩码来区分。

设置接口比如07B平台的always_ask_encode_data_account_id,6235_08A的cbm_encode_data_account_id接口。不同平台可能略有差别。

五、联通卡还是移动卡?

参考其他Socket联网代码中有的以接入点是否为”uniwap”来判断是不是联通的代理上网,但是通过实验,即使在联通卡时连接移动的”cmwap”账户,也是可以正常联网的。不知道设计“GPRS数据账户”的最初意图是什么?通过apn来区分同一内部ip地址网关不同的公网ip吗?如有高人路过,请指点;

 

六、HTTP1.1与Transfer-Encoding 为chunked的编码方式

      发送一个请求后,如果服务器返回的消息头内容包括“Transfer-Encoding: chunked”那么他的传输编码为“chunked”类型。这种传输类型的数据体内容格式是这样:

 

[16进制数字字符串 1到4个字节 len]/r/n

[len 长的数据体]/r/n

[16进制数字字符串 1到4个字节 len]/r/n

[len 长的数据体]/r/n

[16进制数字字符串 1到4个字节 len == 0]/r/n/r/n

 

其中,长度len是16进制的数字,表示本段数据体的长度(字节数),回车换行后,就是这一段数据真实内容,这就是一段数据体的格式,一段接一段;直到数据体长度为0的数据段出现,紧接着两个回车换行,标识本次请求的数据均已接收完毕。不过socket可以根据soc_recv返回值等于0来判断接收数据结束。如果收到的是这个编码类型的内容,需要对接收到的数据进行处理。

 

七、MTK平台的S8类型的误导

     MTK平台定义的两个数据类型U8和S8,一看名称我们可能会以为是unsigned char和signed char,但事实并非如此,

typedef char         S8;

typedef unsigned char  U8;

    MTK平台的char默认也是unsigned char类型的,soc_gethostbyname返回值类型是kal_int8(typedef signed char  kal_int8;),如果S8或平台的char类型是有符号的字符型,那么,kal_int8和S8应该是等价的,但用S8类型变量作为soc_gethostbyname的返回值时,经常返回254导致域名不会被正常解析,其实应该返回SOC_WOULDBLOCK(-2),应该是阻塞码,将soc_gethostbyname返回值类型改为kal_int8后,就能正常处理域名解析了。这证明平台的S8类型及char类型默认是无符号的。

八、不理解的链接错误?

       在添加连接超时功能时用到了gui_start_timer和gui_cancel_timer时,没有加入#include "gui.h"时,出现以下链接错误:

Error: L6286E: Value(0x818153e) out of range(-0x400000 - 0x3fffff) for relocation #13 (wrt symbol gui_cancel_timer) in Socket.obj(i. SocDinit)

加上#include "gui.h"时,就没有这个问题,如果程序找不到这个符号,应该是个编译错误,在此为什么是个链接错误。

 

查了一下arm的帮助文档:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka3553.html

依然不明白,如果高手路过,请深入指教一下原因。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/guojin08/archive/2009/07/02/4315138.aspx

原创粉丝点击