MTK平臺用Socket實現HTTP請求總結

轉自新浪博客:http://blog.sina.com.cn/s/blog_4cd5d2bb0100fe7y.html
html

公司作了一個小型的wap瀏覽器的項目,其中涉及到用socket的實現http請求的方法,因爲網上相關資料比較少,尤爲是詳細的資料比較少,因此走了很多彎路。在此僅從實現的角度說明MTK平臺用Socket實現HTTP的方法,但願能給後來者一些微小的幫助。編程

 

1、MTK平臺Socket聯網過程
熟悉PC機編程的人都知道,Socket編程接口分兩套:TCP和UDP;TCP和UDP中又有服務器端和客戶端的概念,這裏講的是TCP的客戶端編程接口。windows

MTK平臺中Socket建立步驟:瀏覽器

         一、soc_create()  建立Socket;服務器

         二、soc_setsockopt  設置Socket爲非阻塞模式;網絡

         三、soc_setsockopt  設置Socket選項爲鏈接,讀,寫,關閉;不清楚爲何要連續設置兩次,若有高人路過,請指點;app

        四、若是是CMNET聯網而且請求中用到了英文域名還須要解析域名soc_gethostbyname,除非使用ip做爲域名,解析出來的IP做爲咱們創建鏈接的目標IP;若是是CMWAP聯網,直接跳到第5步,直接鏈接移動或聯通的網關:10.0.0.172:80;socket

        五、soc_connect與服務器創建鏈接;jsp

        六、soc_send    發送請求;ui

        七、soc_recv     接收服務器返回的數據;

        八、soc_close    關閉Socket;

        九、若是須要關閉數據帳戶soc_close_nwk_account

2、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

 

 

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的其餘方法,因爲在應用中沒有用到,在這裏不作介紹。

3、CMNET,CMWAP鏈接差異
一、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的帳戶。

 

二、目標服務器:

還以空中網的天氣服務爲例,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」。

 

三、HTTP請求內容格式(或稱報文):

如第二節所述。

4、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接口。不一樣平臺可能略有差異。

5、聯通卡仍是移動卡?
參考其餘Socket聯網代碼中有的以接入點是否爲」uniwap」來判斷是否是聯通的代理上網,可是經過實驗,即便在聯通卡時鏈接移動的」cmwap」 帳戶,也是能夠正常聯網的。不知道設計「GPRS數據帳戶」的最初意圖是什麼?經過apn來區分同一內部ip地址網關不一樣的公網ip嗎?若有高人路過,請 指點;

 

6、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來判斷接收數據 結束。若是收到的是這個編碼類型的內容,須要對接收到的數據進行處理。

 

7、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類型默認是無符號 的。

8、不理解的連接錯誤?
       在添加鏈接超時功能時用到了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

依然不明白,若是高手路過,請深刻指教一下緣由。

相關文章
相關標籤/搜索