標籤:收集 param build ons 代理服務 變數 bytes 連接埠 退出
源碼:https://github.com/EZLippi/WebBench
關鍵全域變數: speed 成功次數 failed 失敗次數 bytes 接收位元組數 benchtime 執行時間長度(秒)
build_request() 函數:產生請求字串。一)請求第一行,如:GET /mall HTTP/1.0
- 根據命令列參數中的要求方法種類,把"GET"、"HEAD"、"OPTIONS"或"TRACE"相應複製到 request[]。
- 在request中,接下來添加一個空格。
- 如果命令列參數url不包含"://",則它不是個有效URL,報錯、退出。
- 如果url長度超過1500個字元,則太長,退出。
- 如果url開頭不是"http://",則報錯。
- 如果沒有設定代理,則
- 從url中取主機名稱和連接埠號碼,分別填至host和proxyport
- 取路徑部分,添加至 request
- 如果使用HTTP 1.0 或 1.1,則將 " HTTP/1.0" 或 " HTTP/1.1" 添加至 request。(注意前置空格)
- 如果使用HTTP 0.9,則無需添加此協議部分。
- 換行:添加 "\r\n" 至 request
二)請求後續行:
- 若HTTP版本在1.0及以上,則向request添加:"User-Agent: WebBench 1.5\r\n"。注意有換行。
- 若不使用代理,且版本在1.0以上,則向request添加主機頭("Host: " + host)並換行。
- 若不使用代理,且強制重新整理,則向request添加緩衝控制(不緩衝):"Pragma: no-cache\r\n"。
- 若版本在1.1及以上,則添加:"Connection: close\r\n"。
- 若版本在1.0及以上,則再添加空行:"\r\n"。
- 結束。■
bench()函數:建立各子進程以發送HTTP請求,並收集統計資料。
- 檢測目標伺服器(URL中的host或者代理)是否可以串連:使用connect()。
- 建立一對管道:使用pipe()。
- 建立指定個數clients的子進程:使用fork()。
- 在子進程中:
- 調用 benchcore() 執行測試。
- 向管道寫入三項資料:速度、失敗次數、位元組數。
- 結束。■
[在父進程中]
- 迴圈 clients次,反覆執行:
- 從管道讀入下一個子進程的三項資料:速度、失敗次數、位元組數。
- 若讀入項數少於3,說明已無資料可讀、或其餘子進程已提前結束,跳出迴圈。
- 累計三項資料
- 列印統計結果:
- 速度:分兩項
- 總請求數 / 時間 = (speed+failed)/,單位:次/分
- 總位元組數 / 時間,單位:位元組/秒
- 成功次數:speed
- 失敗次數:failed
- 結束。■
benchcore()函數:(在子進程中)反覆發送HTTP請求。
- 使用SIGALRM安裝定時器:時間長度來自命令列參數。
- 迴圈 直到定時器逾時:
- 串連伺服器(或Proxy 伺服器),得fd;若串連失敗,則失敗次數 failed 增1,跳至下一輪迴圈
- 向fd寫入請求串;若寫入失敗,則 failed 增1,關閉fd,跳至下一輪迴圈
- 若採用HTTP/0.9協議,則停止發送:使用shutdown();
- 若要等伺服器響應,則
- 反覆從fd讀出響應資料,直到讀入0位元組(表示讀完),累計位元組數至 bytes。
- 若出錯,則 failed 增1,關閉fd,跳至下一輪迴圈
- 關閉fd。若出錯,則 failed 增1。
- 累加成功次數 speed。
- 結束。■
學習到的Linux API/C庫函數:getopt、getopt_long() 命令列參數解析,詳見《使用GETOPT()處理命令列參數》strstr() 在字串中搜尋另一個字串strchr() 從串頭開始搜尋單個字元srrrchr() 從串尾開始搜尋單個字元strncasecmp() 串比較,大小寫不敏感strcspn(s1, s2) 返回n,表示從s1串頭開始連續有n個字元都不在字串s2中。例如 strcspn("My 1984", "0123456789") == 3。fdopen、fprintf、fscanf、setvbuf 等流式庫I/O函數。fork、pipe 與進程有關的函數。shutdown() 與 close() 的區別。 問題:1、為什麼sleep()能讓子進程快點?
/* fork children */ for (i = 0; i < clients; i++) { pid = fork(); if (pid <= (pid_t) 0) { /* child process or error*/ sleep(1); /* make children faster */ break; } }
雜項:主機名稱最大長度:64命令列最大長度:2048/* 定義所在檔案:/usr/include/asm/param.h */#define MAXHOSTNAMELEN 64 /* max length of hostname */#define COMMAND_LINE_SIZE 2048
WebBench源碼分析與心得