[好文备份]高树的故事

Posted on Thu, 26 Aug 2010 12:08:16 -1100

        很久很久以前,在拉格朗日照耀下,有几座城:分别是常微分方城和偏微分方城这两座兄弟城,还有数理方城、随机过城。从这几座城里流出了几条溪,比较 著名的有:柯溪、数学分溪、泛函分溪、回归分溪、时间序列分溪等。其中某几条溪和支流汇聚在一起,形成了解析几河、微分几河、黎曼几河三条大河。

        河边有座古老的海森堡,里面生活着亥霍母子,穿着德布罗衣、卢瑟服、门捷列服,这样就不会被开尔蚊骚扰,被河里的薛定鳄咬伤。城堡 门口两边摆放着牛墩和道尔墩,出去便是鲍林。鲍林里面的树非常多:有高等代树、抽象代树、线性代树、实变函树、复变函树、数值代树等,还有长满了傅立叶, 开满了范德花的级树。。。。人们专门在这些树边放了许多的盖(概)桶,高桶,这是用来放尸体的,因为,挂在上面的人,太多了,太多了。。。。这些人死后就 葬在微积坟,坟的后面是一片广阔的麦克劳林,林子里有一只费马,它喜欢在柯溪喝水,溪里撒着用高丝做成的ε-网,有时可以捕捉到二次剩鱼。

        后来,芬斯勒几河改道,几河不能同调,工程师李群不得不微分流形,调河分溪。几河分溪以后,水量大涨,建了个测渡也没有效果,还是挂了很多人,连非交换代树都挂满了,不得不弄到动力系桶里扔掉。

        有些人不想挂在树上,索性投入了数值逼井(近)。结果投井的人发现井下生活着线性回龟和非线性回龟两种龟:前一种最为常见的是简单线性回龟和多元线性回龟,它们都喜欢吃最小二橙。

        柯溪经过不等市,渐近县和极县,这里房子的屋顶都是用伽罗瓦盖的,人们的主食是无穷小粮。

        极县旁有一座道观叫线性无观,线性无观里有很多道士叫做多项士,道长比较二,也叫二项士。线性无观旁有一座庙叫做香寺,长老叫做满 志,排出咀阵,守卫着一座塔方。一天二项士拎着马尔可夫链来踢馆,满志曰:“正定!正定!吾级数太低,愿以郑太求和,道友合同否?”二项士惊呼:“特真值 啊!”立退。不料满志此人置信度太低,不以郑太求和,却要郑太回归。二项式大怒在密度函树下展开标准分布,布里包了两个钗钗,分别是标准钗和方钗。满志见 状央(鞅)求饶命。二项式将其关到希尔伯特空间,命巴纳赫看守。后来,巴纳赫让其付饭钱,满志念已缴钱便贪多吃,结果在无参树下被噎死(贝叶 斯)。。。。。

几道积分不等式习题的解题思路

Posted on Sat, 21 Aug 2010 03:59:22 -1100

例题

例1. f(x)在(a,b)上可导, \underset{[a,b]}{max}f^{\,\prime}(x)=M 且有f(a)=0证明\int_{a}^{b}f(x)dx<=\frac{M}{2}(b-a)^{2}

例2. f(x)在(a,b)上导函数连续,\underset{[a,b]}{max}f^{\,\prime}(x)=M 且有f(a)=f(b)=0证明 \int_{a}^{b}f(x)dx<=\frac{M}{4}(b-a)^{2}

例3. f(x)在(a,b)上二阶导函数连续,\underset{[a,b]}{max}f^{\,\prime\,\prime}(x)=M 且有f(a)=f(b)=0证明\vert\int_{a}^{b}f(x)dx\vert<=\frac{M}{12}(b-a)^{3}
解题思路

• 拉格朗日中值定理

f(x)-f(a)=(x-a)f^{\,\prime}(\xi)

• 分部积分法

\int_{a}^{b}udv=uv\vert_{a}^{b}-\int_{a}^{b}vdu 对于上面这类题目还要进行一些配凑,如\int_{a}^{b}f(x)d(x-a)或者是\int_{a}^{b}f(x)d(x-b)

• 泰勒公式

若某f(x)在(a,b)上有n+1阶导数,且有x_{0}\epsilon(a,b)时的\forall x\epsilon(a,b)f(x)=\underset{i=0}{\overset{n}{\sum}}\frac{f^{\,\prime}(x_{0})}{i\,!}(x-x_{0})^{i}+\frac{f^{\,(n+1)}(\xi)}{(n+1)!}(x-x_{0})^{n+1}其中\xi在x到x_{0}之间

然而对于上面的几题,泰勒公式要向下面这样用,

\forall x\epsilon(a,b)在x点展开,对于某个t\epsilon(a,b),则f(t)可表示为f(t)=\underset{i=0}{\overset{n}{\sum}}\frac{f^{\,\prime}(x)}{i\,!}(t-x)^{i}+\frac{f^{\,(n+1)}(\xi)}{(n+1)!}(t-x)^{n+1}其中\xi在x到t之间

而在上述几题中,将已知的f(x)=0点带入(如令t=a或t=a,t=b联立求解),求得f(x)与其高阶导数的关系,联立方程组,比较不等式后可得出结果

另外,上面三道题都可用泰勒公式求解

[转]Ruby上使用飞信的例子

Posted on Thu, 12 Aug 2010 11:26:33 -1100

由于我一直想学习下ruby,但又苦于没有时间和精力,以致到现在也没能真正的上手.

今天狂论坛时发现了个ruby使用Fetion的例子,感觉蛮简练的,更想不到的是,

试了下,直接运行就可以了,会向自己的号码发送一条测试短信!

注意要把最后的账户密码改成自己正确的才能用

 

#!/usr/bin/ruby
# Using GPL v2
# Author:: DongYuwei(mailto:newdongyuwei@gmail.com)
# 更新部分内容应对2010年7月25日飞信升级 

require 'uri'
require 'net/http'
require 'net/https'
require "socket"
require 'rexml/document'
require 'digest/md5'
require 'digest/sha1'
require "iconv"

class Fetion
  def initialize(phone_num , password)
    @phone_num = phone_num;
    @password = password;
    @domain = "fetion.com.cn";
    @login_xml = '<args><device type="PC" version="0" client-version="3.5.2540" /><caps value="simple-im;im-session;temp-group;personal-group" /><events value="contact;permission;system-message;personal-group" /><user-info attributes="all" /><presence><basic value="400" desc="" /></presence></args>';
    self.init
  end
  
  def init
    doc = REXML::Document.new(self.get_system_config())
    sipc_proxy = ""
    doc.elements.each("//sipc-proxy") do |element|  # using regexp should be faster
      sipc_proxy = element.text
    end
    @SIPC = SIPC.new(sipc_proxy);
    
    sipc_url = ""
    #ssi-app-sign-in
    doc.elements.each("//ssi-app-sign-in-v2") do |element|
      sipc_url = element.text
    end
    @fetion_num = self.get_fetion_num(self.SSIAppSignIn(sipc_url))
  end
  
  def login()
    request1 = sprintf("R %s SIP-C/2.0\r\nF: %s\r\nI: 1\r\nQ: 1 R\r\nL: %s\r\n\r\n",@domain, @fetion_num, @login_xml.length)
    request1 = request1 + @login_xml
    server_response = @SIPC.request(request1)
    @nonce = server_response.scan(/nonce="(.*)"/)[0][0]
    
    request2 = sprintf("R %s SIP-C/2.0\r\nF: %s\r\nI: 1\r\nQ: 2 R\r\nA: Digest response=\"%s\",cnonce=\"%s\"\r\nL: %s\r\n\r\n", @domain, @fetion_num, self.get_response(), @cnonce, @login_xml.length)
    request2 = request2 + @login_xml
    @SIPC.request(request2)
  end
  
  def send_sms(phone, sms_text)
    sms_text = Iconv.iconv("UTF-8","UTF-8",sms_text)[0]
    request = sprintf("M %s SIP-C/2.0\r\nF: %s\r\nI: 2\r\nQ: 1 M\r\nT: tel:%s\r\nN: SendSMS\r\nL: %s\r\n\r\n",@domain, @fetion_num, phone, sms_text.length)
    request = request + sms_text
    @SIPC.request(request)
  end
  
  def send_sms_to_self(sms_text)
    sms_text = Iconv.iconv("UTF-8","UTF-8",sms_text)[0]
    request = sprintf("M %s SIP-C/2.0\r\nF: %s\r\nI: 2\r\nQ: 1 M\r\nT: %s\r\nN: SendCatSMS\r\nL: %s\r\n\r\n",@domain, @fetion_num, @uri, sms_text.length)
    request = request + sms_text
    @SIPC.request(request)
  end

  def logout()
    logout_request = sprintf("R %s SIP-C/2.0\r\nF: %s\r\nI: 1 \r\nQ: 3 R\r\nX: 0\r\n\r\n", @domain, @fetion_num)
    @SIPC.request(logout_request)
  end
  
  def get_response()
    @cnonce = Digest::MD5.hexdigest(rand.to_s)
    key = Digest::MD5.digest(@fetion_num + ":" + @domain + ":" + @password)
    h1 = Digest::MD5.hexdigest(key + ":" + @nonce + ":" + @cnonce).upcase
    h2 = Digest::MD5.hexdigest("REGISTER:" + @fetion_num).upcase
    return Digest::MD5.hexdigest(h1+":" + @nonce + ":" + h2).upcase
  end
  
  def get_system_config()
    uri = URI.parse("http://nav.fetion.com.cn/nav/getsystemconfig.aspx")
    http = Net::HTTP.new(uri.host, uri.port)
    params = sprintf('<config><user mobile-no="%s" /><client type="PC" version="3.5.2540" platform="W5.1" /><servers version="0" /><service-no version="0" /><parameters version="0" /><hints version="0" /><http-applications version="0" /><client-config version="0" /></config>',@phone_num)
    headers = {
      'Content-Type' => 'application/x-www-form-urlencoded'
    }
    resp = http.post(uri.path, params, headers)
    return resp.body
  end
  
  def SSIAppSignIn(url)
    uri = URI.parse(url)
    path = uri.path + "?mobileno=" + @phone_num + "&pwd=" + @password
    http = Net::HTTP.new(uri.host,uri.port)
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_NONE # turn off SSL warning
    resp, xml = http.get(path, nil)
    
    ok = "200"
    doc = REXML::Document.new(xml)
    doc.elements.each("//results") do|element|
           ok = element.attribute("status-code").value
       end
       if ok != "200"#421 verification picture?
            return self.SSIAppSignIn(url)
       end
    return xml
  end
    
  def get_fetion_num(xml)
    @uri = ""
    doc = REXML::Document.new(xml)
    doc.elements.each("//results/user") do |element|
      @uri = element.attribute("uri").value
    end 
    return @uri.scan(/sip:([0-9]+)@/)[0][0]
  end
end

class SIPC
  def initialize(sipc_addr)
    uri = sipc_addr.split(":")
    @socket = TCPSocket.new(uri[0], uri[1].to_i)
  end

  # send SIP request
  def request(sip_request)
    puts sip_request
    @socket.write_nonblock(sip_request)
    #select read_nonblock and rescue is the key
    IO.select [@socket]
    res = ""
    begin
      while chunk = @socket.read_nonblock(4096)
        res = res + chunk
      end
    rescue
            puts "Error: #{$!}"
    end
    puts res 
    return res 
  end
end

#for test
if __FILE__ == $0
    fetion = Fetion.new("136********","password")
    fetion.login()
    fetion.send_sms_to_self("test-ruby-fetion")
    #fetion.send_sms("mobileID","any sms")
end

出处的网页不小心关掉了,因为打开了一堆,印象中好像是CSDN的ruby版块.

SlickEdit v15.0.1.3[目前最新版本] 破解方法

Posted on Sat, 07 Aug 2010 01:25:50 -1100

在此,还是要感谢下zhiwei.li那位大牛,虽然他的博客还未更新,

但是基本的方法还是一样的,

假设你用的是IDA PRO这个工具

那么首先要导入vs.exe

经前面提到的那位大牛的分析,vs.exe其中有个函数块只要返回0,就可正常使用SlickEdit了

 

仔细研究了下发现,这个exe文件在调用vsSubscription函数会调用一段代码,

而这段代码可以通过查询"|== NOT FOR RESALE ==|"字符串,这时会展现出一块比较大的图片

不难发现有两处可以返回(retn),图片中左路无需额外关注,重点在右边,只要把右路最后的一块代码(有关返回值的)顶部的

mov ax,*** (不同的版本可能有所不同)改为 xor ax,ax 就可以啦!

 

当然,如果你觉得上面的叙述很麻烦,那么直接看下面

对应最新的v15.0.1.3 的Windows版本(v15.0.0.X版本及更早的偏移地址有所不同,不通用),

       将vs.exe 偏移地址 0x0000EC90 处的  mov eax, ebp  改成  xor eax,eax

       对应的 16进制 的值就是  将8B C5 改成  33 C0

Linux版本也是大同小异,这两天没时间去弄,以后有时间再弄,或是等别人弄了.....

JCOOP入门指南[04]

Posted on Sun, 18 Jul 2010 06:32:18 -1100

//修改 : 2010.7.25 修正自JCOOP 0.12之后[不包括0.12]SUB_CTOR宏接受三个参数,最后一个参数显示的指明共享部分的指针名称

 

//这两天对JCOOP核心的宏做了一些修改[本文编写时这个版本还未上传,不过也快了],主要是增加了些返回的状态,

//便于出错后的检测,不过因为用到的printf,所以某些超低端嵌入式平台如果使用最好做一些修改,以减小代码体积.

继前文介绍了JCOOP[sourceforge.net/projects/jcoop]类的设计方法[简化类,标准类,以及含有继承的类],

本篇介绍使用JCOOP中的"包含"

假设某个机车的核心是一个发动机,

我们可以这样设计这些类,

先设计一个发动机类,再从此类派生一个汽车类.

但也可采用下面的方法,

设计一个汽车类,在此类中包含一个指向原先设计好的发动机类的指针.

上面的例子中显然后者更和常理,绝大多数情况下,两种设计可以互相转化.

在良好的设计中应该尽可能的使用第二种设计方式,尽管这样会舍弃了一些语言本身的简易特性,但会使得代码更易修改,耦合度低,程序更加紧凑.....

下面的叙述还是采用上一篇中的代码,稍作修改,以演示如何在JCOOP中方便的使用"包含"的方式去设计一个类

先设计一个非常简单的Toy类

CLASS(Toy)
	unsigned char *name;
	SHARE(Toy)
		METHOD(void,playWithToy)(void *);
END_CLASS

然后我们假设每个小孩都有一个玩具,并且可以玩!

这样Baby类就变成了下面这样

CLASS(Baby)
	HAVE(Toy,toy);
	unsigned int age; //表示年龄的成员
	SHARE(Baby)
		HAVES(Toy,toy);
		METHOD(unsigned int,getAge)(void *);
		METHOD(void,setAge)(void *,unsigned int);
		METHOD(void,cry)(); //两个void分别对应返回值和参数
END_CLASS

而Baby的构造函数就变成了

CTOR(Baby) //构造函式
	SUB_CTOR(Toy,toy);   //注意,0.12后的版本应使用SUB_CTOR(Toy,toy,toy),这样可以指定对应共享部分指针的名称
	printf("Baby constructor called ... \n");
	ASSIGN(age,1); //赋值
	CTORS(Baby)
		SUB_CTORS(Toy,toy);
		printf("Baby share part constructor called ... \n");
		CONNECT(cry,Jcry); //链接到指定的函式
		CONNECT(getAge,JgetAge);
		CONNECT(setAge,JsetAge);
END_CTOR

其析构函数也相应的变成了

DTOR(Baby) //析构函式
	printf("Baby destructor called ... \n");
	UNASSIGN(age); //置零
	SUB_DTOR(Toy,toy);
	DTORS(Baby)
		printf("Baby share part destructor called ... \n");
		DISCONNECT(getAge);
		DISCONNECT(setAge);
		DISCONNECT(cry); //断开链接
		SUB_DTORS(Toy,toy);
END_DTOR

注意到

在CLASS中使用的是HAVE...HAVES的组合[要注意,共享和非共享部分的指针名称应保证一致,否则会报错]

在CTOR中使用的是SUB_CTOR...SUB_CTORS的组合
在DTOR中使用的是SUB_DTOR...SUB_DTORS的组合

下面列出完整的代码

#include <stdio.h>                                                                                                     
#include "jc_oop.h"


CLASS(Toy)
	unsigned char *name;
	SHARE(Toy)
		METHOD(void,playWithToy)(void *);
END_CLASS


CLASS(Baby)
	HAVE(Toy,toy);
	unsigned int age; //表示年龄的成员
	SHARE(Baby)
		HAVES(Toy,toy);
		METHOD(unsigned int,getAge)(void *);
		METHOD(void,setAge)(void *,unsigned int);
		METHOD(void,cry)(); //两个void分别对应返回值和参数
END_CLASS

CLASS(Boy)
	EXTD(Baby);
	unsigned int sex;
	unsigned char * favor;
	SHARE(Boy)
		EXTDS(Baby);
		METHOD(int,setFavor)(void *,const unsigned char *);
		METHOD(unsigned char *,getFavor)(void *);
		METHOD(void,cry)();  
END_CLASS

static void JplayWithToy(void *z){
	ZS(Toy);
	printf("\n>>>>>                           \n");
	printf("playing with %s\n",this->name);
	printf("                           <<<<<\n\n");
}
static void Jcry(){
	printf("baby is crying...\n");
}
static void JboyCry(){
	printf("boy is crying...\n");
}
static unsigned int JgetAge(void *z){
	ZS(Baby);
	return this->age;
}

static void JsetAge(void *z,unsigned int age){
	ZS(Baby);
	this->age=age;
}

static int JsetFavor(void *z,const unsigned char *str){
	ZS(Boy);
	unsigned int len=strlen(str)+1;
	if((this->favor=(unsigned char *)malloc(sizeof(unsigned char)*len))!=NULL){
		strncpy(this->favor,str,len);
		return 1;
	}
	return 0;
}

static unsigned char * JgetFavor(void *z){
	ZS(Boy);
	return this->favor;
}
 


CTOR(Toy) //构造函式
	printf("Toy constructor called ... \n");
	ASSIGN(name,"audi car mini-model"); //赋值
	CTORS(Toy)
		printf("Toy share constructor called ... \n");
		CONNECT(playWithToy,JplayWithToy);
END_CTOR

DTOR(Toy) //构造函式
	printf("Toy destructor called ... \n");
	UNASSIGN(name);
	DTORS(Toy)
		printf("Toy share destructor called ... \n");
		DISCONNECT(playWithToy);
END_DTOR

CTOR(Baby) //构造函式
	SUB_CTOR(Toy,toy);  //注意,0.12后的版本应使用SUB_CTOR(Toy,toy,toy),这样可以指定对应共享部分指针的名称	
        printf("Baby constructor called ... \n");
	ASSIGN(age,1); //赋值
	CTORS(Baby)
		SUB_CTORS(Toy,toy);
		printf("Baby share part constructor called ... \n");
		CONNECT(cry,Jcry); //链接到指定的函式
		CONNECT(getAge,JgetAge);
		CONNECT(setAge,JsetAge);
END_CTOR

DTOR(Baby) //析构函式
	printf("Baby destructor called ... \n");
	UNASSIGN(age); //置零
	SUB_DTOR(Toy,toy);
	DTORS(Baby)
		printf("Baby share part destructor called ... \n");
		DISCONNECT(getAge);
		DISCONNECT(setAge);
		DISCONNECT(cry); //断开链接
		SUB_DTORS(Toy,toy);
END_DTOR


CTOR(Boy)
	SU_CTOR(Baby);
	printf("Boy constructor called ... \n");
	ASSIGN(Baby.age,10);
	ASSIGN(sex,1);
	unsigned int len=strlen("play football")+1;
	this->favor=(unsigned char *)malloc(sizeof(unsigned char)*len);
	strncpy(this->favor,"play football\0",len);
	CTORS(Boy)
		SU_CTORS(Baby);
		printf("Boy share part constructor called ... \n");
		CONNECT(cry,JboyCry); //链接到指定的函式
		CONNECT(getFavor,JgetFavor);
		CONNECT(setFavor,JsetFavor);
END_CTOR



DTOR(Boy)
	printf("Boy destructor called ... \n");
	UNASSIGN(sex);
	free(this->favor);
	this->favor=NULL;
	SU_DTOR(Baby);
	DTORS(Boy)
		printf("Boy share part destructor called ... \n");
		DISCONNECT(cry); //断开链接
		DISCONNECT(getFavor);
		DISCONNECT(setFavor);
		SU_DTORS(Baby);
END_CTOR

	


int main(){
	NEW_BUNDLE(Boy,boy,bs);
	printf("the boy's age is %d\n",bs->Baby.getAge(boy));    
	bs->Baby.setAge(boy,15);
	printf("the boy's age is %d\n",bs->Baby.getAge(boy)); 
	bs->cry();	
	printf("the boy's favor is %s\n",bs->getFavor(boy)); 
	bs->setFavor(boy,"play basketball");
	printf("the boy's favor is %s\n",bs->getFavor(boy)); 
	
	bs->Baby.toy->playWithToy(boy->Baby.toy);
	 
	printf("\n***** now test the conversion *****\n\n"); 
	
	BabyShare *babys=NULL;
	babys=CAST_PTR(BabyShare,bs);
	babys->cry();
	Baby *baby=NULL;
	baby=CAST_PTR(Baby,boy);
	printf("the baby's age is %d\n",babys->getAge(baby)); 
	   
	DEL(Boy,boy);
	DELS(Boy,bs);
	return 0;
}

正确的运行结果如下,

Toy share constructor called ... 
Baby share part constructor called ... 
Boy share part constructor called ... 
Toy constructor called ... 
Baby constructor called ... 
Boy constructor called ... 
the boy's age is 10
the boy's age is 15
boy is crying...
the boy's favor is play football
the boy's favor is play basketball

>>>>>                           
playing with audi car mini-model
                           <<<<<


***** now test the conversion *****

baby is crying...
the baby's age is 15
Boy destructor called ... 
Baby destructor called ... 
Toy destructor called ... 
Boy share part destructor called ... 
Baby share part destructor called ... 
Toy share destructor called ... 

使用C语言来写网页

Posted on Mon, 12 Jul 2010 11:59:59 -1100

前面的几篇文章简单介绍了一些基础知识,

本文给出一个具体的实例,

先说明一下

测试环境是xampp套件(apache)+win32

开发工具是SlickEdit+Mingw

 

下面的文字主要介绍,用C语言[CGI]捕获html表单传递的信息.

其实和PHP,PERL类似,简单的方法就是环境变量的获取

[常用的环境变量,我前面的文章已经罗列了一些,这里就不多说了]

在C语言中,环境变量需要通过

	char *  getenv (const char *)

这个函数来获取,使用时需要包含stdlib.h这个头文件

有了这个函数,其它的就很简单了,写一个html的表单,比如

	<form name="input" action="../cgi-bin/test.exe" method="post">
Username: 
<input type="text" name="user" />
<input type="submit" value="Submit" />
</form>

注意 : action指向所需可执行文件[win下自然是exe了,linux下管用.cgi的后缀]

当然还有一个前提,就是Apache的CGI功能必须打开,这个配置很简单的,过阵子有空了再总结,这里不多罗嗦.

如果我们,输入了一些字符,点击提交后[假设那个test.exe里面用getenv捕获了某个环境变量,并打印出来],

会发现和我们想象的有些差异,

这里简单说明一下,

        1.最常见的疑问是html中的转义字符串,命令行中的\n或是\n\r到html里就应该用</br>,类似的还有一些

        2.如果我们输入的有空格,那么返回时编程了'+'号

        3.如果我们输入一个中文词组[假定GB2132编码]--"你好",那么返回的是 "%C4%E3%BA%C3"

        4.其它没有总结的......(哈哈)

1的话自己注意下就好,2和3可以写一个简单的函数避免这些问题,比如像下面这样

void   decode(unsigned char *src , unsigned char *dst)
{
	unsigned int len=0;
	unsigned int i=0,j=0;

	len=strlen(src);
	while (i<len) {
		if (*(src+i) == '+') {
			*(dst+j) = ' ';
		} else if (*(src+i) == '%') {
			unsigned int code;    
			if (sscanf(src+i+1,"%2x",(unsigned int *)&code)!=1) {
				code=(unsigned int)'?';
			}
			*(dst+j)=(unsigned char)code;
			i+=2; 
		} else{
			*(dst+j)=*(src+i);
		}
		++i;
		++j;
	} 
	*(dst+j)='\0';  
}    

啰嗦的就到这里,下面给出完整的测试用例[关于环境变量的意义,见我前文的总结]

#include<stdio.h>
#include<stdlib.h>    
 
void   decode(unsigned char *src , unsigned char *dst)
{
	unsigned int len=0;
	unsigned int i=0,j=0;

	len=strlen(src);
	while (i<len) {
		if (*(src+i) == '+') {
			*(dst+j) = ' ';
		} else if (*(src+i) == '%') {
			unsigned int code;    
			if (sscanf(src+i+1,"%2x",(unsigned int *)&code)!=1) {
				code=(unsigned int)'?';
			}
			*(dst+j)=(unsigned char)code;
			i+=2; 
		} else{
			*(dst+j)=*(src+i);
		}
		++i;
		++j;
	} 
	*(dst+j)='\0';  
}    



int   main()    
{    
	unsigned char *env;

	long len;

	printf("%s\n\n", "Content-Type:text/html;charset=gb2312");


	env=getenv("CONTENT_LENGTH");
	printf("CONTENT_LENGTH : %s</br>",env);

	env=getenv("DOCUMENT_ROOT");
	printf("DOCUMENT_ROOT : %s</br>",env);

	env=getenv("HTTP_REFERER");
	printf("HTTP_REFERER : %s</br>",env);

	env=getenv("HTTP_USER_AGENT");
	printf("HTTP_USER_AGENT : %s</br>",env);

	env=getenv("PATH_INFO");
	printf("PATH_INFO : %s</br>",env);

	env=getenv("PATH_TRANSLATED");
	printf("PATH_TRANSLATED : %s</br>",env);

	env=getenv("QUERY_STRING");
	printf("QUERY_STRING : %s</br>",env);

	env=getenv("REMOTE_ADDR");
	printf("REMOTE_ADDR : %s</br>",env);

	env=getenv("REMOTE_ADDR");
	printf("REMOTE_ADDR : %s</br>",env);

	env=getenv("REMOTE_HOST");
	printf("REMOTE_HOST : %s</br>",env);

	env=getenv("REQUEST_METHOD");
	printf("REQUEST_METHOD : %s</br>",env);

	env=getenv("SCRIPT_NAME");
	printf("SCRIPT_NAME : %s</br>",env);

	env=getenv("REQUEST_URI");
	printf("REQUEST_URI : %s</br>",env);

	env=getenv("SERVER_NAME");
	printf("SERVER_NAME : %s</br>",env);

	env=getenv("SERVER_PORT");
	printf("SERVER_PORT : %s</br>",env);

	unsigned char oriData[500];
	unsigned char data[500];
	fgets(oriData,500,stdin);
	printf("original data : %s , %d</br>",oriData,strlen(oriData)  );
	decode(oriData,data);
	printf("data : %s , %d</br>",data,strlen(data)  );

	return   0;    
}    

对应的html表单的代码前面贴过了,就不重复贴了,

假设我们在表单中填上"你好"这个词组,那么当我们点击提交按钮后,

如果配置正确的话,浏览器会像我们返回类似如下的字串,

CONTENT_LENGTH : 17
DOCUMENT_ROOT : E:/xampp/htdocs
HTTP_REFERER : http://localhost/test.html
HTTP_USER_AGENT : Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6
PATH_INFO : (null)
PATH_TRANSLATED : (null)
QUERY_STRING :
REMOTE_ADDR : 127.0.0.1
REMOTE_ADDR : 127.0.0.1
REMOTE_HOST : (null)
REQUEST_METHOD : POST
SCRIPT_NAME : /cgi-bin/test2.exe
REQUEST_URI : /cgi-bin/test2.exe
SERVER_NAME : localhost
SERVER_PORT : 80
original data : user=%C4%E3%BA%C3 , 17
data : user=你好 , 9

HTTP报文实例

Posted on Mon, 12 Jul 2010 00:43:03 -1100

本文整理自网络,原始链接不知何处........

 

在罗列具体的实例之前,先啰嗦几句概念性的东西.

GET,POST,SOAP都是基于HTTP协议的,但是,

POST 是被设计用来向上放东西的,而GET是被设计用来从服务器取东西的,

GET也能够向服务器传送较少的数据,而Get之所以也能传送数据,

只是用来设计告诉 服务器,你到底需要什么样的数据.

POST的信息作为HTTP 请求的内容,而GET是在HTTP 头部传输的.

当然数据传送量上,POST自然要多些...

SOAP是依赖于HTTP POST模式实现的,它遵循一种特殊的xml消息格式
在SOAP中,Content-type设置为: text/xml,任何数据都可以xml化

具体看以下HTTP的格式

发送

<request line>

<headers>

<blank line>

[<request-body>]

接收

<status line>

<headers>

<blank line>

[<response-body>]

在响应中唯一真正的区别在于第一行中用状态信息代替了请求信息。状态行(status line)通过提供一个状态码来说明所请求的资源情况。

而常用的状态码如下

◆200 (OK): 找到了该资源,并且一切正常。
◆304 (NOT MODIFIED): 该资源在上次请求之后没有任何修改。这通常用于浏览器的缓存机制。
◆401 (UNAUTHORIZED): 客户端无权访问该资源。这通常会使得浏览器要求用户输入用户名和密码,以登录到服务器。
◆403 (FORBIDDEN): 客户端未能获得授权。这通常是在401之后输入了不正确的用户名或密码。
◆404 (NOT FOUND): 在指定的位置不存在所申请的资源。

 

 

下面仅是HTTP中最常用的GET和POST方法几个实例,以及基于POST的SOAP方法

GET 方法

发送:

GET /DEMOWebServices2.8/Service.asmx/CancelOrder?UserID=string&PWD=string&OrderConfirmation=string HTTP/1.1
Host: api.efxnow.com

接收:

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<objPlaceOrderResponse xmlns="https://api.efxnow.com/webservices2.3">
<Success>boolean</Success>
<ErrorDescription>string</ErrorDescription>
<ErrorNumber>int</ErrorNumber>
<CustomerOrderReference>long</CustomerOrderReference>
<OrderConfirmation>string</OrderConfirmation>
<CustomerDealRef>string</CustomerDealRef>
</objPlaceOrderResponse>

注意其中没有实质的内容,自然也没有CONTENT-LENGTH,所以在CGI中若是GET方法发送的报文,通过环境变量获得的值为NULL

特别要注意其中的空行,之前是报文头,之后是报文的实际内容,下面的POST方法,发送时也有类似的规则

POST方法

发送

POST /DEMOWebServices2.8/Service.asmx/CancelOrder HTTP/1.1
Host: api.efxnow.com
Content-Type: application/x-www-form-urlencoded
Content-Length: length

UserID=string&PWD=string&OrderConfirmation=string

接收

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<objPlaceOrderResponse xmlns="https://api.efxnow.com/webservices2.3">
<Success>boolean</Success>
<ErrorDescription>string</ErrorDescription>
<ErrorNumber>int</ErrorNumber>
<CustomerOrderReference>long</CustomerOrderReference>
<OrderConfirmation>string</OrderConfirmation>
<CustomerDealRef>string</CustomerDealRef>
</objPlaceOrderResponse>

最后再介绍一种基于POST的方法

SOAP方法(soap 1.2)

发送

POST /DEMOWebServices2.8/Service.asmx HTTP/1.1
Host: api.efxnow.com
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
    <CancelOrder xmlns="https://api.efxnow.com/webservices2.3">
      <UserID>string</UserID>
      <PWD>string</PWD>
      <OrderConfirmation>string</OrderConfirmation>
    </CancelOrder>
</soap12:Body>
</soap12:Envelope>

回复

HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
    <CancelOrderResponse xmlns="https://api.efxnow.com/webservices2.3">
      <CancelOrderResult>
        <Success>boolean</Success>
        <ErrorDescription>string</ErrorDescription>
        <ErrorNumber>int</ErrorNumber>
        <CustomerOrderReference>long</CustomerOrderReference>
        <OrderConfirmation>string</OrderConfirmation>
        <CustomerDealRef>string</CustomerDealRef>
      </CancelOrderResult>
    </CancelOrderResponse>
</soap12:Body>
</soap12:Envelope>          

 

另外要补充说明的是,上面例子中报文头部分都比较简单,还有一些特别的属性可以根据需要添加,

比如要求服务器自动断开链接等功能就可以通过一些属性来设置

再举两个例子

GET发送

GET /books/?name=Professional%20Ajax HTTP/1.1
Host: www.wrox.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Connection: Keep-Alive

POST发送

POST / HTTP/1.1
Host: www.wrox.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 40
Connection: Keep-Alive
     (----此处空一行----)
name=Professional%20Ajax&publisher=Wiley

CGI中常用的环境变量

Posted on Sun, 11 Jul 2010 13:20:58 -1100

简单总结一下CGI中常用的环境变量,

当然我本初学,有一些也没用过,有一些仅是网上资料的汇总.

另外只是概要性的叙述,有一些变量在某些时候会返回空值,具体情况并未一一列出.

 

CGI中常用的环境变量

1. CONTENT_LENGTH

2. DOCUMENT_ROOT

3. HTTP_REFERER

4. HTTP_USER_AGENT

5. PATH_INFO

6. PATH_TRANSLATED

7. QUERY_STRING

8. REMOTE_ADDR

9. REMOTE_HOST

10. REQUEST_METHOD

11. SCRIPT_NAME

12. REQUEST_URI

13. SERVER_NAME

14. SERVER_PORT

概要1. 获取POST方法中传递实际信息的有效字节数
(CONTENT_LENGTH)

概要2. www目录信息获取
(DOCUMENT_ROOT)

概要3. 链接到当前页面的前一页面的 URL 地址。不是所有的用户代理(浏览器)都会设置这个变量,而

且有的还可以手工修改它。
因此,这个变量不总是真实正确的。
(HTTP_REFERER)

概要4. 客户端的名称和版本号
(HTTP_USER_AGENT)

概要5. http://www.test.com/index.php/foo/bar.html?c=index&m=search
我们可以得到 $_SERVER['PATH_INFO'] = ‘/foo/bar.html’,而此时 $_SERVER['QUERY_STRING'] =

'c=index&m=search';
(PATH_INFO)

概要6. 获取本文件的绝对路径
(PATH_TRANSLATED)

概要7. 获取IP地址
(REMOTE_ADDR)

概要8. 获取hostname
(REMOTE_HOST)

概要9. 获取请求方法,一般为GET,POST,HEAD
(REQUEST_METHOD)

概要10. # http://www.yoursite.com/example/  -- -- -- /
# http://www.yoursite.com/example/index.php -- -- -- /example/index.php
# http://www.yoursite.com/example/index.php?a=test -- -- -- /example/index.php?a=test
# http://www.yoursite.com/example/index.php/dir/test -- -- -- /example/index.php/dir/test
(REQUEST_URI)

概要11. # http://www.yoursite.com/example/  -- -- -- /example/index.php
# http://www.yoursite.com/example/index.php -- -- -- /example/index.php
# http://www.yoursite.com/example/index.php?a=test -- -- -- /example/index.php
# http://www.yoursite.com/example/index.php/dir/test -- -- -- /example/index.php
(SCRIPT_NAME)

概要12. 服务器的hostname或IP
(SERVER_NAME)

概要13. 服务器的监听端口
(SERVER_PORT)

概要14. http://www.test.com/index.php/foo/bar.html?c=index&m=search
我们可以得到 $_SERVER['PATH_INFO'] = ‘/foo/bar.html’,而此时 $_SERVER['QUERY_STRING'] =

'c=index&m=search';
注意:QUERY_STRING只是用于GET方法.
(QUERY_STRING)

 

JCOOP入门指南[03]

Posted on Fri, 09 Jul 2010 07:35:21 -1100

通过前面的介绍,相信本文的读者(具备一定编程基础)对JCOOP[sourceforge.net/projects/jcoop]有了大致的了解

本节依旧是以实例为主来说明如何使用JCOOP来模拟"继承"这一OO中重要的元素.

 

C语言中本没有类的概念,但其实有了结构体和函数指针,一个类的最基本功能是都可以实现的.前文中这些都已介绍了.

不过学过CPP和JAVA都知道,OO中必然有继承,这是C语言中所没有的,那么如何用C来实现呢?

准确说来C只能说是来模拟,而不能实现所有继承的功能,而模拟的方法自然还是用结构体[C中就那么点东西啊....]

具体见下面的示例

struct A{

        int a;

};

struct B{

        struct  A   stA;

        int b;

};

后面的结构体b包含了a结构体的一个实例.而类型转换时遵循位置靠前的原则.

在JCOOP中定义了如下一些宏来方便的实现继承这一功能,

类的声明中使用-->EXTD(共享部分使用EXTDS)

类的构造中使用-->SU_CTOR(共享部分使用SU_CTORS)

类的析构中使用-->SU_DTOR(共享部分使用SU_DTORS)

具体可以看下面的代码[如果感觉下面的代码仍有些怪异,请阅读前面相关JCOOP的文章]

 

#include <stdio.h>                                                                                                     
#include "./include/jc_oop.h"


CLASS(Baby)
	unsigned int age; //表示年龄的成员
	SHARE(Baby)
		METHOD(unsigned int,getAge)(void *);
		METHOD(void,setAge)(void *,unsigned int);
		METHOD(void,cry)(); //两个void分别对应返回值和参数
END_CLASS

CLASS(Boy)
	EXTD(Baby);
	unsigned int sex;
	unsigned char * favor;
	SHARE(Boy)
		EXTDS(Baby);
		METHOD(int,setFavor)(void *,const unsigned char *);
		METHOD(unsigned char *,getFavor)(void *);
		METHOD(void,cry)();  
END_CLASS


static void Jcry(){
	printf("baby is crying...\n");
}
static void JboyCry(){
	printf("boy is crying...\n");
}
static unsigned int JgetAge(void *z){
	ZS(Baby);
	return this->age;
}

static void JsetAge(void *z,unsigned int age){
	ZS(Baby);
	this->age=age;
}

static int JsetFavor(void *z,const unsigned char *str){
	ZS(Boy);
	unsigned int len=strlen(str)+1;
	if((this->favor=(unsigned char *)malloc(sizeof(unsigned char)*len))!=NULL){
		strncpy(this->favor,str,len);
		return 1;
	}
	return 0;
}

static unsigned char * JgetFavor(void *z){
	ZS(Boy);
	return this->favor;
}
 




CTOR(Baby) //构造函式
	printf("Baby constructor called ... \n");
	ASSIGN(age,1); //赋值
	CTORS(Baby)
		printf("Baby share part constructor called ... \n");
		CONNECT(cry,Jcry); //链接到指定的函式
		CONNECT(getAge,JgetAge);
		CONNECT(setAge,JsetAge);
END_CTOR

DTOR(Baby) //析构函式
	printf("Baby destructor called ... \n");
	UNASSIGN(age); //置零
	DTORS(Baby)
		printf("Baby share part destructor called ... \n");
		DISCONNECT(getAge);
		DISCONNECT(setAge);
		DISCONNECT(cry); //断开链接
END_DTOR


CTOR(Boy)
	SU_CTOR(Baby);
	printf("Boy constructor called ... \n");
	ASSIGN(Baby.age,10);
	ASSIGN(sex,1);
	unsigned int len=strlen("play football")+1;
	this->favor=(unsigned char *)malloc(sizeof(unsigned char)*len);
	strncpy(this->favor,"play football\0",len);
	CTORS(Boy)
		SU_CTORS(Baby);
		printf("Boy share part constructor called ... \n");
		CONNECT(cry,JboyCry); //链接到指定的函式
		CONNECT(getFavor,JgetFavor);
		CONNECT(setFavor,JsetFavor);
END_CTOR



DTOR(Boy)
	printf("Boy destructor called ... \n");
	UNASSIGN(sex);
	free(this->favor);
	this->favor=NULL;
	SU_DTOR(Baby);
	DTORS(Boy)
		printf("Boy share part destructor called ... \n");
		DISCONNECT(cry); //断开链接
		DISCONNECT(getFavor);
		DISCONNECT(setFavor);
		SU_DTORS(Baby);
END_CTOR

	


int main(){
	NEW_BUNDLE(Boy,boy,bs);
	printf("the boy's age is %d\n",bs->Baby.getAge(boy));    
	bs->Baby.setAge(boy,15);
	printf("the boy's age is %d\n",bs->Baby.getAge(boy)); 
	bs->cry();	
	printf("the boy's favor is %s\n",bs->getFavor(boy)); 
	bs->setFavor(boy,"play basketball");
	printf("the boy's favor is %s\n",bs->getFavor(boy)); 


	printf("\n***** now test the conversion *****\n\n"); 
	
	BabyShare *babys=NULL;
	babys=CAST_PTR(BabyShare,bs);
	babys->cry();
	Baby *baby=NULL;
	baby=CAST_PTR(Baby,boy);
	printf("the baby's age is %d\n",babys->getAge(baby)); 
	   
	DEL(Boy,boy);
	DELS(Boy,bs);
	return 0;
}

运行时,会显示下面的字符,

Baby share part constructor called ... 
Boy share part constructor called ... 
Baby constructor called ... 
Boy constructor called ... 
the boy's age is 10
the boy's age is 15
boy is crying...
the boy's favor is play football
the boy's favor is play basketball

***** now test the conversion *****

baby is crying...
the baby's age is 15
Boy destructor called ... 
Baby destructor called ... 
Boy share part destructor called ... 
Baby share part destructor called ... 

上面这个实例实现了一个Boy类,该类继承了前面的Baby类[见前文],

这里仅简单说明以下几点,

    1.Boy中继承了Baby类,共享部分也是如此.

    2.Boy中类也实现了单独的cry方法,你可以将这种方式理解成函数的重写.

    3.类型转换时,因为上面程序中都是使用CAST_PTR宏,因为类都建立在堆上,我们只是用指向其的指针.

    4.如果最后调用babys->cry();那么还是打印baby is crying ......

    5.注意上面constructor和destructor调用的辅助文字仅仅在说明调用的次序,当然如果你改变它的位置,打印的位置也会有所改变.

    6.另外JboyCry()仅仅是因为两个类都放在一个文件中,为了避免重名才这样做.

 

 

 

JCOOP入门指南[02]

Posted on Thu, 08 Jul 2010 12:54:01 -1100

上一篇中用JCOOP[sourceforge.net/projects/jcoop]设计了一个最最简单的Baby类,但是如果都像这样做的话一旦类的规模增大,

每声明一个实例,有些时候就要额外的占用一定的空间[比如类方法使用的指针],

为了节约资源,在JCOOP中一个类其实包含了两部分,一部分存储每个实例的属性成员,

另一部分存储公共的变量,可以是共享变量也可以是公用的方法[这类似与C++中的虚表]

而其声明方式类似下面这样,

CLASS(A)

        ......//普通成员

        SHARE(A)

                ......//方法或共享成员

END_CLASS

而每个类的私有部分和公有部分通过一个名为share的指针(如果声明了公有部分则存在于私有部分,否则不存在)

指向公有部分.

类似的,类的构造和析构也有相应的宏CTOR...CTORS...END_CTORDTOR...DTORS...END_DTOR来声明.

具体见下面的代码,

 

#include <stdio.h>                                                                                                     
#include "./include/jc_oop.h"


CLASS(Baby)
	unsigned int age; //表示年龄的成员
	SHARE(Baby)
		METHOD(unsigned int,getAge)(void *);
		METHOD(void,setAge)(void *,unsigned int);
		METHOD(void,cry)(void *); //两个void分别对应返回值和参数
END_CLASS

static void Jcry(void *z){
	printf("baby is crying...\n");
}

static unsigned int JgetAge(void *z){
	ZS(Baby);
	return this->age;
}

static void JsetAge(void *z,unsigned int age){
	ZS(Baby);
	this->age=age;
}


CTOR(Baby) //构造函式
	printf("Baby constructor called ... \n");
	ASSIGN(age,1); //赋值
	CTORS(Baby)
		printf("Baby share part constructor called ... \n");
		CONNECT(cry,Jcry); //链接到指定的函式
		CONNECT(getAge,JgetAge);
		CONNECT(setAge,JsetAge);
END_CTOR

DTOR(Baby) //析构函式
	printf("Baby destructor called ... \n");
	UNASSIGN(age); //置零
	DTORS(Baby)
		printf("Baby share part destructor called ... \n");
		DISCONNECT(getAge);
		DISCONNECT(setAge);
		DISCONNECT(cry); //断开链接
END_DTOR

int main(){
	NEW_BUNDLE(Baby,baby,bs);
	printf("the baby's age is %d\n",bs->getAge(baby));    
	bs->cry(baby);
	bs->setAge(baby,3);
	printf("the baby's age is %d\n",bs->getAge(baby));    
	DEL(Baby,baby);
	DELS(Baby,bs);
	return 0;
}

这里要特别声明的是如果用ZS宏,第一个参数的声明应为void *z,这样才会正确的转换成相应的"this指针"

编译正确后,会输出如下,

Baby share part constructor called ... 
Baby constructor called ... 
the baby's age is 1
baby is crying...
the baby's age is 3
Baby destructor called ... 
Baby share part destructor called ... 

另外顺带要说一下NEW_BUNDLE这个宏,其相当于NEWS和NEW这两个宏的组合,第一次声明某个实例时使用该宏会更加简洁.

和前面讲到的CTORS和DTORS一样,那个末尾的S表示SHARE,也就是公有部分.

而程序中我们实际使用的是两个类型分别BabyShareBaby指针,其分别指向了两个在堆上创建的实例.

当然如果你正确的使用NEW和DEL等宏,那么一般不用过多关注堆上类所用内存的分配.