epoll实现压测工具
代码:
/*
* g++ -o stress_test ./stress_test.cpp
*/ #include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h> #include <unistd.h>
#include <sys/types.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h> static const char *request = "GET / HTTP/1.1\r\nHost: 192.168.1.5\r\nConnection: keep-alive\r\n\r\n"; int setnonblocking(int fd)
{
int old_option = fcntl(fd, F_GETFL);
int new_option = old_option | O_NONBLOCK;
fcntl(fd, F_SETFL, new_option); return old_option;
} int add_fd(int epoll_fd, int fd)
{
struct epoll_event event;
event.events = EPOLLOUT | EPOLLET | EPOLLERR;
event.data.fd = fd;
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &event);
setnonblocking(fd);
} bool write_nbytes(int sockfd, const char *buffer, int len)
{
int bytes_write = ;
printf("write out %d bytes to socket %d\n", len, sockfd);
while()
{
bytes_write = send(sockfd, buffer, len, );
if (bytes_write == -)
{
printf("send failed, errno[%d], error[%s]\n", errno, strerror(errno));
return false;
}
else if (bytes_write == )
{
printf("send 0 bytes\n");
return false;
} len -= bytes_write;
buffer = buffer + bytes_write;
if (len <= )
{
return true;
}
}
} bool read_once(int sockfd, char *buffer, int len)
{
int bytes_read = ;
memset(buffer, '\0', len);
bytes_read = recv(sockfd, buffer, len, );
if (bytes_read == -)
{
printf("recv failed, errno[%d], error[%s]\n", errno, strerror(errno));
return false;
}
else if (bytes_read == )
{
printf("recv 0 bytes\n");
return false;
}
printf("read in %d bytes from socket %d\n", bytes_read, sockfd); return true;
} int start_conn(int epoll_fd, const char *ip, int port, int num)
{
struct sockaddr_in addr;
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(ip);
addr.sin_port = htons(port); socklen_t len = sizeof(addr);
for (int i = ; i < num; ++i)
{
sleep();
int fd = socket(AF_INET, SOCK_STREAM, );
if (fd == -)
{
printf("socket failed, errno[%d], error[%s]\n", errno, strerror(errno));
continue;
} if (connect(fd, (struct sockaddr*)&addr, len) == )
{
printf("build connection %d\n", i);
add_fd(epoll_fd, fd);
}
else
{
printf("connect failed, errno[%d], error[%s]\n", errno, strerror(errno));
continue;
}
}
} int close_conn(int epoll_fd, int fd)
{
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL); printf("close socket[%d]\n", fd);
close(fd);
} int main(int argc, char **argv)
{
if (argc != )
{
printf("usage:stress_test ip port num\n");
exit(-);
} int epoll_fd = epoll_create();
start_conn(epoll_fd, argv[], atoi(argv[]), atoi(argv[]));
epoll_event events[];
char buffer[];
while ()
{
int fds = epoll_wait(epoll_fd, events, , );
for (int i = ; i < fds; ++i)
{
int sockfd = events[i].data.fd;
if (events[i].events & EPOLLIN)
{
if (!read_once(sockfd, buffer, ))
{
close_conn(epoll_fd, sockfd);
} struct epoll_event event;
event.events = EPOLLOUT | EPOLLET | EPOLLERR;
event.data.fd = sockfd;
epoll_ctl(epoll_fd, EPOLL_CTL_MOD, sockfd, &event);
}
else if (events[i].events & EPOLLOUT)
{
if (!write_nbytes(sockfd, request, strlen(request)))
{
close_conn(epoll_fd, sockfd);
} struct epoll_event event;
event.events = EPOLLIN | EPOLLET | EPOLLERR;
event.data.fd = sockfd;
epoll_ctl(epoll_fd, EPOLL_CTL_MOD, sockfd, &event);
}
else if (events[i].events & EPOLLERR)
{
close_conn(epoll_fd, sockfd);
}
}
} return ;
}
epoll实现压测工具的更多相关文章
- Http压测工具wrk使用指南
用过了很多压测工具,却一直没找到中意的那款.最近试了wrk感觉不错,写下这份使用指南给自己备忘用,如果能帮到你,那也很好. 安装 wrk支持大多数类UNIX系统,不支持windows.需要操作系统支持 ...
- Http压测工具wrk使用指南【转】
用过了很多压测工具,却一直没找到中意的那款.最近试了wrk感觉不错,写下这份使用指南给自己备忘用,如果能帮到你,那也很好. 安装 wrk支持大多数类UNIX系统,不支持windows.需要操作系统支持 ...
- Http 压测工具 wrk 基本使用
Http 压测工具 wrk 基本使用 Intro wrk 是一款现代HTTP基准测试工具,能够在单个多核CPU上运行时产生显着负载.它将多线程设计与可扩展事件通知系统(如epoll和kqueue)结合 ...
- wrk压测工具使用
介绍分为四部分 1.wrk简述 2.wrk安装 3.wrk运行参数 4.wrk高级用法 1.wrk简述 当使用ab做压测的时候发现,ab的客户端消耗很大,而且测试时性能较差,测试redis,sprin ...
- 4. 堪比JMeter的.Net压测工具 - Crank 进阶篇 - 认识wrk、wrk2
目录 堪比JMeter的.Net压测工具 - Crank 入门篇 堪比JMeter的.Net压测工具 - Crank 进阶篇 - 认识yml 堪比JMeter的.Net压测工具 - Crank 进阶篇 ...
- web压测工具http_load原理分析
一.前言 http_load是一款测试web服务器性能的开源工具,从下面的网址可以下载到最新版本的http_load: http://www.acme.com/software/http_load/ ...
- [软件测试]网站压测工具Webbench源码分析
一.我与webbench二三事 Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的性能.Webbench ...
- python服务端多进程压测工具
本文描述一个python实现的多进程压测工具,这个压测工具的特点如下: 多进程 在大多数情况下,压测一般适用于IO密集型场景(如访问接口并等待返回),在这种场景下多线程多进程的区分并不明显(详情请参见 ...
- 内存压测工具Memtester
在做压力测试时,发现一个内存压测工具Memtester,可以随意设置内存占用大小,非常方便 下载地址:http://pyropus.ca/software/memtester/old-versions ...
随机推荐
- js中获取键盘事件【转】
<script type="text/javascript" language=JavaScript charset="UTF-8"> 2 docu ...
- Oracle临时表
1概念理解 ORACLE系统的临时表常被用于存放系统操作的中间数据,由于对临时的任何操作都不产生redo(但会因为修改undo而产生redo),所以临时表的数据操作效率一般都比较高.常用的临时表主要有 ...
- 大量查询SQL语句 实例
1.查看表结构语句:DESC 表名 2.查询所有列:select * from 表名 3.查询指定列:select 字段名 form 表名 4.查询指定行:SELECT * ...
- 【应用笔记】【AN004】VB环境下基于RS-485的4-20mA电流采集
版本:第一版作者:周新稳 杨帅 日期:20160226 =========================== 本资料高清PDF 下载: http://pan.baidu.com/s/1c1uuhLQ ...
- Redis主从在线互相切换
由于某些原因,我们可能需要将redis master更换机器,我们可以停机进行更换,但是那样可能影响到用户体验.本文简要操作进行不停机迁移. 系统环境 CentOS 6.3 x64redis-serv ...
- 【C51】UART串口通信
我们常需要单片机和其他模块进行通信,数据传输,常用的方式就是串口通信技术. 常用来 单片机<-->电脑, 单片机<-->单片机之间通信. 串行通信 versus 并行通信 并 ...
- android:layout_gravity 和 android:gravity 的区别
gravity 这个英文单词是重心的意思,在这里就表示停靠位置的意思. android:layout_gravity 和 android:gravity 的区别 从名字上可以看到,android:gr ...
- iOS/OS X线程安全的基础知识
处理多并发和可重入性问题,是每个库发展过程中面临的比较困难的挑战之一.在Parse平台上,我们尽最大的努力保证你在使用我的SDKs时所做的操作都是线程安全的,保证不会出现性能问题. 在这篇文章中我们将 ...
- php闭包实现函数的自调用,也是递归
php的闭包可能不常用,但是在某些场合之下还是可以考虑用php的闭包来实现某些功能的,比如递归,这里讲一下用php的闭包实现递归 //php闭包实现函数的自调用,也就是实现递归 function cl ...
- Android-Activity使用(2) -传值
一.简单传值 1.修改MainActivity protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedIns ...