//Logo Image
作者:吳昌暉(2004-11-02);推薦:徐業良(2004-11-05)。

如何用pic_SERVERHTTP伺服器傳送大量數據

HTTP伺服器是基於TCP/IP協議的應用軟體,pic_SERVERTCP伺服器是精簡版的TCP伺服器,HTTP伺服器則是精簡加強版的,二者均與標準的HTTPTCP有所差異,pic_SERVERTCPclient模式則是標準的。pic_SERVERHTTP serverTCP server、以及TCP client均可與Winsock軟體正常通訊。以下首先介紹標準的TCP通訊流程,再說明pic_SERVERTCP server模式與標準TCP server的差異,最後介紹用HTTP協議傳輸大量數據以及認證加密的方式。在不擴充外部程式記憶體的前提下,pic_SERVER最多可以有128kB的程式,足夠裝得下一個自行開發的POSPicmicro OS),一套包含TCP/IPFAT16以及小型DataBase等的BIOS

1.     TCP協議的通訊流程

TCP/IP通訊協議是一種clientserver(用戶-服務器)的通訊模式,先開口提出通訊請求的就是clientserver絕對不會先開口,server收到client訊息後一定要回答。簡化版的標準的通訊流程如下:

(1)      client說:有人在家嗎?(發SYN碼,提出通訊請求)

(2)      server答:我在家。(發SYN-ACK碼同意請求,ACK=Acknowledgement

(3)      client說:數據資訊給你。(發Data+ACK碼)

(4)      server答:收到,答覆給你。(發Data+ACK碼,沒有Data亦可)

(5)      client說:收到,答覆給你。(發Data+ACK碼,沒有Data亦可)

(6)      繼續聊天,直到二者之一提出結束通訊的要求並互相確認為止。

TCP的特點之一是在任何一個步驟中,發話人在預先設定的時限內(0.1~1.0秒)若沒有收到對方的回應,就會自動重發,一直嘗試到預先設定的時限(timeout)為止,這時限可由軟體設定,一般用3~60秒。

TCP的特點之二是當通訊建立後,在一次會談(session)之中可連續傳送數據,因此每一次所發送的數據實際上是總數據的一部份,是一個片段,故稱為segment,每一次所發送的封包(packet)不能超過乙太網路(EtherNet)協議的限制,TCP segmentIP header(標籤)不得超過1500byte

2.     pic_SERVERTCP伺服器

pic_SREVERTCP_server的服務流程如下:

(1)      client說:有人在家嗎?(發SYN碼,提出通訊請求)

(2)      server答:我在家。(發SYN-ACK碼同意請求,ACK=Acknowledgement

(3)      client說:數據資訊給你。(發Data+ACK碼)

(4)      server答:收到,答覆給你,再見!(發Data+FIN碼,沒有Data亦可)

(5)      client說:收到,再見啦。(發FIN+ACK碼,FIN=Finish

與標準的TCP server的差異在於,pic_SREVERTCP_server只做一次答覆就結束通訊!其目的在於簡化軟體,減輕CPU的負擔,減少記憶體的用量,也完全消除當機的可能性。在這種運作方式下,pic_SERVER無需記憶他跟特定客戶的通訊過程,無需記憶在一次會談中通訊到第幾個回合,故無需使用Finite State Machine處理許多客戶的通訊歷程,故稱為無狀態(stateless)的伺服器。一般的TCP伺服器可以同時和許多客戶通訊,server要能記住他和每一個客戶的通訊狀態在第幾個階段,pic_SERVER一次只處理一個客戶,講完話馬上把客戶打發回家,因此稱為單工的伺服器。

3.     pic_SERVERHTTP伺服器與雙向傳輸的方式

HTTP伺服器是基於TCP伺服器的應用軟體,因此pic_SERVERHTTP伺服器也是單工無狀態(single-client stateless)的伺服器,一次只服務一個客戶,在任何一瞬間pic_SERVER的手上最多只有一個客戶,但仍可以服務無限多的客戶(multi-user)pic_SERVERHTTP伺服器目前僅提供GET method的服務,也就是說只允許客戶向pic_SERVER提出抓檔案的請求,但是我們仍可以用HTTP協議雙向傳輸資訊!

HTTP clientHTTP server提出請求的幾種標準格式如下:

(1)   client說:GET/。(server就給他index.htm

(2)   client說:GET/any_file.htm。(server手上若有any_file.htm就給他,否則就給他index.htm

(3)   client說:GET/any_file.htm?pas=xxxx?cmd=yyyy。(第一個問號是檔名結束碼)

從上述第3種格式可知,除了檔名之外,client還可以順便夾帶高達1.4kB的資訊送交server,這就是client透過HTTPserver傳輸資訊的方式。

pic_SERVERHTTP伺服器向client傳輸資訊的方式如第2節所述,其限制是每個session只能傳給client一個封包的資訊,因此當HTTP clientpic_SERVER索取檔案時,每個檔案的大小加上HTTP header(標籤)不能超過1460byteHTML檔案過大時,就必須由程式員自行手工分割為幾個小檔案才行,或是轉介連結到大型伺服器去,讓client自己去大型伺服器抓靜態的(static)大檔案。在任務分工上,pic_SERVERHTTP伺服器應該只負責動態的(dynamic)檔案,如CGIEGI檔等關鍵性或牽涉安全性的重要檔案。大型的、靜態的、圖檔、固定的程式檔(JAVA等等),連結到大型主機就好,不要放在pic_SERVER

4.     如何用pic_SERVERHTTP伺服器傳輸大量數據以及認證加密的方式

這一節中將討論以下4個問題:

pic_SERVERHTTP_server如何將大量數據傳給client

HTTP_client如何將大量數據傳給pic_SERVER

pic_SERVERHTTP_server如何進行client的安全認證?

HTTP_client傳輸數據給pic_SERVER時如何加密?

(1)   pic_SERVERHTTP_server如何將大量數據傳給client

有兩種做法,第一種用網頁檔裡面的EGI檔,配合寫在pic_SERVER_egi.c裡面的callback函數,do_webpage_EGI_code_substitution(),依據EGI碼傳送數據。

這些數據若在程式中依狀況適時更新,就成為動態數據,EGI檔就成為動態檔案。EGI(Embedded Gateway Interface)檔的概念與CGI(Common Gateway Interface)完全相同,請參閱YZ_PIC_v_4.08d軟體裡面的“網頁檔名與動態數據規範.TXT”以及範例程式pic_server_step_1.c ~ step_3.c。負責應用軟體開發的程式員可自行修改EGI碼的傳輸規則,修改do_webpage_EGI_code_substitution()即可。範例如下:

if (egi_code=='1') for(i=0;i<block_1_data_length;i++)

printf(nic_putc," %u", block_1_data[i]);

改成

if (egi_code=='1') for( i=0; i<500;i++)

printf(nic_putc," %u", x_data[i]);

自己去宣告一個總體陣列變數 x_data 就好,沒有任何限制啦!

Socket函數void nic_putc(unsigned char c)pic_SERVER EtherNet TCP/IP BIOS的核心,直接將一個byte的數據寫入NICNetwork Interface Controller, 硬體採用RTL8019AS晶片)的緩衝區。printf(nic_putc,,)這種語法則是CCS公司的C編譯器的特異功能,相當於ANSI-C裡的fprintf()中重新導向的功能。

第二種做法不使用網頁檔裡面的EGI檔,直接在callback函數

void process_command_from_HTTP_client(void)    

void collect_data_for_HTTP_client(void)

裡面依據HTTP client 送來的資訊或指令,直接用nic_putc()printf(nic_putc,,)送出數據就完成啦。

第一種方法的優點是可以用HTML等網頁語言製作好看的介面。第二種方法的優點是,無需去管理維護一堆HTMLEGI網頁檔案,傳輸數據的規則全部寫在C-code 裡面,從軟體工程的角度看,或許會比較容易管理維護軟體。這兩種方法都可以用IE等瀏覽器直接抓數據,沒有限制。

如何突破pic_SERVERHTTP_server在一個session中最多只能傳送1460 byteclient的限制?有一個做法,就是在HTTP servercallback函數中插個旗標,回到主程式後依據旗標啟動TCP client task,就可以在一個pic_SERVERTCP client session中傳遞無限量的數據給遠端的TCP server啦!當然,這TCP serverHTTP client可能是同一台電腦,也可能是不同的電腦,總之,關鍵在於pic_SERVERTCP_client在一個session中可傳送的封包總數是無限的,程式員自行規劃即可。

(2)   HTTP_client 如何將大量數據傳給pic_SERVER

如第3節所述,每個session可夾帶1.4 kB數據,可用Socket函數

int1 nic_getc(int8 *c)                                   

int16 nic_gets(int8 *array, int16 size) 讀取。

(3)   pic_SERVERHTTP_server如何進行client的安全認證?

安全認證係採用client提出服務請求時送來的password作為依據。服務請求字串

GET /any_file.htm?pas=xxxx?cmd=yyyy

中第一個問號後面的第5~18字在韌體中的定義就是password

ClientIP無法做為安全認證的基礎,因為通過router/gateway轉信時,有些元智大學的router/gateway就會用它的IP取代clientIP。因此安全認證僅能依賴client送交pic_SERVER的服務請求中的數據內容做為依據。

(4)   HTTP_client傳輸數據給pic_SERVER時如何加密?

為避免上述client送交pic_SERVER的服務請求中的數據內容中的認證資訊(password)以及具安全性的重要指令在網路傳輸時遭駭客竊聽,可將此服務請求進行編碼,pic_SERVER的韌體內建Iron_code解碼機制,VB軟體Iron_key.DLL則負責將服務請求中的檔名結束碼之後的14字符password以及密碼後面的56字的指令予以亂數編碼,並將解碼所需的Iron_key加入服務請求字串中一併傳送給pic_SERVERpic_SERVER解碼後會將這56字放在總體變數data_from_client[]裡面,請參閱pic_server_step_3.c並用VB範例pic_SERVER_client_VB_Iron_Key測試即可。

最後如何將數據打包,切割,加標籤,這些是應用軟體程式開發員的自由與責任啦。

開發工具方面,用VB所撰寫的範例程式就是開發工具。安裝YZ_PIC_v_4.08d 軟體後會出現在C:\YZ_PIC\Samples\pic_SERVER\VBpic_SERVER\VB\TCP_UDP 兩個目錄底下。TCP通訊時的監聽軟體,Packet Sniffer,必要時也可以幫點小忙。

參考文獻:

[1]   RFC1180, “A TCP/IP Tutorial”.

[2]   “TCP/IP Lean: Web Servers for Embedded Systems”

[3]   http://www.iosoft.co.ukpic_SERVER的原始碼是向Iosoft公司買的)

[4]   http://www.china-pub.com/computers/common/info.asp?id=12191