--- title: 2016q1 Homework #3 toc: no ... 預期目標 ------------ - 學習多執行緒程式開發 - 應用物件導向程式開發方法 - 學習使用 Linux 系統呼叫 - 透過 Doxygen 自動建立技術文件 - 培養專業程式開發風格 預先安裝的套件 ------------ ``` $ sudo apt-get install apache2-utils check $ sudo apt-get install doxygen graphviz ``` Server Framework in modern C ----------------------------- * [server-framework](https://github.com/embedded2016/server-framework): 用 C99 撰寫、具備物件導向程式設計風格的伺服器開發框架 * 由三部份組成: - [async](https://github.com/embedded2016/server-framework/blob/master/async.h) - [reactor](https://github.com/embedded2016/server-framework/blob/master/reactor.h) - [protocol-server](https://github.com/embedded2016/server-framework/blob/master/protocol-server.h) * 取得原始碼並編譯: ``` $ git clone https://github.com/embedded2016/server-framework.git $ cd server-framework $ make ``` * 測試 [async](https://github.com/embedded2016/server-framework/blob/master/async.h) ``` $ ./test-async ``` - 預期將看到類似以下輸出: ``` wrote task 8190 wrote task 8191 Hi! 16377 Hi! 16378 # signal finish at (711.426132) ms # elapsed time: (711.728594) ms ``` * 測試 [reactor](https://github.com/embedded2016/server-framework/blob/master/reactor.h) ``` $ ./test-reactor ``` - 預期將看到以下訊息: ``` Serving HTTP on 127.0.0.1 port 8080 now open up the URL http://localhost:8080 on your browser ``` - 依據指示,在網頁瀏覽器裡頭打開網址 `http://localhost:8080`,將會看到 "Hello World!" 字樣 - 回到原本執行 `./test-reactor` 的終端機視窗,按下 `Ctrl-C` 以結束程式 * 測試 [protocol-server](https://github.com/embedded2016/server-framework/blob/master/protocol-server.h) ``` $ ./test-protocol-server ``` - 預期將看到類似以下訊息: ``` (pid 4130 : 8 threads) Listening on port 8080 (max sockets: 65536, ~5 used) ``` - 這時開啟新的終端機,輸入 `telnet localhost 8080`,可以發現原本執行 `test-protocol-server` 的終端機印出以下訊息: ``` A connection was accepted on socket #7. ``` - 回到執行 `telnet` 的終端機,可發現以下輸出: ``` Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Simple echo server. Type 'bye' to exit. ``` - 試著打字 (記得按下 `Enter`),會發現會重複輸出,直到輸入 `bye` 時,才會結束連線 測試網頁伺服器的效能 ----------------- * 確保之前的測試程式均已關閉,而且 port 8080 沒被佔用 - 可透過 `$ pkill -9 httpd` 和 `$ pkill -9 "test-"` 來強制關閉伺服器 * 執行 `$ ./httpd`,預期將看到類似以下輸出: ``` (pid 4223 : 1 threads) Listening on port 8080 (max sockets: 65536, ~5 used) Clients: 0 # Total Clients: 0 ``` * 不要關閉執行 `httpd` 的終端機視窗,為了後續說明方面,我們稱為這個終端機畫面為「伺服器」 * 開啟新的終端機視窗,並執行以下指令: ``` $ ab -c 32 -n 100 http://localhost:8080/ ``` - 預期將看到以下輸出,請抱持耐心等待,且暫時不要執行其他程式 ``` This is ApacheBench, Version 2.3 <$Revision: 1706008 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ ``` - 如果出現 Benchmarking localhost (be patient)...apr_socket_recv: Connection refused (111) - 嘗試將 localhost 改為 127.0.0.1 後再執行一次 * 等待一陣子之後,會看到類似以下輸出: ``` Concurrency Level: 32 Time taken for tests: 15.621 seconds Complete requests: 100 Failed requests: 6 (Connect: 0, Receive: 0, Length: 6, Exceptions: 0) Total transferred: 9900 bytes HTML transferred: 1300 bytes Requests per second: 6.40 [#/sec] (mean) Time per request: 4998.873 [ms] (mean) Time per request: 156.215 [ms] (mean, across all concurrent requests) Transfer rate: 0.62 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 2 0.7 2 3 Processing: 3619 3877 177.2 3996 4001 Waiting: 0 1 0.5 0 3 Total: 3621 3879 177.2 3998 4001 ``` * 當對伺服器按下 `Ctrl-C` 時,預期將看到類似以下輸出: ``` server done (4223) Stopped listening for port 8080 ``` 使用 Doxygen 自動產生文件 ----------------------- * Doxygen 可掃描給定原始程式碼內容、註解,之後將自動產生程式文件,其中一種輸出就是 HTML,可透過瀏覽器來閱讀文件和程式碼 * 執行 `make doc`,之後會產生新的目錄 `html`,可用 Firefox 或 Chrome browser 開啟該目錄底下的 `index.html` 檔案 * 類似以下網頁畫面,注意右邊有搜尋功能: ![](/embedded/2016q1h3/html.png) * 按下 "Data Structures" 頁面可探究物件相依性示意圖: ![](/embedded/2016q1h3/graph.png) * 延伸閱讀: [Learning Doxygen](http://wiki.herzbube.ch/index.php/LearningDoxygen) 作業要求 ------- * 在 GitHub 上 fork [server-framework](https://github.com/embedded2016/server-framework) * 在「[作業區](https://embedded2016.hackpad.com/2016q1-Homework-3-a3Rb2XROJso)」紀錄你閱讀程式碼過程中的疑惑,像是語法、物件導向設計方法、系統呼叫的使用,需要具體指出程式碼片段,以及自己探索過程中閱讀的材料 * 搭配閱讀以下材料: - [How to use epoll? A complete example in C](https://banu.com/blog/2/how-to-use-epoll-a-complete-example-in-c/) - [The Event Poll Interface](https://www.safaribooksonline.com/library/view/linux-system-programming/0596009585/ch04s02.html) - [Understanding “volatile” qualifier in C](http://www.geeksforgeeks.org/understanding-volatile-qualifier-in-c/) - [Unix Signals](http://cis-linux1.temple.edu/~giorgio/cis307/readings/signals.html) - [Introduction to JDBC and types of drivers](https://www.javatpoint.com/java-jdbc) - [信號量測](http://www.intra.idv.tw/data/tech/hw/travellogic.htm) - [Reactor Pattern](https://en.wikipedia.org/wiki/Reactor_pattern) - [pipe system call](http://www2.cs.uregina.ca/~hamilton/courses/330/notes/unix/pipes/pipes.html) - [Sockets Tutorial](http://www.linuxhowtos.org/C_C++/socket.htm) - [Sockets Tutorial](https://madanswer.com/C+Plus+Plus) * 研讀[第 5 週課程](https://embedded2016.hackpad.com/ep/pad/static/CH64GFFiviW)的物件導向程式設計參考資料,也一併紀錄問題於共筆上 * 分析 `httpd` 程式執行效能,指出效能低落的原因,並且提出改進方案 - 需要實際去改寫程式碼! * 加分題 - 補完 `tests/test-buffer.c` 的測試項目 - 實做基本的 HTTP parser - 參考 `tests/test-protocol-server.c`,實做類似 BBS 的 telnet server,可允許使用者登入 + BBS 控制碼可參考 [maplebbs](https://github.com/xeonchen/maplebbs-itoc) 截止日期 ------- * Apr 3, 2016 (含) 之前 * 越早在 GitHub 上有動態、越早接受 code review,評分越高