libuv学习

libuv 是重写了下libev,封装了windows和unix的差异性。
libuv的特点
非阻塞TCP套接字 socket?
非阻塞命名管道
UDP
定时器
子进程 fork?
通过 uv_getaddrinfo实现异步DNS
异步文件系统API uv_fs_*
高分辨率时间 uv_hrtime
正在运行程序路径查找 uv_exepath
线程池调度 uv_queue_work
TTY控制的ANSI转义代码 uv_tty_t
文件系统事件支持 inotify ReadDirectoryChangesW kqueue 马上回支持 uv_fs_event_t
进程间的IPC与套接字共享 uv_write2

事件驱动的风格:程序关注/发送事件,在事件来临时给出反应。
系统编程中,一般都是在处理I/O,而IO的主要障碍是网络读取,在读取的时候是阻塞掉的。标准的解决方案是使用多线程,每一个阻塞的IO操作被分配到一个线程。当线程block,处理器调度处理其他线程。
libuv使用了另一个方案,异步。操作系统提供了socket的事件,即使用socket,监听socket事件即可。

libuv简单使用 创建一个loop,关闭loop。
#include <stdio.h>
#include <stdlib.h>
#include <uv.h>

int main()
{
uv_loop_t *loop = malloc(sizeof(uv_loop_t));
uv_loop_init(loop);

printf("hello, libuv");

uv_run(loop, UV_RUN_DEFAULT);

uv_loop_close(loop);
free(loop);

return 0;
}

如果只需要一个loop的话,调用uv_default_loop就可以了。
tips:Nodejs中使用了这个loop作为主loop。
uv_loop_t *loop = uv_default_loop();

uv_run(loop, UV_RUN_DEFAULT);

uv_loop_close(loop);

Error
初始化或同步函数,会在执行失败是返回一个负数,可以通过uv_strerror、uv_err_name获得这个错误的名字和含义
I/O函数的回调函数会被传递一个nread参数,如果nread小于0,也代表出现了错误。

Handle & Request
libuv的工作建立在事件的监听上,通常通过handle来实现,handle中uv_TYPE_t中的type指定了handle监听的事件。
在uv.h中可以找到handle和request的定义
/* Handle types. */
typedef struct uv_loop_s uv_loop_t;
typedef struct uv_handle_s uv_handle_t;
typedef struct uv_stream_s uv_stream_t;
typedef struct uv_tcp_s uv_tcp_t;
typedef struct uv_udp_s uv_udp_t;
typedef struct uv_pipe_s uv_pipe_t;
typedef struct uv_tty_s uv_tty_t;
typedef struct uv_poll_s uv_poll_t;
typedef struct uv_timer_s uv_timer_t;
typedef struct uv_prepare_s uv_prepare_t;
typedef struct uv_check_s uv_check_t;
typedef struct uv_idle_s uv_idle_t;
typedef struct uv_async_s uv_async_t;
typedef struct uv_process_s uv_process_t;
typedef struct uv_fs_event_s uv_fs_event_t;
typedef struct uv_fs_poll_s uv_fs_poll_t;
typedef struct uv_signal_s uv_signal_t;

/* Request types. */
typedef struct uv_req_s uv_req_t;
typedef struct uv_getaddrinfo_s uv_getaddrinfo_t;
typedef struct uv_getnameinfo_s uv_getnameinfo_t;
typedef struct uv_shutdown_s uv_shutdown_t;
typedef struct uv_write_s uv_write_t;
typedef struct uv_connect_s uv_connect_t;
typedef struct uv_udp_send_s uv_udp_send_t;
typedef struct uv_fs_s uv_fs_t;
typedef struct uv_work_s uv_work_t;

/* None of the above. */
typedef struct uv_cpu_info_s uv_cpu_info_t;
typedef struct uv_interface_address_s uv_interface_address_t;
typedef struct uv_dirent_s uv_dirent_t;

handle是持久化的对象。在异步操作中,相应的handle有许多关联的request。
request是短暂性的,通常只维持一个回调的时间,一般对应handle的一个IO操作。request用来在初始函数和回调函数中传递上下文。
例如uv_udp_t代表了一个udp的socket,每一个socket的写入完成后,都有一个uv_udp_send_t被传递。

handle的设置
uv_TYPE_init(uv_loop_t*, uv_TYPE_t);

一个idle handle的使用例子 观察下它的生命周期
#include <stdio.h>
#include <uv.h>

int counter = 0;

void wait_for(uv_idle_t * handle)
{
counter++;

if (counter > 10e6)
{
uv_idle_stop(handle);
}
}

int main()
{
uv_idle_t idler;

uv_idle_init(uv_default_loop(), &idler);
uv_idle_start(&idler, wait_for);

printf("Idle......");

uv_run(uv_default_loop(), UV_RUN_DEFAULT);

uv_loop_close(uv_default_loop());

return 0;
}

参数传递
handle和request都有一个data域,用来传递信息。uv_loop_t也有一个相似的data域。

文件系统
简单的文件读写是通过uv_fs_*函数族和与之相关的uv_fs_t结构体完成的。
系统的文件操作是阻塞的,所以libuv在线程池中调用这些函数,最后通知loop。

如果没有指定回调函数,文件操作是同步的,return libuv error code。
异步在传入回调函数时调用,return 0。

获得文件描述符
int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb);
关闭文件描述符
int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
回调函数
void callback(uv_fs_t* req);
还有uv_fs_read uv_fs_write uv_fs_t构成了基本的文件操作

流操作使用uv_stream_t,比基本操作方便不少
uv_read_start uv_read_stop uv_write
流操作可以很好的配合pipe使用
pipe相关函数
uv_pipe_init uv_pipe_open uv_close

文件事件
uv_fs_event_t uv_fs_event_init uv_fs_event_start

网络
uv_ip4_addr ip为 0.0.0.0表示绑定所有接口 255.255.255.255是一个广播地址,意味着数据将往所有的子网接口发送,端口号0表示由操作系统随机分配一个端口
tcp
TCP是面向连接的字节流协议,因此基于libuv的stream实现
uv_tcp_t
服务器端创建流程
uv_tcp_init 建立tcp句柄
uv_tcp_bind 绑定
uv_listen 建立监听,当有新的连接到来时,激活调用回调函数
uv_accept 接收链接
使用stream处理数据以及与客户端通信

客户端
客户端比较简单,只需要调用uv_tcp_connect

udp
UDP是不可靠连接,libuv基于uv_udp_t和uv_udp_send_t
udp的流程与tcp类似

libuv提供了一个异步的DNS解决方案,提供了自己的getaddrinfo
配置好主机参数addrinfo后使用uv_getaddrinfo即可

调用uv_interface_addresses获得系统的网络信息

未完待续。

来源:http://luohaha.github.io/Chinese-uvbook/source/introduction.html

使用gyp

GYP(Generate You Project),生成IDE项目的工具,使用Python脚本写成,配置文件为JSON格式。

使用gyp需要两个环境,python和gyp。gyp可以直接在这里下载

git clone https://chromium.googlesource.com/external/gyp

一般下载到build/gyp

使用python将我们的gyp文件加载并运行起来

args中可以添加工程的配置文件,大概格式如下:

target_name:工程名

type: 工程类型

dependencies: 依赖文件夹

sources: 源文件

conditions:条件判断

msvs-settings:msvs额外设置

 

Windows 10 回收站中文件无法删除的解决

Windows 10系统回收站的某些文件无法删除,选择清空回收站的时候,虽然能听到清空的声音,但所有的文件都还在,回收站已经有几个G的文件无法清空,这样很浪费磁盘的空间,可以用下面的办法来处理。

1.选择显示隐藏目录
Windows10Setting

2.在查看中显示受系统保护的操作系统文件

Windows10Setting2

3.在显示出来的隐藏目录中找到回收站的目录"$Recycle.Bin"

Windows10Setting3

4.双击目录找到“回收站”目录,并且点击进入
Windows10Setting4

5.点击输入栏,显示当前目录的完整的路径
Windows10Setting5

6.复制显示出来的路径

Window10Setting6

7.在左下角的搜索输入框中输入"CMD",点击显示出来的"命令提示符",右击选择"以管理员身份运行"

Windows10Setting7

8.在打开的命令行中,切换到刚刚复制的目录中,执行"del * ",执行删除操作。

Windows10Setting8

Android Studio 2.1 Preview: ':app:transformClassesWithInstantRunForDebug' FAILED

升级到Android Studio 2.1 Preview版本后,编译的时候,报告如下错误:

解决方法为:

禁用“Instant Run option in Android Studio 2.0 Preview”

nDO8x

参考链接:


Android Studio 2.0 Preview: ':app:transformClassesWithInstantRunForDebug' FAILED

Android Studio 多Library单元测试(testCompile project(":A"))提示找不到依赖库中定义的类

工程布局


工程 network-api
-> src/main/java
-> src/test/java
工程 network-biz
-> src/main/java (依赖工程 network-api的 src/main/java 下的文件)
-> src/test/java (依赖工程 network-api的 src/main/java 下的文件)

 

当编写network-biz的测试用例的时候,在build.gradle中增加

此时会发现network-biz编写的测试用例是无法编译通过的,提示找不到类定义。

这个问题是由于Android Studio没有正确的处理testCompile project导致的,这个BUG在Android Studio 2.0.0 Beta7版本中才获得修复,目前使用Canary Channel升级到最新的Android Studio 2.1 Preview 1版本以后是可以修正这个问题的。

参考链接:


Gradle (Android) - Multiproject dependency missing in testCompile
issue 200952: Library modules not added to classpath for testsz

Android Studio 1.5 集成的Android Monitor 中Logcat日志丢失

Android Studio 1.5 中使用集成的Android Monitor中的Logcat查看设备返回的日志,如果日志打印稍微密集一点,就会出现中间的部分信息丢失的问题,当使用独立版本的Android Device Monitor查看日志的时候,日志是完整的。
这个问题的根源是由于Android Studio 1.5 中使用集成的Android Monitor存在BUG导致的,目前已知的解决方法是升级到Android Studio 2.0 Beta 版本,目前看到这个问题已经被修复。

JS-深拷贝

在JS中使用变量,使用=号拷贝,如

obj1 = obj2

是浅拷贝,即改变obj1内容的时候也会改变obj2.

有时候我们是不希望看到这种情况的,JS使用深拷贝有很多方法,介绍一个简单好用的

这种用法会破坏obj2的构造类型,但一般情况是足够了。

大批WordPress网站被渗透 ,成为DDOS攻击源

1456369411312.jpg!small

近日,Sucuri的安全研究人员发现,数万WordPress站点被利用于实施第7层DDos攻击。共有两万六千个不同的WordPress站点持续向同一个网站以每秒一万到一万一千次的频率发送HTTPS请求,最多时能达到两万次每秒。更严重是,如果Pingback功能默认开启,全球任何一个WordPress站点都可能被利用,成为DDos攻击网络的一个源头。

HTTP Flood是针对Web服务在第七层协议发起的大规模流量攻击,不仅可以直接导致被攻击的Web前端响应缓慢,还间接攻击到后端的Java等业务层逻辑以及更后端的数据库服务,增大它们的压力,甚至对日志存储服务器都带来影响。

建议所有基于Wordpress的网站尽快禁用Pingback。虽然无法保证网站免于遭受攻击,但会终止黑客利用您的网站来攻击其它目标。

最好的做法是,如果你确定不用pingbacks,就和xmlrpc一并关闭。如果需要使用,可以简单修改.htaccess文件,只允许白名单中的IP来存取文件。流行插件Jetpack也可用于流量监控。

14562244766558.png!small

WordPress的pingback服务可被DDoS攻击利用,这个漏洞早有披露,但至今仍有大量网站存在此问题,原因在于网站所有者很少刻意防止网站被僵尸网络捕获。而由于这种DDoS攻击中流量来自数千个不同IP,基于网络的防火墙也无法识别和拦截,只能限制每个IP地址的访问频率。

1456224508906.png!small

研究人员还发现,大多数实施攻击的源网站托管在知名VPS/云服务提供商:亚马逊的AWS、Digital Ocean、谷歌云、微软的Azure、HETZNER、OVH和Linode。

原文地址:Thousands of WordPress websites used as a platform to launch DDOS