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

2021-04-30 08:22:10 字數 4640 閱讀 1516

公司做了乙個小型的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瀏覽器傳送的請求內容

「 當然模擬器上用的是cmnet,如果是cmwap,則需要這樣:

「 post方法

對一些需要向伺服器傳入引數的請求,按名稱搜尋等請求。還以空中網天氣查詢為例,之中的其他城市天氣查詢,輸入其他城市名稱或**區號查詢:

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

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

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

公司做了乙個小型的wap瀏覽器的專案,其中涉及到用socket的實現http請求的方法,由於網上相關資料比較少,尤其是詳細的資料比較少,所以走了不少彎路。在此僅從實現的角度說明mtk平台用socket實現http的方法,希望能給後來者一些微小的幫助。一 mtk平台socket聯網過程 熟悉pc機程式...

MTK平台用Socket實現HTTP請求

一 mtk平台socket聯網過程 熟悉pc機程式設計的人都知道,socket程式設計介面分兩套 tcp和udp tcp和udp中又有伺服器端和客戶端的概念,這裡講的是tcp的客戶端程式設計介面。mtk平台中socket建立步驟 1 soc create 建立socket 2 soc setsock...

用Socket實現TCP,UDP通訊

udp適用於一次只傳送少量資料 對可靠性要求不高的應用環境。public class udpserver catch socketexception e catch unknownhostexception e catch ioexception e public class udpclient c...