C 网页压力测试器

  我在长大 : http://music.163.com/#/song?id=155977

#
description.switch.threshold
右键新建 Integer 值,键名为 description.switch.threshold ,赋值 750000。

背后拼接结果截图如下:

Pearl Crescent Page Saver Basic
1.5

保留网页为图片,这样存网页也有益。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

//控制台打印错误信息, fmt必须是双引号括起来的宏
#ifndef CERR
#define CERR(fmt, ...) \
    fprintf(stderr,"[%s:%s:%d][error %d:%s]" fmt "\r\n",\
         __FILE__, __func__, __LINE__, errno, strerror(errno),##__VA_ARGS__)

//检测并退出的宏
#define CERR_EXIT(fmt, ...) \
    CERR(fmt, ##__VA_ARGS__), exit(EXIT_FAILURE)

#endif/* !CERR */

// url长度限制 和 请求串长度限制
#define _INT_URL (1024)
#define _INT_REQ (2048)
//主机地址的最大长度
#define _INT_PORT (255)
//等待时间,在60s后就不在处理了
#define _INT_END  (23)

//简单结构
struct iport{
    short port;
    char ip[_INT_PORT];
};

//默认全局标识, 控制开关
volatile int v_timer = 0;

//闹钟信号,当它启动那一刻就表示可以退下了.
static void __alarm(int sig)
{
    v_timer = 1;
}

/*
 * 执行的主要方法,结果会通过写管道 wfd写入
 */
void bcore(struct iport* ips, const char* req, int wfd);

/*
 * 只接受完整请求 
 * 例如
 * brequest("http://192.168.1.162:80/", ...) 或 http://www.baidu,com
 * 通过url拼接请求串,并返回访问结构
 */
struct iport* brequst(const char* url, char rqs[], int len);
//请求主方法,客户端,返回开启的子进程数
int bench(int cut, const char* url, int wfd);

/*
 * 请求链接主机,根据ip或url
 *
 * host    : url地址
 * port : 请求的端口号
 */
int contweb(const char* host, int port);

Tab Mix Plus 0.3.6
增强标签页浏览功用的恢宏。其实这么些也很鸡肋,然而对此我如此一个无独有偶了用The
World浏览器的用户来说,双击关闭标签已经称为一种习惯了- -!

美高梅娱乐4858.com 1

backword 1.3.4
backword
是一个拉扯人们收集页面中的陌生的词汇及其出现的场地以帮扶了然和记­忆的
web 工具。工作方法与金山词霸的屏幕取词类似,但仅功效于 firefox 页面。

终极输出 每分钟请求的页面数, 每秒请求的bit流,请求成功多少次,请求失利多少次.

 

咱俩先说一下,参照的事物和内需领会的东西

# network.http.pipelining
在 Filter 中输入 network.http.pipelining,双击赋值为 true,默认为
false。如若没有找到这些键值,能够右键新建一个 Boolean,把它赋值为 true
就 OK 了。

这里需要控制简单的Linux 操作,这里分享一个要好总计的socket入门基础文档.

#
network.http.pipelining.maxrequests
在 Filter 中输入 network.http.pipelining.maxrequests,双击并赋值为
8,默认键值为 4。
#
network.http.proxy.pipelining
在 Filter 中输入 network.http.proxy.pipelining,双击并赋值为 true。

 

Copy Link Name 1.2.4
可以经过右键关联菜单复制链接名称。这样就不需要吃力地选中链接文字举办Ctrl+C了^_^

正文

   
至于说它其他地点的缺点呢?举个例证,用以下js代码编写一个HTML网页来测试,即使您是2.0.0.6及其以下版本(现在的新星版本)保证会让你的FF瘫痪-
-!

  错误是免不了,欢迎指正交换,共同消磨有趣的时光.
( ^_^ )/~~拜拜

# description.notify.ontimer
右键新建 Boolean 值,键名为 description.notify.ontimer,赋值 true。

 

至于Firefox的要旨(皮肤),我前天用的是Vista-aero
2.0.0.0
,因为Vista系统下用那个皮肤确实看的不利,呵呵

//请求主方法,客户端,返回开启的子进程数
int bench(int cut, const char* url, int wfd);

#
description.notify.backoffcount
右键新建 Integer 值,键名为 description.notify.backoffcount,赋值 5。

4.看案例结果 

   
这里有个网页的测试链接:http://cathayan.org/temp/test_intervals_bug.html,据说是setInterval方法与FF的兼容问题。当然IE下浏览那些网页是正规的。

地方就是本次拍卖的首要流程, 多次伸手拔取的fork多少个子进程

Drag de Go 0.2.5
拖放选定的文件、链接、图片、指向扩张文件的链接,可以兑现不同的效能。(正在考虑这么些扩张要不要卸载以提高FF性能,重假如觉得有点鸡肋)

到这基本函数基本都形成了,总的业务构建请看下边

   
近些年可比闲,看到那么多网站和博客上的广告推荐安装Firefox,于是便想亲身感受下。作为一名VISTA的前驱体验者,不体验下鼎鼎知名的
Firefox实在是有点。。之所以写这篇小说,一来是想记录下自己设置的壮大,以便将来重装的时候查阅,二来也是想把自己行使Firefox的感受推荐
给大家。
    与IE相比较,Firefox的独到之处有许多,GG广告上用来“吹嘘”的两大优势是:
1、安全,不会因而网页感染病毒;
2、浏览网页速度比IE快。
   
第一个亮点,应该是不用置疑的。对网页代码标准化和对ActiveX插件的的严刻要求,使得Firefox很难染上病毒。可是Firefox也绝不全盘无缺,最强烈的劣势就是:内存占用量极大。有人用“内存就是用来用的,留着也是荒废”说服了自我(已不玩3D网游的自身现在很难把电脑的1G内存用完-
-!)。假使您想找一款内存占用量最少,最好用的浏览器,我向你推荐的是迄今我觉着最好用的IE内核浏览器:The
World(世界之窗浏览器)http://www.ioage.com/cnnew/index.htm

/*
 * 执行的主要方法,结果会通过写管道 wfd写入
 */
void 
bcore(struct iport* ips, const char* req, int wfd)
{
    int srv, len, rlen;
    int speed = 0, failed = 0, bytes = 0;
    FILE* fx;
    char buf[_INT_REQ];    

    //先注册信号
    if(SIG_ERR == signal(SIGALRM, __alarm))
        CERR_EXIT("signal SIGALRM error!");
    alarm(_INT_END);

    len = strlen(req);    
    for(;;){
        if(v_timer){ //结束之前减一,认为成功过
            if(failed>0)
                --failed;
            break;
        }        

        srv = contweb(ips->ip, ips->port);
        if(srv < 0){
            ++failed;
            continue;    
        }
        //开始写入数据
        if(len != write(srv, req, len)){
            ++failed;
            close(srv);
            continue;
        }
        //下面读取数据,v_timer标志是否超时,超时直接走
        for(;!v_timer;){
            rlen = read(srv, buf, _INT_REQ);                
            if(rlen < 0){ //不考虑软中断了,有问题直接退出
                ++failed;
                close(srv);
                goto __bcore_exit; //退出结算
            }
            if(rlen == 0)//服务端关闭,结束读取
                break;
            bytes += rlen;
        }
        close(srv);
        ++speed;
    }    

__bcore_exit:
    //管道写入
    fx = fdopen(wfd, "w");
    if(NULL == fx)    
        CERR_EXIT("fdopen wfd:%d error!", wfd);
    fprintf(fx,"%d %d %d\n", speed, failed, bytes);    
    fclose(fx);
}

# description.notify.interval
右键新建 Integer 值,键名为 description.notify.interval,赋值 750000。

       一切都发生在追思的刹这。

Thunder Extension 3.5
那些是FF补助迅雷下载的增添,习惯用迅雷的用户可以装这几个,安装模式,打开”迅雷“-”工具“-”浏览器补助“-”添加Firefox辅助”

协议等.

#
description.max.tokenizing.time
右键新建 Integer 值,键名为 description.max.tokenizing.time,赋值
2250000。

末尾就需要我们尝试了,用的还凑合者.

JSView 1.4
翻开外部JS和CSS,这么些对Web Designer来说无疑是分析网页的利器~

背后介绍的是有了请求串,怎么发送请求和拍卖请求,代码如下:

以上所关联的保有扩充,都得以在这里找到,这一个扩大推荐自家大部分也是从aw这里看到的

不知疲倦的整夜码代码 像块石头一样滚来滚去
不过找不到家的自由化
自家在长大 / 我在长大 / 我在长大 / 我在长大

#
description.interrupt.parsing
右键新建 Boolean 值,键名为 description.interrupt.parsing,赋值 true。

  经过地方简单格式介绍,这里就说一下思路. 关于 那篇博文,C 对网页的压力测试构建的思路.具体如下:

IE Tab 1.3.3.20070528
以此貌似的话都是不可或缺的,功用是让Firefox切换成IE内核,浏览部分只帮忙IE浏览器的页面。有了那个,基本上你的IE就不曾存在的必不可少了。。。

背后我们就经过代码来说了,最好你写五次,就明白容易了.扯一点,关于volatile 可以阐明是为了艺术编译器优化,导致代码死循环.

   
具体的装置原因,在这边能够找到:http://forums.mozine.cn/index.php?showtopic=16474
    接下去是自我设置的FF扩充列表:

主机的sin_addr地址量.


在用Firefox也绝非什么太大的病症,就是打开某些代码不规范的网站速度奇慢,甚至有可能让FF崩溃-
-!所以IE
Tab扩大的用途如故很大滴,不过自己要么控制继续用FF一段时间,当然也可能也会直接用下来。关于IE
Tab设置的过滤列表我暂时设置了以下这多少个:

    2. socket 简单入门doc
http://download.csdn.net/detail/wangzhione/9412538

Firebug 1.05
美高梅娱乐4858.com,编排、调试和监察任何网页上的 CSS、HTML 和
Javascript。功效异常强劲,对于网页设计师来说很实用!

美高梅娱乐4858.com 2  

# network.dns.disableIPv6
在 Filter 中输入 network.dns.disableIPv6,双击并赋值为 true。

1.概括说一点格式

Cache Status 0.7.2
在场合栏方便地查看缓存状态和管制缓存。

前言

<SCRIPT>
    set_y = 0;
    distance = 0;
   
document.all[‘move_banner’].style.left = 900;
    move_div();
//   
setInterval(‘move_div()’);
    function move_div()
    {
            var new_y;
            new_y =
document.body.scrollTop;
            distance = new_y – set_y
;
            if( set_y != new_y )
set_y += ( distance / 10 );
           
document.all[‘move_banner’].style.top = set_y+250;
   
setInterval(‘move_div()’);
    }
</SCRIPT>

 

 现在用Firefox也从没什么样太大的病症,就是开辟某些代码不规范的网站速度奇慢,甚至有可能让FF崩溃-
-!所以IE
Tab扩大的用途仍然很大滴,不过我或者决定继续用FF一段时间,当然也恐怕也会平素用下来。关于IE
Tab设置的过滤列表我临时设置了以下这个:
http://60.28.178.201/\*这个是迅雷下载的链接页面,不用IE的话迅雷弹不出来的。。
http://my.xunlei.com/\*
http://photo.qq.com/\*本来以为QQ代码都没问题的,结果发现QQ相册二级页面在FF下无法显示相册列表,具体原因也懒得找
http://user.qzone.qq.com/\*这个QQ空间FF肯定是支持不了滴
http://www.icbc.com.cn/\*中国工商银行网上银行
剩余的IE
Tab自带的过滤网址我就绝不了~

到这里, 基本准备干活就完了了,这就搞起吧, 看看那几个说起来很神秘的工具是怎么概括实现的.顺带扯一点,

InFormEnter 0.5.3
半机关格局帮您填表,同样的表单再也不用填写第二遍了,OH YEAH~

  <<独白>> 席慕蓉 节选一

# nglayout.initialpaint.delay
右键新建 Integer 值,键名为 nglayout.initialpaint.delay,赋值 0。

    for(i=0; i<cut; ++i){
        pid = fork(); //狂开进程了
        if(pid <= 0){
            sleep(1);//别让它太快完毕,父进程来不及收尸
            break;//结束子进程继续
        }
        ++rt;
    }        

    言归正传,最先推荐Firefox扩张~
   
第一,你得下载一个Firefox浏览器最新版本,你可以去官网下载:http://www.mozilla.com/en-US/firefox/或者
是去朋友的FF推广链接这里下载,因为这会给您的爱人带来一些微薄的收入。安装好FF后,首先,大家在地点栏输入about:config

 

从不什么样花哨的事物就是一道链接HTTP服务器, 假若传入的的host是url那么就调用 gethostbyname 获取到 请求

要么比较基础的,首要用的就是Linux编程相关的学问点.

d.总计请求报文, 输出总计

地点打印很多connect error,意思是成千上万经过请求链接退步,长期大量链接造成对方服务器拒绝链接, 负载均衡差,

/*
 * 这是一个对外的接口函数声明,
 *相当于public
 */
extern int isbig(void);

/*
 * 这个接口也具备对外能力,但是省略了extern
 *意图就是构建整个 *.h文件的时候需要用它,但是不希望用户用.
 *属于 low level api, 内部接口集用,外部不推荐用,有点像protected
 */
int heoo(void);

/*
 *    这个是个内部声明或定义, 只能在当前接口集的内部使用,外部无法
 *访问,相当于pirate
 */
static void* __run(void* arg);

     把向您借来的笔还给您吧。

个中 contweb 是一个可以按照ip或主机地址url解析,链接主机.具体贯彻如下

 

至于父子进程通信选用 管道

再来请求一个普通网站的截图

配乐 :

美高梅娱乐4858.com 3

c. 处理请求报文, 处理

// 主函数业务,从这开始
int main(int argc, char* argv[])
{
    int cut, len; //开启进程数量 和 读取scanf返回值
    int pfds[2];    
    FILE* fx;
    int speed = 0, failed = 0, bytes = 0;

    //简单检测    
    if((argc != 3) || (cut = atoi(argv[1]))<=0 || cut > USHRT_MAX){        
        CERR_EXIT(
             "\r\nuage:   ./webtest.out [cut] [url]"
            "\r\n    :=> ./webtest.out 19 http://www.baidu.com/"
        );
    }    

    //创建管道 进行测试, 代码比较杂,需要一些Linux基础知识,多练习
    if(pipe(pfds)<-1)
        CERR_EXIT("pipe create is error!");

    //结果处理,开启指定多个进程,重新获取进程开启成功数
    cut = bench(cut, argv[2], pfds[1]);    

    //这里读取管道信息
    fx = fdopen(pfds[0], "r");
    if(NULL == fx)
        CERR_EXIT("fdopen pfds[0]:%d error.", pfds[0]);

    //统计最后数据
    setbuf(fx, NULL);
    while(cut > 0){
        int s, f, b;
        len = fscanf(fx, "%d %d %d", &s, &f, &b);    
        if(len < 3){
            CERR("fscnaf read error! len:%d.", len);
            break;
        }
        speed += s;
        failed += f;
        bytes += b;            
        --cut;        
    }
    fclose(fx);
    close(pfds[0]);
    close(pfds[1]);

    //输出统计结果
    puts("***********-----------------------------------------------------------***********");
    printf("Collect %.2f pages/min, %.2f kb/sec. Request %d sucess, %d failed.\n",
        (speed+failed)*60.0f/_INT_END, bytes/1024.0f/_INT_END, speed, failed);
    puts("***********-----------------------------------------------------------***********");

    return 0;
}

 

光鲜的私自都是平凡.喜欢才是人那台机器的最好能源.

全体的socket demo都4-5百行代码,写的手疼.封装也很麻烦.可是你精通了它的思绪或套路,如故很容易上马提枪的.

  首先代码可以优化,我写好后没优化了,就直接分享了.先看http协议分析代码如下

美高梅娱乐4858.com 4

首先观望下边前戏代码

CERR连串是一个匡助宏,简单打印错误音讯. 技巧值得推介使用.其中
_INT_END 代表每个子进程请求的时日长度(s).

此处就这么了. 麻雀虽小,能用就好. 完整测试 demo 如下

       把向你借来的笔还给您啊。

 

要有好套路,这样打起来才顺.等同于实践可以总括出理论基础.前任要感谢.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

//控制台打印错误信息, fmt必须是双引号括起来的宏
#ifndef CERR
#define CERR(fmt, ...) \
    fprintf(stderr,"[%s:%s:%d][error %d:%s]" fmt "\r\n",\
         __FILE__, __func__, __LINE__, errno, strerror(errno),##__VA_ARGS__)

//检测并退出的宏
#define CERR_EXIT(fmt, ...) \
    CERR(fmt, ##__VA_ARGS__), exit(EXIT_FAILURE)

#endif/* !CERR */

// url长度限制 和 请求串长度限制
#define _INT_URL (1024)
#define _INT_REQ (2048)
//主机地址的最大长度
#define _INT_PORT (255)
//等待时间,在60s后就不在处理了
#define _INT_END  (23)

//简单结构
struct iport{
    short port;
    char ip[_INT_PORT];
};

//默认全局标识, 控制开关
volatile int v_timer = 0;

//闹钟信号,当它启动那一刻就表示可以退下了.
static void __alarm(int sig)
{
    v_timer = 1;
}

/*
 * 执行的主要方法,结果会通过写管道 wfd写入
 */
void bcore(struct iport* ips, const char* req, int wfd);

/*
 * 只接受完整请求 
 * 例如
 * brequest("http://192.168.1.162:80/", ...) 或 http://www.baidu,com
 * 通过url拼接请求串,并返回访问结构
 */
struct iport* brequst(const char* url, char rqs[], int len);
//请求主方法,客户端,返回开启的子进程数
int bench(int cut, const char* url, int wfd);

/*
 * 请求链接主机,根据ip或url
 *
 * host    : url地址
 * port : 请求的端口号
 */
int contweb(const char* host, int port);

// 主函数业务,从这开始
int main(int argc, char* argv[])
{
    int cut, len; //开启进程数量 和 读取scanf返回值
    int pfds[2];    
    FILE* fx;
    int speed = 0, failed = 0, bytes = 0;

    //简单检测    
    if((argc != 3) || (cut = atoi(argv[1]))<=0 || cut > USHRT_MAX){        
        CERR_EXIT(
             "\r\nuage:   ./webtest.out [cut] [url]"
            "\r\n    :=> ./webtest.out 19 http://www.baidu.com/"
        );
    }    

    //创建管道 进行测试, 代码比较杂,需要一些Linux基础知识,多练习
    if(pipe(pfds)<-1)
        CERR_EXIT("pipe create is error!");

    //结果处理,开启指定多个进程,重新获取进程开启成功数
    cut = bench(cut, argv[2], pfds[1]);    

    //这里读取管道信息
    fx = fdopen(pfds[0], "r");
    if(NULL == fx)
        CERR_EXIT("fdopen pfds[0]:%d error.", pfds[0]);

    //统计最后数据
    setbuf(fx, NULL);
    while(cut > 0){
        int s, f, b;
        len = fscanf(fx, "%d %d %d", &s, &f, &b);    
        if(len < 3){
            CERR("fscnaf read error! len:%d.", len);
            break;
        }
        speed += s;
        failed += f;
        bytes += b;            
        --cut;        
    }
    fclose(fx);
    close(pfds[0]);
    close(pfds[1]);

    //输出统计结果
    puts("***********-----------------------------------------------------------***********");
    printf("Collect %.2f pages/min, %.2f kb/sec. Request %d sucess, %d failed.\n",
        (speed+failed)*60.0f/_INT_END, bytes/1024.0f/_INT_END, speed, failed);
    puts("***********-----------------------------------------------------------***********");

    return 0;
}

/*
 * 请求链接主机,根据ip或url
 *
 * host    : url地址
 * port : 请求的端口号
 */
int 
contweb(const char* host, int port)
{
    int sd;
    in_addr_t ia;
    struct sockaddr_in sa = { AF_INET };    
    struct hostent *hp;

    ia = inet_addr(host);
    if(ia != INADDR_NONE)
        memcpy(&sa.sin_addr, &ia, sizeof(ia));
    else {
        hp = gethostbyname(host);
        if(hp < 0){
            CERR("gethostbyname %s error!", host);
            return -1;
        }
        memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);    
    }
    if((sd=socket(PF_INET, SOCK_STREAM, 0))<0){
        CERR("socket SOCK_STREAM");
        return sd;
    }    

    //连接主机
    sa.sin_port = htons(port);
    if(connect(sd, (struct sockaddr*)&sa, sizeof sa)<0){
        CERR("connect sd:%d error!", sd);
        return -1;
    }

    return sd;    
}

//通过url拼接请求串
struct iport* 
brequst(const char* url, char rqs[], int len)
{
    static struct iport __ips;
    //请求的主机, 中间用的url, 临时数据
    const char *hurl, *tmp;        
    char c;
    int pt = 0;//临时用的int变量

    //简单检查参数检查,检查数组大小,url是否合法
    if(len<_INT_REQ || !url || !*url || strlen(url)>_INT_URL)
        CERR_EXIT("params url:%s, len[>=%d];%d error.", url, _INT_REQ, len);    
    //检测url是否是http请求的url,也比较简单,复杂检查要用正则表达式
    hurl = strstr(url, "://");
    if(!hurl || strncasecmp(url, "http", 4))
        CERR_EXIT("url is err [%s]!", url);
    //简单初始化
    memset(rqs, 0, len);    
    memset(&__ips, 0, sizeof __ips);

    //这种代码可以优化,用指针替代数组索引
    strcat(rqs, "GET ");
    hurl += 3; //跳过 "://"指向下一个字符

    //解析url 上是否有端口信息
    tmp = index(hurl, ':');
    if(tmp && tmp < index(hurl, '/')){ 
        strncpy(__ips.ip, hurl, tmp - hurl);
        //没有做安全检查
        while((c=*++tmp)!='\0' && c!='/'){
            if(c<='9' && c>='0'){
                pt = 10*pt + c - '0';
                continue;
            }
            CERR_EXIT("url is error [%s].", url);        
        }
    }    
    else{
        pt = 80; //默认端口
        //这句话意思 是 将 www.baidu.com/ 其中/之前的地方写入到 ip[]中
        strncpy(__ips.ip, hurl, strcspn(hurl, "/"));    
    }
    __ips.port = pt;    

    //将这些内容链接到rqs中
    strcat(rqs, hurl + strcspn(hurl, "/"));
    //采用HTTP1.1 协议
    strcat(rqs, " HTTP/1.1\r\n");
    //添加请求方
    strcat(rqs, "User-Agent: Happy is good.\r\n");
    //上面这样解析有点慢,最快的是整体for,但是更难维护
    strcat(rqs, "Host: ");
    strcat(rqs, __ips.ip);
    strcat(rqs, "\r\n");
    //拼接串最后,连接状态,完毕就关闭
    strcat(rqs, "Connection: close\r\n");
    //拼接空行, 上面可以优化
    strcat(rqs, "\r\n");

    //最终检测,是否字符串太长了
    if(rqs[len-1])
        CERR_EXIT("get http too len!");

    return &__ips;            
}

/*
 * 执行的主要方法,结果会通过写管道 wfd写入
 */
void 
bcore(struct iport* ips, const char* req, int wfd)
{
    int srv, len, rlen;
    int speed = 0, failed = 0, bytes = 0;
    FILE* fx;
    char buf[_INT_REQ];    

    //先注册信号
    if(SIG_ERR == signal(SIGALRM, __alarm))
        CERR_EXIT("signal SIGALRM error!");
    alarm(_INT_END);

    len = strlen(req);    
    for(;;){
        if(v_timer){ //结束之前减一,认为成功过
            if(failed>0)
                --failed;
            break;
        }        

        srv = contweb(ips->ip, ips->port);
        if(srv < 0){
            ++failed;
            continue;    
        }
        //开始写入数据
        if(len != write(srv, req, len)){
            ++failed;
            close(srv);
            continue;
        }
        //下面读取数据,v_timer标志是否超时,超时直接走
        for(;!v_timer;){
            rlen = read(srv, buf, _INT_REQ);                
            if(rlen < 0){ //不考虑软中断了,有问题直接退出
                ++failed;
                close(srv);
                goto __bcore_exit; //退出结算
            }
            if(rlen == 0)//服务端关闭,结束读取
                break;
            bytes += rlen;
        }
        close(srv);
        ++speed;
    }    

__bcore_exit:
    //管道写入
    fx = fdopen(wfd, "w");
    if(NULL == fx)    
        CERR_EXIT("fdopen wfd:%d error!", wfd);
    fprintf(fx,"%d %d %d\n", speed, failed, bytes);    
    fclose(fx);
}

//请求主方法,客户端,返回开启子进程数
int 
bench(int cut, const char* url, int wfd)
{
    int i, rt = 0;//rt 记录正常开启的进程
    pid_t pid;
    char req[_INT_REQ];
    struct iport* ips;

    //这里初始化一些环境
    ips = brequst(url, req, sizeof req);    
    puts("***********-----------------------------------------------------------***********");
    puts(req); //打印数据
    puts("***********-----------------------------------------------------------***********");

    for(i=0; i<cut; ++i){
        pid = fork(); //狂开进程了
        if(pid <= 0){
            sleep(1);//别让它太快完毕,父进程来不及收尸
            break;//结束子进程继续
        }
        ++rt;
    }        
    if(pid < 0)
        CERR_EXIT("child %d process create error!", i);
    if(pid == 0){ //子进程处理
        bcore(ips, req, wfd);
        exit(EXIT_SUCCESS);//子进程这里就结束了
    }
    //下面是父进程处理
    return rt;                    
}

觉得注释也挺详细的有关

说到底总括结果是 每分钟请求了6357个界面左右,开启了23个子进程, 成功2414个,23个错误. 总的而言百度的发散着实无误,负载均衡强.

概念部分简单表明一下.在先博文中说过,这里再简单说一遍,编程和打游戏一样,要有好点子,

     
我的彻悟假设是缘自一种迷乱,那么,我的各种迷乱不也就只是因为一种彻悟?

重中之重思路是先检查 参数, 看 是否是 左边这样正则格式的串 
“http.://.+/”

走到中途,才猛然发现,我只剩余一副模糊的真面目,和一条不能够悔过自新的路。

 

//请求主方法,客户端,返回开启子进程数
int 
bench(int cut, const char* url, int wfd)
{
    int i, rt = 0;//rt 记录正常开启的进程
    pid_t pid;
    char req[_INT_REQ];
    struct iport* ips;

    //这里初始化一些环境
    ips = brequst(url, req, sizeof req);    
    puts("***********-----------------------------------------------------------***********");
    puts(req); //打印数据
    puts("***********-----------------------------------------------------------***********");

    for(i=0; i<cut; ++i){
        pid = fork(); //狂开进程了
        if(pid <= 0){
            sleep(1);//别让它太快完毕,父进程来不及收尸
            break;//结束子进程继续
        }
        ++rt;
    }        
    if(pid < 0)
        CERR_EXIT("child %d process create error!", i);
    if(pid == 0){ //子进程处理
        bcore(ips, req, wfd);
        exit(EXIT_SUCCESS);//子进程这里就结束了
    }
    //下面是父进程处理
    return rt;                    
}
/*
 * 定义加声明,放在一块
 */
static int __run(void)
{
    static union {
        unsigned short _s;
        unsigned char _cs[sizeof(unsigned short)];
    } __ut = { 1 };
    return __ut._cs[0] == 0;
}

/*
 * 声明和定义分开
 */
 extern void start(void);
 //下面是定义部分
 void
 start(void)
 {
     puts("你好!");
 }
//默认全局标识, 控制开关
volatile int v_timer = 0;

//闹钟信号,当它启动那一刻就表示可以退下了.
static void __alarm(int sig)
{
    v_timer = 1;
}

流量差不多,可能和网速有关,请求界面数挺多的这一个界面不错,可能是纯静态的. 对于详细查看为何失利,可以在笔录 failed++的时候打印日志看看,

成立管道,调用多进程处理函数,汇总最终结果.注意一点是打开的管道最后索要团结关闭.(可能这边有坑),回头看一下,代码其实

a. 拼接请求报文 , 解析

中级发送了一个alarm延时发送SIGALRM 信号,还有一个信号容易混淆视听,是SIGCLD信号 子进程退出时候给父进程发送.

下边代码自己多看几次写三遍,可以帮忙您领悟Linux中广大基础概念,例如 信号,多进程, 管道,socket,中断,

首先部分头文件,阐明解析

为了要拿到外人的称扬与微笑,我心惊肉跳地将协调套入所有的格局,所有的管束。

编译代码如下

webtest.c

第二有的挨家挨户,定义解析

 

2.说思路

具体参照

 

3.逐个实现

套路很多,都是历代编程王者,开创的各大武功的起手式,各大定式都可以就看你想拜入那么些门派,开始这些编程网游之旅.

尤为详细关于HTTP协议分析的,可以参考我面前的连续,HTTP协议简单解析.

 

 

 

引言

终极还有个 开启多进程的函数代码

首选看下边一个操作图,先请求百度尝试

/*
 * 请求链接主机,根据ip或url
 *
 * host    : url地址
 * port : 请求的端口号
 */
int 
contweb(const char* host, int port)
{
    int sd;
    in_addr_t ia;
    struct sockaddr_in sa = { AF_INET };    
    struct hostent *hp;

    ia = inet_addr(host);
    if(ia != INADDR_NONE)
        memcpy(&sa.sin_addr, &ia, sizeof(ia));
    else {
        hp = gethostbyname(host);
        if(hp < 0){
            CERR("gethostbyname %s error!", host);
            return -1;
        }
        memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);    
    }
    if((sd=socket(PF_INET, SOCK_STREAM, 0))<0){
        CERR("socket SOCK_STREAM");
        return sd;
    }    

    //连接主机
    sa.sin_port = htons(port);
    if(connect(sd, (struct sockaddr*)&sa, sizeof sa)<0){
        CERR("connect sd:%d error!", sd);
        return -1;
    }

    return sd;    
}

也正如好精通,先凑合请求串,再打开多进程挨个请求处理.

b. 发送请求报文 , 请求

中间 fdopen 是将 Linux文件讲述符和 C系统文件操作句柄转换.就是总括数据写入到管道中,管道 是
1进 0出.

  1. HTTP磋商简单介绍
http://www.cnblogs.com/biyeymyhjob/archive/2012/07/28/2612910.html

    //创建管道 进行测试, 代码比较杂,需要一些Linux基础知识,多练习
    if(pipe(pfds)<-1)
        CERR_EXIT("pipe create is error!");
//通过url拼接请求串
struct iport* 
brequst(const char* url, char rqs[], int len)
{
    static struct iport __ips;
    //请求的主机, 中间用的url, 临时数据
    const char *hurl, *tmp;        
    char c;
    int pt = 0;//临时用的int变量

    //简单检查参数检查,检查数组大小,url是否合法
    if(len<_INT_REQ || !url || !*url || strlen(url)>_INT_URL)
        CERR_EXIT("params url:%s, len[>=%d];%d error.", url, _INT_REQ, len);    
    //检测url是否是http请求的url,也比较简单,复杂检查要用正则表达式
    hurl = strstr(url, "://");
    if(!hurl || strncasecmp(url, "http", 4))
        CERR_EXIT("url is err [%s]!", url);
    //简单初始化
    memset(rqs, 0, len);    
    memset(&__ips, 0, sizeof __ips);

    //这种代码可以优化,用指针替代数组索引
    strcat(rqs, "GET ");
    hurl += 3; //跳过 "://"指向下一个字符

    //解析url 上是否有端口信息
    tmp = index(hurl, ':');
    if(tmp && tmp < index(hurl, '/')){ 
        strncpy(__ips.ip, hurl, tmp - hurl);
        //没有做安全检查
        while((c=*++tmp)!='\0' && c!='/'){
            if(c<='9' && c>='0'){
                pt = 10*pt + c - '0';
                continue;
            }
            CERR_EXIT("url is error [%s].", url);        
        }
    }    
    else{
        pt = 80; //默认端口
        //这句话意思 是 将 www.baidu.com/ 其中/之前的地方写入到 ip[]中
        strncpy(__ips.ip, hurl, strcspn(hurl, "/"));    
    }
    __ips.port = pt;    

    //将这些内容链接到rqs中
    strcat(rqs, hurl + strcspn(hurl, "/"));
    //采用HTTP1.1 协议
    strcat(rqs, " HTTP/1.1\r\n");
    //添加请求方
    strcat(rqs, "User-Agent: Happy is good.\r\n");
    //上面这样解析有点慢,最快的是整体for,但是更难维护
    strcat(rqs, "Host: ");
    strcat(rqs, __ips.ip);
    strcat(rqs, "\r\n");
    //拼接串最后,连接状态,完毕就关闭
    strcat(rqs, "Connection: close\r\n");
    //拼接空行, 上面可以优化
    strcat(rqs, "\r\n");

    //最终检测,是否字符串太长了
    if(rqs[len-1])
        CERR_EXIT("get http too len!");

    return &__ips;            
}

首要开启多进程的,依次调用 breques解析url 和 调用 bcore 处理socket
.

gcc -Wall -o webtest.out webtest.c

  这里我们先看下边一段代码格式,来打探C接口设计中有些潜规则.

     
在一想起间,才幡然发现,原来,我的终身的各样努力,可是只是为了周遭的人都对我满足而已。

 

其三有的主函数逻辑构建

后记

扯一点,socket编程大部分也一如既往业务代码,固定的套路固定的形式,写写也都会写了.但也挺辛勤了,随便一个简便的

再有一个是经过信号处理超时问题

发表评论

电子邮件地址不会被公开。 必填项已用*标注