webbench1.5源碼讀後總結

webbench簡介html

webbench由C語言寫成的用於網站壓力測試的一個很是簡單的工具,它最多能夠模擬30000個併發鏈接去進行測試。web

webbench的安裝和使用能夠自行百度,也能夠過下這篇文章併發

 

webbench執行流程dom

命令行解析 --> 構建HTTP請求包 --> 建立指定數量的工做進程 --> 每一個工做進程對測試網站在測試時間內持續發送請求/接收響應socket

 

具體分析函數

1. 命令行解析。工具

  這裏主要用到了getopt庫。getopt庫是C中經常使用的命令行解析庫,具備以下一些經常使用的全局變量、結構體以及函數。測試

/* 經常使用全局變量 */

extern char*   optarg;    // 指向獲取的option
extern int     optind;    // 已經解析過的option的個數     
extern int     opterr;    // 錯誤碼
extern int     optopt;
/* 結構體:解析option時主要的結構體,用以指明有哪些指定options */

struct option {
    const char*    name;
    int            has_arg;
    int*           flag;
    int            val;      
};

/* has_arg的幾個宏 */
#define no_argument       0
#define require_argument  1
#define optional_argument 2
/* 經常使用的幾個函數 */

int getopt();

int getopt_long(int __argc, char* const* __argv, const char* __shortopts, const struct option* __longopts, int* __longind);

int getopt_long_only(int __argc, char* const* __argv, const char* __shortopts, const struct option* __longopts, int* __longind);

2. 構建HTTP請求包。網站

  代碼調用了build_request函數對HTTP請求包進行了構建。常見的HTTP請求包構建規則:ui

  請求方法 URL 協議版本 \r\n

   頭部字段名: 值  \r\n

    ....

   頭部字段名: 值  \r\n

   \r\n

   \r\n

  請求數據

  請求方法:GET, POST, HEAD, PUT, DELETE, TRACE, CONNECT, OPTIONS

  協議版本:HTTP/1.0   HTTP/1.1

  頭部: User-agent, Host, Pragma, Connection等等

3. 使用fork建立指定數量的工做進程,用pipe讓主進程和工做進程創建通訊,以便於主進程收集子進程的測試信息。

/* 使用fork建立多進程代碼片斷 */

static int bench(void)
{
    ...
    for (i = 0; i < clients; i++)
    {
        pid = fork();
        if (pid <= 0)  // 若是是子進程或者fork失敗了,退出這個循環 
        {
             sleep(1);
             break;
        }
    }

    ...   
}
/* fork 函數聲明 */

#include <unistd.h>
#include <sys/types.h>

pid_t fork(void);   // pid_t 在 sys/types.h 中定義


/* pipe 函數聲明 */
#include <unistd.h>

int pipe(int pipefd[2]);


/* fdopen 函數聲明 */
#include <stdio.h>

FILE *fdopen(int fd, const char *mode); // 打開 pipe 文件 

4. 每一個進程模擬一個客戶端,建立socket並鏈接測試web,用alarm定時測試時長,在這個時間段裏,客戶端持續向web請求並接收響應。

 這裏有幾點要注意:

  a) 在客戶端的socket須要兩步完成對web的鏈接:建立一個socket(使用socket()函數);鏈接web(使用connect()函數)。

  b) alarm定時時長,輸入的參數只能是秒數。當定時時間到了的時候,系統會發送一個SIGALRM信號給alarm所在的進程,因此在調用alarm以前,須要註冊一個信號函數sigaction或signal(代碼中使用了sigaction),將SIGALRM與回調函數綁定,當系統發送SIGALRM,會調用相應的回調函數(代碼中使用了alarm_handler)進行處理。

上面幾個函數的聲明以下

/* socket, connect 函數聲明 */
#include <sys/types.h>
#include <sys/socket.h>

int socket(int domain, int type, int protocol);
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);


/* alarm 函數聲明 */
#include <unistd.h>

unsigned int alarm(unsigned int seconds);


/* sigaction 函數聲明 */
#include <signal.h>

int sigaction(int signum, const struct sigaction *act, struct sigation *oldact);

struct sigaction {
    void          (*sa_handler)   (int);
    void          (*sa_sigaction) (int, siginfo_t*, void*);
    sigset_t      sa_mask;
    int           sa_flag;
    void          (*sa_restorer)  (void);
};

 

完!

2018-03-21 23:39:46

相關文章
相關標籤/搜索