在silverlight与防盗链的网站中提取音乐文件

[audio:http://www.seenthewind.com/./wp-content/uploads/2011/11/secret_base.mp3|titles=secret_base]

url: http://bz.5sing.com/941638.html
step:
1. 查看网页源码,发现mp3链接,无法下载,估计已经配置的防盗链。
2. 使用chrome打开,输入 about:cache,查找到mp3-url的缓存,另存为。
3. 打开播放器,不能播放,用vim打开,发现是http报文明文 (╯#-皿-)╯~~╧═╧
4. 查找到ID3标签(MP3文件的标志头),截取出真正的mp3,还不够,目前是十六进制字符串的表示,我们要把他们换算成二进制存起来。
5. 写了一个python,做字符串处理,提取出纯净的hex-string。

import os
fp = open('123.txt', 'r')
wp = open('secret_base.txt', 'w')
for line in fp:
    l = line.split()
    #print l
    for l_hex in l[1:17]:
        wp.write(l_hex)
        #print l_hex,
    #print ''
    #os.system('pause')

6. 然后把文件中的hex-string流转换成纯二进制保存,用python处理二进制不太舒服,换成C++。

#include 
#include 
#define READ_MAX 1024

unsigned char chartohex(unsigned char * data)
{
    unsigned char ret = 0x00;

    if (*data < 'a') 
        ret = ret+(*data - '0');
    else
        ret = ret+10+(*data - 'a');
    ret = ret << 4;

    data++;
    if (*data < 'a') 
        ret = ret+(*data - '0');
    else
        ret = ret+10+(*data - 'a');
    return ret;
}

int main()
{
    FILE * fpr, * fpw;
    fpr = fopen("secret_base.txt", "r");
    fpw = fopen("secret_base.mp3", "wb");

    unsigned char readbuffer[READ_MAX];
    unsigned char writebuffer[READ_MAX/2];

    int len, i;
    while ( len=fread(readbuffer, sizeof(unsigned char), READ_MAX, fpr) )
    {
        for (i=0; i

7. ok, 提取出来的音乐在文章开头。

发表在 C, C++, Python, 编程 | 标签为 , , , | 留下评论

2011年11月23日

景蓝花,湿衣雨;
岁安巷,守城铁。
口莫言,心自辩;
不想念,若待缘。

发表在 唠叨, 许愿墙 | 留下评论

Windows下的非阻塞socket编程初探

下午检查灰度部署的结果,突然系统有点延迟,原来是因为网络策略的变更,导致防火墙把socket的一个主连接挡住了。
虽然会自动切换到备连接,但是系统每隔5分钟会再去检查主连接是否恢复。

这个时候,由于防火墙挡掉的socket链接就会阻塞很长一段时间才会返回错误,需要修改。

因为在Linux下面的情况比较简单,提供一个下面的语句做参考。

setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); // 通过SO_SNDTIMEO来控制connect的超时时间

据表哥介绍,这个设置原本是用来设置发送超时的,不过Linux下面貌似会很”巧合”的把连接超时也搞定了。
Windows下面当然没这么简单,下面整理网上的一些资料,对windows下面的socket非阻塞链接做探讨。

写在前面:下面的程序在windows下编译需要链接ws2_32.lib/DLL

继续阅读

发表在 C++, Windows, 系统, 编程 | 标签为 , , | 留下评论

Unix 下信号相关知识(Signal, kill)

1. 文章参考APUE第10章

kill在*nux族中主要代表两类,一是在函数内部调用的kill函数,用于给其他进程发送signal。
函数原型 int kill(pid_t pid, int sig);)

二是在Shell执行的kill命令,用于给后台进程发送信号。(参考这里

至于9是什么,在*unix中,signal是一组整数。
参考这个头文件

例如:

#define SIGKILL		 9
#define SIGUSR1		10
#define SIGUSR2		12
#define SIGSTOP		19

上面代码展示的几个值是比较关键的。我们继续来谈。

聊完了kill, 就有必要知道程序是怎么处理信号的,因为是特别篇所以我懒得讲到中断什么的。。这里就讲一下怎么用signal覆盖或者无视中断。

程序调用signal()函数来自定义对信号的处理,他的原型是: void (*signal(int signo, void (*func)(int)))(int);

这个原型比较复杂,推荐把他看懂。 (看不懂参考这里

简单介绍一下。 首先我们看到 signal, 他的左边是(),右边是*, 说明他是一个返回*号的函数,参数是()里面的东西。

然后跳出 signal所在的括号看,void ()(int) 眼熟么,就像void (*p) (int) ,这是一个指向函数的指针,函数的参数是int。如此以来,signal返回的是一个指向函数的指针

说明signal返回的是一个函数指针,然后在看signal(这里),是 int signo, void(*func)(int) 眼熟么,第一个参数是int, 第二个参数是函数指针。

当然这是自我折腾的函数声明,其实人民也会这样定义它。

typedef void Signalfunc(int);

Signalfunc * signal(int, Signalfunc *);

好了,这回还看不懂。。。就去多读书孩子。。

说了那么多,signal可以做几件事情,我们关心的有:

1. 屏蔽对一些信号的响应,传入 Signalfunc = SIG_IGN

一般来说,SIG_IGN 的定义是: #define SIG_IGN (void (*)()) 1,我暂时没有找到他在头文件里的定义,有兴趣可以找找。

2. 修改对一些信号的响应,自己定义一个Signalfunc函数,传到signal接口里就行了。

要注意的事情是,参数 SIGKILL 和 SIGSTOP 不能覆盖或者屏蔽。

最后贴一段代码,测试signal函数

#include 
#include 

static void sig_usr(int);

int main()
{
    if (signal(SIGUSR1, sig_usr) == SIG_ERR)
        printf("can't catch SIGUSR1\n");
    if (signal(SIGUSR2, sig_usr) == SIG_ERR)
        printf("can't catch SIGUSR2\n");

    for (;;)
        sleep(1);
}

static void sig_usr(int signo)
{
    if (signo == SIGUSR1)
        printf("recevied SIGUSR1\n");
    else 
        if (signo = SIGUSR2)
            printf("recevied SIGUSR2\n");
        else
            printf("recevied signal %d\n", signo);
}

下班了,准备出趟门,对了SIGUSR1和SIGUSR2是系统默认给用户自定义的。

测试这个函数的方法是:
mattchen@ooxx:~/code/signal$ ./a.out &
[1] 15781
mattchen@ooxx:~/code/signal$ kill -USR1 15781
recevied SIGUSR1
mattchen@ooxx:~/code/signal$ kill -USR2 15781
recevied SIGUSR2
mattchen@ooxx:~/code/signal$ kill -9 15781

发表在 C, C++, Linux, 系统, 编程 | 标签为 , , | 留下评论

My Heart can wait

1. 看到俱乐部新的招新照片,音乐正好放到《那些花儿》。
2. 深圳的天气很好,每天穿短袖,睡觉盖大被子。
3. Leader是很有内涵的人,Mentor是技术大牛。
4. 有时候人会迷失方向,有时候人会不知道接下来怎么做,一局棋下到中局,再往前想10步都很艰难。
5. 将要完成实习生课题,保持进度,周四结题报告。
6. 然后过国庆节,请个假回学校一趟。
7. 看看爸爸妈妈。
8. 没有什么不可以。
9. My Heart can wait.

发表在 许愿墙 | 留下评论

Windows 捕获磁盘IO量与磁盘活动时间(util)

windows下的底层开发相对Linux比较不方便,这里对主题做一些讨论,和贴一些自己写的代码。
磁盘IO可以由NtQuerySystemInformation获得(2号操作符),这个方法比较轻松,之前的获取CPU使用率也是这样。
但是磁盘的活动时间无法由NtQuerySystemInformation函数查询,因为他并没有提供有关磁盘时间的信息,或者队列情况。(也可能是有,我没有在网上找到资料。)
此外有两种方法获得磁盘详细信息,一种是PDH方法,一种是更底层的DeviceIoControl方法。
第二种方法实现起来比较复杂,不做研究,这里展示PDH方法。

#include 
#include 
#include 
#include 
#include 

#pragma comment(lib, "pdh.lib")

CONST ULONG SAMPLE_INTERVAL_MS    = 1000;

PDH_STATUS Status;
HQUERY Query = NULL;
HCOUNTER Counter;
PDH_FMT_COUNTERVALUE DisplayValue;
DWORD CounterType;

void init()
{

	char CounterPathBuffer[] = "\\PhysicalDisk(*)\\% Idle Time";

	//
	// Create a query.
	//

	Status = PdhOpenQuery(NULL, NULL, &Query);
	if (Status != ERROR_SUCCESS) 
	{
		wprintf(L"\nPdhOpenQuery failed with status 0x%x.", Status);
		goto Cleanup;
	}


	//ZeroMemory(&CounterPathBuffer, sizeof(CounterPathBuffer));

	//
	// Add the selected counter to the query.
	//

	Status = PdhAddCounter(Query, CounterPathBuffer, 0, &Counter);
	if (Status != ERROR_SUCCESS) 
	{
		wprintf(L"\nPdhAddCounter failed with status 0x%x.", Status);
		goto Cleanup;
	}

	Status = PdhCollectQueryData(Query);
	if (Status != ERROR_SUCCESS) 
	{
		wprintf(L"\nPdhCollectQueryData failed with 0x%x.\n", Status);
		goto Cleanup;
	}

	//
	// Print counter values until a key is pressed.
	//
	return;
Cleanup:
	if (Query) 
	{
		PdhCloseQuery(Query);
	}

}

void wmain(void)
{
	init();

	while (!_kbhit()) 
	{
		Sleep(SAMPLE_INTERVAL_MS);

		Status = PdhCollectQueryData(Query);
		if (Status != ERROR_SUCCESS) 
		{
			wprintf(L"\nPdhCollectQueryData failed with status 0x%x.", Status);
		}


		Status = PdhGetFormattedCounterValue(Counter,
			PDH_FMT_DOUBLE,
			&CounterType,
			&DisplayValue);
		if (Status != ERROR_SUCCESS) 
		{
			wprintf(L"\nPdhGetFormattedCounterValue failed with status 0x%x.", Status);
			goto Cleanup;
		}

		double DBIOUseTime = DisplayValue.doubleValue;

		if (DBIOUseTime > 100) DBIOUseTime = 100;

		DBIOUseTime = 100 - DBIOUseTime;

		wprintf(L"%0.2f%%\n", DBIOUseTime);
	}

Cleanup:

	//
	// Close the query.
	//

	if (Query) 
	{
		PdhCloseQuery(Query);
	}
}

需要注意的是,PDH方法采集的磁盘活动时间信息,是即时演算的,如果程序本身的活动时间和负载较大,会出现自身干扰。
出现这种情况,可以考虑Sleep 一段时间后再试。

发表在 C++, Windows, 系统, 编程 | 标签为 , , | 一条评论

Windows 服务程序配置

目标:
1. 实现配置后台服务,使其自动启动。
2. 当程序down后,会自动启动。


/*主要流程*/

1. 判断是否已经是服务在运行(argv)
2. 如果是第一次执行,初始化服务:
	SC_HANDLE sc_handle=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
	if(sc_handle==NULL)
	{
		printf("OpenSCManager 安装失败\n");
		return -1;
	}
	char filename[1024]={0};
	//获取当前的绝对路径:
	::GetModuleFileName(NULL,filename,1024);
	cout<<"GetModuleFileName:"<
							
发表在 C++, Windows, 系统, 编程 | 标签为 , , , | 留下评论

Windows 下获取多核CPU使用率

工作时候写的Dome, 可以参考:

MSDN
讲解如何利用NT Native API获取NT系统的CPU使用率(支持多核)
Win32 SDK 获得多核心处理器使用率。
阅读更多查看代码

继续阅读

发表在 C, C++, Windows, 系统, 编程 | 3条评论

[APUE] dup 的小测试

#include 
#include 
#include 
#include 

int main()
{
    char a[10] = "std in\n";
    char b[10] = "std out\n";
    char c[10] = "std error\n";

    write(0, a, sizeof(a));
    write(1, b, sizeof(b));
    write(2, c, sizeof(c));
    return 0;
}

mattchen@ooxx:~/code/dup$ ./a.out 
std in
std out
std error
mattchen@ooxx:~/code/dup$ ./a.out 2>&1
std in
std out
std error
mattchen@ooxx:~/code/dup$ ./a.out 2>&1 >tmpfile
std in
std error
mattchen@ooxx:~/code/dup$ ./a.out >tmpfile 2>&1 
std in
发表在 C, Linux, 系统, 编程 | 标签为 , , | 留下评论

SHELL 编程代码阅读

1. $# 表示传入参数个数,例如 ./a.sh input_file 这里 $# == 1

2. $1 表示第一个传入的参数

3. [ -f "somefile" ] 判断是否是一个文件, 猜猜 [ ! -f "somefile" ] 是?

	PS:
	[ -x "/bin/ls" ] 判断/bin/ls是否存在并有可执行权限
	[ -n "$var" ]    判断$var变量是否有值
	[ "$a" = "$b" ]  判断$a和$b是否相等

4. cat $file | grep -v '^$' > $file.1 去掉空行

   grep -v '^$' 表示获得除空行以外的行 $file.1 表示临时文件

5. $? 上个命令的返回

	if [ $? -ne 0 ]; then  如果上个命令返回值不为0
	fi

6. if [ -z "'echo $LINE | grep -v ^$'" ]; then
  	continue
   -z表示字符串为空,这里的含义是检查空行或者全部由空格,制表符组成的行

7. TMP=$(echo $LINE|awk '{print $1}' 去LINE字符串中空格分割后的第一个值

8. SHELL 中可以定义函数,例如:

	Get_ans()
	{
	...
	}

	使用$1获得调用时后面传入的参数

9. expect ooxx.exp $IP $PORT $USER $PASSWD 
 
 使用expect脚本远程交互

参考链接:
shell编程简介(zz)
linux grep命令

发表在 Linux, 系统, 编程 | 留下评论