当前位置: 首页 > 工具软件 > Webbench > 使用案例 >

修改webbench支持长连接

鲁乐
2023-12-01

概述

我们知道HTTP协议采用“请求-应答”模式,当使用普通模式,即非KeepAlive模式时,每个请求/应答客户和服务器都要新建一个连接,完成之后立即断开连接(HTTP协议为无连接的协议);当使用Keep-Alive模式(又称持久连接、连接重用)时,Keep-Alive功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接。

http 1.0中默认是关闭的,需要在http头加入"Connection: Keep-Alive",才能启用Keep-Alive;http 1.1中默认启用Keep-Alive,如果加入"Connection: close ",才关闭。目前大部分浏览器都是用http1.1协议,也就是说默认都会发起Keep-Alive的连接请求了,所以是否能完成一个完整的Keep-Alive连接就看服务器设置情况。

优点明显:避免了建立/释放连接的开销

benchcore.c中增加:

  • 在循环外创建socket,每次重复通过这个socket读写,而不在重新创建socket。
  • 前面参数处理,while((opt=getopt_long(argc,argv,"912Vfrt:p:c:?hk",long_options,&options_index))!=EOF 部分的代码修改。

socket.c中增加

  • SO_LINGER 设置为onoff=1,linger=1,进行优雅关闭。
  • 使用fcntl设置fd为O_NONBLOCK非阻塞。

核心修改:

原来代码

if (http10 > 1)
      strcat(request, "Connection: close\r\n");
   /* add empty line at end */
   if (http10 > 0)
      strcat(request, "\r\n");
   // printf("Req=%s\n",request);

修改为

if(http10>1)
    {
        if (!keep_alive)
            strcat(request,"Connection: close\r\n");
        else
            strcat(request,"Connection: Keep-Alive\r\n");
    }
if (keep_alive)
    {
        while (timerexpired == 0 && (s = Socket(host, port)) == -1){ };
        //s = Socket(host, port);
    nexttry1:
        while (1)
        {
            if (timerexpired)
            {
                if (failed > 0)
                {
                    /* fprintf(stderr,"Correcting failed by signal\n"); */
                    failed--;
                }
                return;
            }

            if (s < 0)
            {
                failed++;
                continue;
            }
            if (rlen != write(s, req, rlen))
            {
                failed++;
                close(s);
                while (!timerexpired == 0 && (s = Socket(host, port)) == -1){};
                //s = Socket(host, port);
                continue;
            }
            if (force == 0)
            {
                /* read all available data from socket */
                while (1)
                {
                    if (timerexpired)
                        break;
                    i = read(s, buf, 1500);
                    /* fprintf(stderr,"%d\n",i); */
                    if (i < 0 && errno == EAGAIN)
                    {
                        usleep(200);
                        continue;
                    }
                    else if (i < 0)
                    {
                        failed++;
                        close(s);
                        //while ((s = Socket(host,port)) == -1);
                        goto nexttry1;
                    }
                    else if (i == 0)
                        break;
                    else
                        bytes += i;
                    // Supposed reveived bytes were less than 1500
                    //if (i < 1500)
                    break;
                }
            }
            speed++;
        }
    }

测试

cwd@cwd:~/work/WebBench$ webbench -t 10 -c 1000 -2 --get -k  http://www.baidu.com/
Webbench - Simple Web Benchmark 1.5
Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.
Runing info: 1000 clients, running 10 sec.

Speed=67344 pages/min, 1410208 bytes/sec.
Requests: 11224 susceed, 0 failed.
cwd@cwd:~/work/WebBench$ webbench -t 10 -c 1000 -2 --get   http://www.baidu.com/
Webbench - Simple Web Benchmark 1.5
Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.
Runing info: 1000 clients, running 10 sec.

Speed=6030 pages/min, 1431723 bytes/sec.
Requests: 1005 susceed, 0 failed.

代码可以参照我的githubMy_WebBench

 类似资料: