最近學習到了《深入理解電腦系統》的第11章網路編程,在最後一節是一個名為Tiny的小型web伺服器的實現,源代碼書中已經給出,這裡就不再複製粘貼了。這篇小博客主要記錄一下課後題10的解答。原題目為: 寫出CGI adder函數的HTML表單。你的表單應該包括兩個文本框,用戶將需要相加的兩個數字填在 ...
最近學習到了《深入理解電腦系統》的第11章網路編程,在最後一節是一個名為Tiny的小型web伺服器的實現,源代碼書中已經給出,這裡就不再複製粘貼了。這篇小博客主要記錄一下課後題10的解答。原題目為:
寫出CGI adder函數的HTML表單。你的表單應該包括兩個文本框,用戶將需要相加的兩個數字填在這兩個文本框中。你的表單應該使用GET方法請求內容。
因為我以前沒接觸過HTML表單,先百度之,找到了w3school的HTML教材,看了一下表單的部分,寫出了一個很簡單的小表單,命名為index.html:
1 <!DOCTYPE html> 2 <html> 3 <body> 4 5 <p> 6 please enter two numbers:<br> 7 </p> 8 9 <form action="/cgi-bin/adder"> 10 The first number: 11 <input type="number" name="num1"> <br> 12 The second number: 13 <input type="number" name="num2"> <br> 14 <input type="submit" value="Submit"> 15 </form> 16 17 </body> 18 </html>
這是輸入localhost:8888之後瀏覽器顯示的效果圖。8888是我設置的tiny的埠,至於為什麼沒有後邊的/index.html,是因為我在源代碼中將index.html設為了主界面。
我們可以隨便輸入兩個數字,點擊Submit按鈕,結果肯定是不對的。。
如上圖所示,結果顯示的是0。註意在該網頁的地址欄處,我們看到"localhost:8888/cgi-bin/adder?num1=22&num2=22",看過tiny源碼我們就會知道,adder.c所要分析的數據是在&符號兩邊的純數字,也就是說,要想正確的被adder.c程式求和,地址欄應該顯示"localhost:8888/cgi-bin/adder?22&22"才對。出現上圖中的錯誤的原因就是,adder程式沒有取得兩個參數的數值大小。解決方法很簡單,只需要在adder.c程式里把兩個數字取出來就行了,整個adder.c代碼如下所示:
1 #include "net.h" 2 3 int main(void) 4 { 5 char *buf, *p; 6 char arg1[MAXLINE], arg2[MAXLINE], content[MAXLINE]; 7 char tmp[MAXLINE]; 8 int n1 = 0, n2 = 0; 9 10 if ( (buf = getenv("QUERY_STRING")) != NULL) { 11 p = strchr(buf, '&'); 12 *p = '\0'; 13 14 strcpy(arg1, buf); 15 strcpy(arg2, p+1); 16 17 //用來取出兩個參數的代碼 18 p = strchr(arg1, '='); 19 strcpy(arg1, p+1); 20 p = strchr(arg2, '='); 21 strcpy(arg2, p+1); 22 23 n1 = atoi(arg1); 24 n2 = atoi(arg2); 25 } 26 27 sprintf(content, "QUERY_STRING = %s", buf); 28 sprintf(content, "Welcome to add.com: "); 29 //sprintf(content, "arg1=%s, arg2=%s\n", arg1, arg2); 調試輸出參數 30 sprintf(content, "%sThe Internet addition portal.\r\n<p>", content); 31 sprintf(content, "%sThe answer is: %d + %d = %d\r\n<p>", 32 content, n1, n2, n1 + n2); 33 sprintf(content, "%sThanks for visiting!\r\n", content); 34 35 //generate the http response 36 printf("Connection: close\r\n"); 37 printf("Content-length: %d\r\n", (int)strlen(content)); 38 printf("Content-type: text/html\r\n\r\n"); 39 printf("%s", content); 40 fflush(stdout); 41 42 exit(0); 43 }
重新編譯adder.c之後,我們再次在瀏覽器輸入網址:localhost:8888,輸入兩個數字,結果如圖:
至此,我們學習Tiny的第一階段就算完成了,完成了課後題11.10的要求,能夠處理來自瀏覽器的靜態請求和動態請求。但是,由於我們的Tiny一次只能處理一個連接,效率太低了。下一節我們就要對Tiny進行一下改進,使其能夠支持併發處理。