2015年9月2日星期三
PHP 安装扩展 pcntl, sockets, mbstring
2014年1月16日星期四
2012年8月9日星期四
PHP函数的形参,实参
function add_some_extra($args)
{
$args['b']= "bbb";
}
$arr['a']= "aaa";
add_some_extra($arr);
fb::log($arr);
>>>>>>>>>> output>>>>>>>>>>>>>>
引用传递参数--------------------------------------------------------------------------
function add_some_extra(&$args)
{
$args['b']= "bbb";
}
$arr['a']= "aaa";
add_some_extra($arr);
fb::log($arr);
>>>>>>>>>> output>>>>>>>>>>>>>>
默认参数(参数为object时, 碉堡了。。。)----------------------------------------
function add_some_extra($args)
{
$args->b ="bbb";
}
$obj->a = "aaa";
add_some_extra($arr);
fb::log($arr);
>>>>>>>>>> output>>>>>>>>>>>>>>
这个aObj会跟着变:
function aObj(&$a, &$b)
{
$a = $b;
}
$a = new StdClass;
$a->i = 1;
$b = new StdClass;
$b->i = 2;
aObj($a, $b);
$b->i = 3;
print $a->i;
这个aObj一点都不变,还是i=1:
方程式aObj() 跟命令行_command_not_changed_相当:
function aObj($a, $b)
{
$a = $b;
}
$a = new StdClass;
$a->i = 1;
$b = new StdClass;
$b->i = 2;
aObj($a, $b);
$b->i = 3;
print $a->i;
这个很详细的描述:
class testRefer{
public $obj ;
public function __construct(){
$obj = new StdClass;
}
public function test($a, $b, &$aRef, &$bRef)
{
//$a = $b; //$aOjb won't be changeed
//$a->i = 10; //$aOjb will be changeed to ->i=10
//$a->i = $b->i; //$aOjb will be changeed to ->i=2
//$a = clone $b; //$aOjb won't be changeed
//$aRef = $bRef; //$aOjb will always be changing follow bOjb
//$aRef = $b; //$aOjb will always be changing follow bOjb
//$aRef->i = 10; //$aOjb will be changeed to ->i=10
//$aRef->i = $bRef->i; //$aOjb will be changeed to ->i=2
//$aRef = clone $bRef; //$aOjb will be changeed to ->i=2
//$a = $bRef; //$aOjb won't be changeed
$this->obj = $b; // $testRefer->obj will always be changing follow bOjb
//$this->obj = $bRef; // $testRefer->obj will always be changing follow bOjb
}
}
$aOjb = new StdClass;
$aOjb->i = 1;
$bojb = new StdClass;
$bojb->i = 2;
$testRefer = new testRefer();
$testRefer->test($aOjb, $bojb,$aOjb, $bojb);
$bojb->i = 3;
var_dump($aOjb);
print '
';
var_dump($bojb);
print '
';
var_dump($testRefer->obj);
print '
';
普通变量测试-------------------------------------------------------------------
function a(&$a, &$b)
{
$a =& $b;
}
$a = 1;
$b = 2;
a($a, $b);
$b = 3;
print $a;
这里输出 a=1
function a2(&$a, &$b)
{
$a = $b;
}
$a = 1;
$b = 2;
a2($a, $b);
$b = 3;
print $a;
这里输出 a=2
方程式a() 跟以下命令行_command_not_changed_相当:
_command_not_changed_:
//a=1
$a = 1;
$b = 2;
$a1 =& $a;
$b1 =& $b;
$a1 = &$b1; //指向被改了
$b = 3;
这里输出 a=1
------------------------
//这个才会跟着变:
$a = 1;
$b = 2;
$a =& $b;
$b = 3;
print $a;
这里输出 a=1
2012年7月2日星期一
zendstudio 批量添加换行符
win:“\r\n”,0x0D0A;
linux:“\n”,0x0A;
mac:"\r",0x0D;
Zendstudio中用\r\n大量替换\r :
Find: \r
Replace with: \r\n
*Regular expressions
2012年2月3日星期五
PHP使用数据库永久连接方式操作MySQL的是与非
PHP 程序员 应该都知道连接MySQL数据库可以使用mysql_pconnect(永久连接)函数,使用数据库永久连接可以提高效率,但是实际应用中数据库永久连接往往会导致出现一些问题,通常的表现就是在大访问量的网站上时常发生断断续续的无法连接数据库的情况,出现类似"Too many connections in ..."的错误提示信息,重新启动服务器又正常了,但过不了一会儿又出现同样的故障。对于这些问题的成因,恐怕就不是每个人都能说清楚的了,虽然PHP文档里有一些相关资料,但是解释的并不浅显易懂,这里我厚着脸皮试图做一个简单的讨论,所述观点不见得全都正确,欢迎大家反馈意见。
首先看看数据库永久连接的定义: 永久的数据库连接是指在脚本结束运行时不关闭的连接。当收到一个永久连接的请求时。PHP 将检查是否已经存在一个(前面已经开启的)相同的永久连接。如果存在,将直接使用这个连接;如果不存在,则建立一个新的连接。所谓“相同”的连接是指用相同的用户名和密码到相同主机的连接。
PHP使用永久连接方式操作MySQL是有前提的:就是PHP必须安装为多线程或多进程Web服务器的插件或模块。最常见的形式是把PHP用作多进程Apache服务器的一个模块。对于一个多进程的服务器,其典型特征是有一个父进程和一组子进程协调运行,其中实际生成Web页面的是子进程。每当客户端向父进程提出请求时,该请求会被传递给还没有被其它的客户端请求占用的子进程。这也就是说当相同的客户端第二次向服务端提出请求时,它将有可能被一个不同的子进程来处理。在开启了一个永久连接后,所有不同子进程请求SQL服务的后继页面都能够重新使用这个已经建立的 SQL服务器连接。它使得每个子进程在其生命周期中只做一次连接操作,而非每次在处理一个页面时都要向 SQL 服务器提出连接请求。每个子进程将对服务器建立各自独立的永久连接。PHP本身并没有数据库连接池的概念,但是Apache有进程池的概念, 一个Apache子进程结束后会被放回进程池, 这也就使得mysql_pconnect打开的的那个mysql连接资源可以不被释放,而是依附在相应的Apache子进程上保存到了进程池中。于是在下一个连接请求时它就可以被复用。一切看起来似乎都很正常,但是在Apache并发访问量大的时候,如果使用mysql_pconnect,会由于之前的 Apache子进程占用的MySQL连接没有close, 很快使MySQL达到最大连接数,使得之后的请求可能得不到响应。
上 面的部分文字是摘抄自PHP文档,看起来可能还是有些文绉绉的不好理解,那么我就用大白话再举一个例子来说明问题: 假设Apache配置最大连接数为1000,MySQL配置最大连接数为100,当Apache服务器接到200个并发访问的时候,其中100个涉及到数据库访问,剩下的100个不涉及数据库访问,因为这个时候还不存在可用的数据库连接,所以这里面涉及到数据库访问的100个并发会同时产生100个数据库永久连接,达到了数据库最大连接数,当这些操作没有结束的时候,任何其他的连接都无法再获得数据库连接,当这些操作结束了,相应的连接会被放入进程池,此时Apache的进程池里就有了200个空闲的子进程,其中100个是带有数据库连接的,由于Apache会为访问请求随机的挑选空闲子进程,所以你得到的子进程很可能是不包含数据库连接的那100个中的一个,而数据库连接已经达到了最大值,你也不可能成功的建立新的数据库连接,唉,你便只好不停的刷新页面,哪个时候运气好,碰巧分配到了带有数据库连接的子进程,才能正常浏览页面。如果是大访问量的网站来说,任何时候都可能存在大量的并发,所以浏览者可能就会不停的发现无法连接数据库的现象了。 或许你会说,我们把Apache和MySQL的最大连接数调成一样大不就可以了么?是的,合理的调整这个最大连接数某种程度上会避免这个问题的发生,但是Apache和MySQL的负载能力是不同的,如果按照Apache的负载能力来设置,对于MySQL来说,这个最大连接数就偏大,会产生大量的 MySQL数据库永久连接,打个比方,就好像和平时代还要养活一个几百万的军队一样,其开销得不偿失;而如果按照Mysql的负载能力设置,对于 Apache来说,这个最大连接数就偏小,有点杀鸡牛刀的感觉,无法发挥Apache的最大效率。
所 以按照PHP手册上的介绍,只适合在并发访问不大的网站上使用数据库永久连接,但对于一个并发访问不大的网站来说,使用数据库永久连接带来的效率提高似乎没有太大的意义,从这个角度上来看,我觉得PHP中的数据库永久连接基本上是一个鸡肋的角色,如果你一定要使用数据库连接池的概念,可以尝试一下sqlrelay 或者Apache本身提供的mod_dbd ,说不定会有惊喜。
2012年1月31日星期二
Zend Studio代码提示工作不正常的解决办法
2011年9月15日星期四
Memcache
Installing Memcached and Libevent
I am going to demonstrate using my shared server on 1and1. This will work on any Linux server which you have shell access to (can be via SSH).
I will use '/kunden/homepages/13/d155370874/htdocs/' as my root directory, because that's the root of what I have access to on my shared server To find your working directory, use
--------------------------
$ pwd
----------------------------
Removing an old libevent
Removing libevent is easy:
-----------------------------------
# apt-get remove --purge libevent1
------------------------------------
Note: That's the number one on the end... it looks a lot like the letter L.
Now check to make sure everything is gone:
---------------------------------------------------
# locate libevent
/var/cache/apt/archives/libevent1_1.1a-1_i386.deb
---------------------------------------------------
First get via (wget) the latest version of libevent available. Then unzip it and install it. I use prefix to install it in my shared directory, because I don't have write access in the usual location for such stuff.
注意:在安装前, ./configure 要将安装路径设置到一个新的文件夹libevent中,而非现在的libevent-1.4.5-stable,否者make install 报错。
原因:不明
--------------------------------------------------------------------
$ wget http://www.monkey.org/~provos/libevent-1.4.5-stable.tar.gz
$ tar -zvxf libevent-*gz
$ cd libevent-*
$ ./configure --prefix=$HOME/libevent
$ make
$ make install
$ cd
---------------------------------------------------------------------
Then get Memcached and install giving it the directory where you installed libevent. (Note: on 1and1 I could only get version 1.1.12 to work; not the latest version; I don't know why)
I didn't have any problem using memcached-1.2.5 (latest at time of this writing) --Merles 18:59, 29 June 2008 (EDT)
----------------------------------------------------------------------
$ wget http://www.danga.com/memcached/dist/memcached-1.2.5
$ tar -zvxf memcached-*
$ cd memcached-*
$ ./configure --prefix=$HOME/memcached --with-libevent=$HOME/libevent
$ make
$ make install
-----------------------------------------------------------------------
Start Memcached
If your server gets restarted, you might have to redo these steps.
------------------------------------------------------------------
$ cd memcached #(the directory where you installed memcached)
$ cd bin
$ ldd memcached
------------------------------------------------------------------
That will output:
libevent-1.3b.so.1 => not found
libc.so.6 => /lib/tls/libc.so.6 (0x00a55000)
/lib/ld-linux.so.2 (0x00a3c000)
Now type (substuting where you installed libevent if needed):
--------------------------------------------------------------
$ export LD_LIBRARY_PATH=$HOME/libevent/lib:$LD_LIBRARY_PATH
$ ldd memcached
--------------------------------------------------------------
That will output: (Notice the path to libevent is now there)
libevent-1.3b.so.1 => /kunden/homepages/13/d155370874/htdocs/libevent-1.3b/lib/libevent-1.3b.so.1 (0x0061f000)
libc.so.6 => /lib/libc.so.6 (0x00a55000)
/lib/ld-linux.so.2 (0x00a3c000)
Start it up: This will start it up as a daemon (it will run in the background) on IP 127.0.0.1 on port 11000 using no more then 64 MB of RAM.
----------------------------------------------------
$ memcached -d -l 127.0.0.1 -p 11000 -m 64
----------------------------------------------------
Confirm that it it is working with
-----------
$ top
----------
Output should be:
24190 u3988386 18 2 24056 22M 248 S N 0.0 0.0 0:00 memcached
Adding PECL Memcache.so to 1&1
注:必须安装libevent pecl扩展和libevent 服务器端
Download PECL to your 1&1 account:
---------------------------------------------------
$ wget http://pecl.php.net/get/memcache-3.0.8.tgz
---------------------------------------------------
Extract the package:
---------------------------------------------------
$ tar xvzf memcache-3.0.8.tgz
---------------------------------------------------
Go into the directory:
---------------------------------------------------
$ cd memcache-pecl-3.0.8
---------------------------------------------------
Run phpize5.5:
---------------------------------------------------
$ phpize5.5
---------------------------------------------------
Change php-config to php-config5.5 in configure script:
---------------------------------------------------
$ sed -i 's/=php-config/=php-config5.5/g' configure
---------------------------------------------------
Run Configure:
---------------------------------------------------
$ ./configure
---------------------------------------------------
如果有configure: error: Cannot find php_session.h
添加--disable-memcache-session
---------------------------------------------------
$ ./configure --disable-memcache-session
---------------------------------------------------
对于libevent
---------------------------------------------------
$ ./configure --with-libevent=$HOME/libevent-2.0.22-stable/ --with-php-config=/usr/bin/php-config5.5
or if by compiling of source libevent with ./configure --prefix=$HOME/libevent do the following:
./configure --with-libevent=$HOME/libevent/ --with-php-config=/usr/bin/php-config5.5
---------------------------------------------------
Change include directives in Makefile:
--------------------------------------------------------------------
$ sed -i 's#-I/usr/local/include/php#-I/usr/include/php5#g' Makefile
注:打开 Makefile文件
改为:phpincludedir = Usage: /usr/local/bin/php-config [--prefix|--includes|--ldflags|--libs|--extension-dir|--version] [...] PHP_EXECUTABLE = Usage: /usr/local/bin/php-config [--prefix|--includes|--ldflags|--libs|--extension-dir|--version] [...] INCLUDES = -I/usr/include/php -I/usr/include/php/main -I/usr/include/php/TSRM -I/usr/include/php/Zend
phpincludedir = Usage: /usr/local/bin/php-config5 [--prefix|--includes|--ldflags|--libs|--extension-dir|--version] [...] PHP_EXECUTABLE = Usage: /usr/local/bin/php-config5 [--prefix|--includes|--ldflags|--libs|--extension-dir|--version] [...] INCLUDES = -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/TSRM -I/usr/include/php5/Zend
改所有的/usr/include/php 为 /usr/include/php5.5
--------------------------------------------------------------------
Run make and make test:
---------------------------------------------------
$ make
$ make test
---------------------------------------------------
Make new extensions folder for new extension to go in:
--------------------------------------------
$ mkdir ~/extensions
--------------------------------------------
Copy uploadprogress extension to new folder
------------------------------------------
$ cp .libs/memcache.so ~/extensions-php5.5/
------------------------------------------
Create new php.ini under your main folder (or under a single subfolder for just that application) to add new extension_dir then add this code to the file
------------------------------------------------------------------
extension_dir=/kunden/homepages/x/dxxxxxxxx/htdocs/extensions/
extension=memcache.so
-------------------------------------------------------------------
2011年8月30日星期二
segmentation fault with sprintf
int lines = 1234;
char *buffer;
sprintf(buffer, "Lines: %d", lines); // very bad!
Proper way:
int lines = 1234;
char *buffer;
buffer = new char[32];
sprintf(buffer, "Lines: %d", lines);
delete[] buffer;
Alternate proper way, using C allocation semantics way:
int lines = 1234;
char *buffer;
if((buffer = (char *)malloc(32)) != NULL)
sprintf(buffer, "Lines: %d", lines);
free(buffer);
2011年8月24日星期三
2011年7月5日星期二
PHP 中的 ==null;is_null();empty()
==null: 0, null, ''
//change to:
function is_emptystring_or_null($str) {
return (is_null($str) || ($str === ''));
}
is_null(): ===null
isset is_null ===null ==null empty
null | F | T | T | T | T |
true | T | F | F | F | F |
false | T | F | F | T | T |
0 | T | F | F | T | T |
1 | T | F | F | F | F |
\0 | T | F | F | F | F |
unset | F | T | T | T | T |
"" | T | F | F | T | T |
[] | T | F | F | T | T |
2011年5月5日星期四
applet授权数字签名【转】
1.假设你的需要压缩的类文件存在的包为:cn.mbq.test1和cn.mbq.test2
2.进入你的classes目录,在DOS窗口中执行命令:jar cf mytest.jar cn.mbq.test1 cn.mbq.test2
3.执行命令后你会在当前目录中找到mytest.jar文件,这个就是刚才生成的档案文件。你可以修改它的后缀为rar,然后使用winrar压缩程序打开它查看看是否正确。
jar -cvf MyApplet.jar class
打包文件夹下所有class jar -cf MyApplet.jar com\company\applet
二、使用keytool工具生成密匙库
1.keytool工具位于${java_home}/bin目录下;
2.在DOS窗口中执行命令:keytool -genkey -keystore mytest.store -alias mbq
注意:mytest.store 是你的密匙库的名称,可以随意修改,后缀请不要修改!
mbq 为别名,这个也可以改成自己的名称
3.执行上述命令后,DOS窗口中会提示你输入keystore的密码、你的姓名、组织单位等等信息。这里要注意的是输入密码请记住,后面要用到的。在最后,我们输入y确认信息。然后再直接回车设置mbq的主密码和store密码一致即可!
三、使用keytool工具导出签名时用到的证书
1.在DOS窗口中执行命令:keytool -export -keystore mytest.store -alias mbq -file mbq.cert
注意:mytest.store 就是第二步生成的密匙库名称
mbq 也是在第二步中我们指定的别名
mbq.cert 为我们生成的证书的名称,可以自己修改名称,注意后缀不要改
2.命令执行成功,我们会在当前目录下找到一个mbq.cert文件,这个就是我们刚才生成的证书。
四、使用jarsigner工具签名jar压缩文档
1.jarsigner工具位于${java_home}/bin目录下;
2.在当前DOS窗口中执行命令:jarsigner -keystore mytest.store mytest.jar mbq
注意:mytest.store 就是我们在第二步中生成的密匙库名称
mytest.jar 就是我们这第一步压缩的jar文档
mbq 是提供者的名称,我们这里设置为我们的别名
再运行的Applet就可以访问本地了
嵌入Applet部分的写法:
OBJECT对象中的CODEBASE指的路径是相对当前页面的路径,是可以有效的.最后部署的时候只需要签名后的jar包就可以了,其他的文件都不需要
关于Html嵌入Applet的问题
标签的属性介绍
属性 含义
Width Applet在Html页面上的宽度
Height Applet在Html页面上的高度
Name Applet在Html页面上的名称,用于区名一个Html页面上的多个Applet
Code Applet类名,必须带后缀”class”当没有属性archive时,直接写类名当有属性archive时,必须带包名
Codebase Applet的类相对路径,相对于Html页面位置
Archive Applet所在Jar包的文件名
标签< PARAM>的属性介绍
属性 含义
Name Applet传入的参数名
Value Applet传入的参数值
当Applet 为一个Class类文件嵌入的写法
属性Code ==========Applet类名,必须带后缀名
属性CodeBase ---------------Class类文件相对于Html页面的相对路径
Applet为一个JAR包,嵌入Html的写法
属性Code ==========Applet类名,包括包名
属性CodeBase ----------------Applet JAR包相对于Html页面的相对路径
属性Archive -----------------------Applet Jar包文件名
对于需要授权的applet(如读取本地文件),进行数字签名后,在paint方法中可以读取本地文件,但放在自定义的方法中,通过js调用自定义的方法还是提示没有权限,不解
可以通过再建立一个线程类,在run方法中调用applet中读取本地文件的自定义方法,线程类可以在applet中的初始化方法init中建立,applet类当做参数传给线程类
JavaScript访问Applet
//JavaScript访问Applet属性
window.document.appletName.appletField (属性必须是public的,"window.document."也可以不写)
/JavaScript访问Applet方法
window.document.appletName.appletMethod (方法必须是public的,"window.document."也可以不写)
var result = appletName.appletMethod ("param"); //调用applet带参数的方法和有返回值的方法
打包jar文件必须把applet引用到的类全部打包进去,否则调用方法会找不到(对象不支持此属性或方法),或一些其他错误
文章转自:http://blog.csdn.net/zhaoyh82/archive/2009/05/19/4200897.aspx
如何突破Applet的安全限制
Java Applet 是用Java 语言编写的小应用程序,这些程序是直接嵌入到页面中,
由支持Java的浏览器(IE 或 Nescape等)解释执行,能够产生特殊效果的程序。
它可以大大提高Web页面的交互能力和动态执行能力。包含Applet的网页被称为Java-powered页,可以称其Java支持的网页。
二、Applet用法
1.确定包含在HTML文档中的Java Applet程序已经存在;
2.调用"applet"格式(以Java01.class 为例)
A.code属性:定义调用的Java Applet 程序名,要注意全名和大小写。
B.codebase属性:定义Java Applet 程序的路径或地址(URL),当Java Applet与HTML文档不在同一目录时用它来定位,
上面调用格式中codebase="javam"说明该Java Applet程序存放在"javam"目录里
(建议将Java Applet 程序和HTML文档放在同一目录)。
C.width和height属性:给出Java Applet程序显示区域以像素为单位的宽度和高度。
D.vspace和hspace属性:用来设置以像素为单位的竖直和水平边距。
E.align属性:控制Java Applet的对齐方式,取值如下:
left(屏幕的左边)
right(屏幕的右边)
top(与该行中最高项的顶部对齐)
texttop(与该行文本的顶部对齐)
middle(使该行的基线与该Java Applet程序显示域的中间对齐)
absmiddle(使该行的中间与该Java Applet程序显示域的中间对齐)
baseline(使该行的基线与该Java Applet的程序显示域的底部对齐)
bottom(使该行的基线与该Java Applet的程序显示域的底部对齐)
absbottom(使该行的底部与图像的底部对齐)
F.archive属性:用逗号分隔的归档文件列表(HTML 4.0 )
G.object属性:序列化的applet文件(HTML 4.0)
H.name属性:为应用的Applet 实例赋一具体的名字。
J.alt属性:为不支持Java Applet程序的浏览器显示你替代的文字,如果支持该属性被忽略。
I.另:为不支持Java Applet程序的浏览器显示你替代的文字,
还可以用在之间插入文字的方法进行,反之该插入文字被忽略不显示。
3.向 Applet 传递变量
A.确定该 Java Applet 程序所接受的变量名,比如 size、font两个变量;
B.在之间输入标记,
C.给标记加入name属性并设置为Java Applet中将接收值的变量名
D.加入value属性为前面定义好的变量赋值。
E.当浏览器遇到 标记中的标记时,它读进变量名和赋予的值传递给当前Java Applet中的命名变量。
三、Applet安全限制
在缺省的情况下,Applet在安全方面受到诸多的限制,几乎不能对系统进行任何“读”“写”的操作。
下面受限制的功能:
不允许Applet读本地系统上的文件。例如,下面的代码将出错:
File readFile=new File("/etc/passwd");
FileInputStrean readIn=new FileInputStream(readFile);
不允许Applet创建,修改或删除本地系统的文件。例如,下面的代码将出错:
//不能创建文件
File writeData=new File("write.txt");
FileOutputStream out= new FileOutputStream(writeData);
cut.write(1);
//不能修改或删除文件,不能更改文件名
File oldName =new File("one.txt");
File newName= new File("two.txt");
oldName.renameTo(newName);
File removeFile=new File("inport.dat");
removeFile.delete();
不允许Applet检查本地系统上文件是否存在。例如,下面的代码将出错:
File isHere = new File("grades.dbm");
isHere.exists();
不允许Applet在本地系统上创建目录。例如,下面的代码将出错:
File createDir= new File("mydir");
createDir.mkdir();
不允许Applet检查目录的内容。例如,下面的代码将出错:
String[] fileNames;
File lookAtDir= new File("/user/hisdir");
fileNames = lookAtDir.list();
不允许Applet检查文件的属性。例如,不允许检查文件的尺寸、类型、最后更改时间等、
例如,下面的代码将出错:
File checkFile= new File("this.dat");
ling checkSize;
boolean checkType;
long checkModTime;
checkSize= checkFile.length();
checkTyty= checkFile.isFile();
checkModTime= checkFile.lastModified();
Applet不能创建或装载Applet的机器的网络连接。
无论使用何种不同的网络Java类(包括:java.net.Socket,java.net.URL,and
java.DatagramSocket),这个规则都成立。例如,假设Applet被下载到www.trusted.org,
下面的代码将出错:
//不能打开TCP socket.
Socket mailSocket = new Socket("mail.nutrusted.org",25);
//不能使用URL对象
URL untrustedWeb=new URL("http://www.untrusted.org/");
URLConection agent= untrustedWeb.openConnection();
agent.connect();
//不能使用UDP数据报发送数据
InetAddress thetSize=new InetAddress("WWW.untrusted.org");
int thatPort=7;
byte[] data= new byte[100];
DatagramPacket sendPacket= new DatagramPacket(data,data.lenght,thatSize,thatPort);
DatagramSocket sendSocket=new datagramSocket();
sendSocket.send(sendPacket);
Applet不能充当网络服务器,监听或接收来自远程系统的连接请求。
例如,下面的代码将出错:
ServerSocket listener= new ServerSocket(8000);
listener.accept();
Applet不能执行任何本地计算机上的程序。例如,下面的代码将出错:
String command="DEL\AUTOEXEC.BAT";
Runtime systemCommands=Runtime.getRuntime();
systemCommands.exec(command);
不允许Applet装载动态库或定义本地方法调用。例如,下面的代码将出错:
Runtime systemCommands= Runtime.getRuntime();
systemCommands.loadLibrary("local.dll:);
在Java环境中,设置了一些标准的系统属性,
jaxa.lang.System.getProperty(String kcy) 方法可以出来访问这些属性,
对于Applet而言,某些系统属性是只读的。这些属性包括:file.separator,
java.class.path,java.class.version,java.home,java.vendor,
java.vendor.url,java.version,line.separator,os.arch,os.name,
os.version,path.separator,user.dir,user.home,user.name。
Applet不能操纵不在自己线程组中的任何线程。
Applet不能关闭JVM。例如,下面的代码将出错:
Runtime systemCommands=Runtime.getRuntime();
systemCommands.exit(0);
system.exit(0);
Applet不能创建SecurityManager或ClassLoader实体。
这些策略表达了一些严格的限制,应该清楚在缺省的情况下,
Applet可以做什么,不可以做什么,正确对待一些非编程方面的错误。
四、Applet数字签名
步骤一:将Applet Class打成Jar包
如:在命令行中执行以下的语句:
jar -cvf MyApplet.jar class
步骤二:(在网页中嵌入Applet)(如何在Html嵌入Apple方法见附录)
下面是嵌入Applet部分的写法:
步骤三:(生成证书及签名)
1、keytool -genkey -keystore pepper.store -alias pepper
这个命令用来产生一个密匙库,执行完毕后应该在c:/admin中产生一个pepper.store的文件,
这里的pepper是我自己的名字,你可以对它进行修改。另外在执行命令的时候还有提示
你输入密匙库的密码,这里你一定要记住,否则后面要用的时候无法输入。
2、keytool -eXPort -keystore pepper.store -alias pepper -file pepper.cert
这个命令用来产生签名时所要用的证书,同样这里的pepper也可以换成你自己需要的名字。
这个命令执行完后在c:/admin中产生一个pepper.cert的文件。
3、 jarsigner -keystore pepper.store MyApplet.jar pepper
这个命令用上面产生的证书将我们的jar文件进行了签名。
步骤四:新建一个策略文件,并把这些策略文件加入(修改文件)
1、在c:/admin中产生一个名为applet.policy的文件,其内容如下:
keystore "file:c: /admin/pepper.store", "JKS";
grant signedBy "pepper"
{ permission Java.io.FilePermission "<<ALL FILES>>", "read";=;
这个文件让由pepper签名的Applet拥有本地所有文件的读权限。
2、修改${java.home}/jre/lib/security目录下的java.security,找到下面这两行:
policy.url.1=file:${java.home}/lib/security/java.policy
policy.url.2=file:${user.home}/.java.policy
在下面添写第三行
policy.url.3=file:c: /admin/applet.policy
完成这个修改后我们在前面创建的applet.policy文件才有效。
步骤五:(转换html文件)
运行前面提到的HTMLConvert工具,将原有的FileReaderApplet.html转化成下面的形式:
<!--"CONVERTED_APPLET"-->
<!-- CONVERTER VERSION 1.3 -->
<!--
<APPLET CODE = "jcomponent.FileReaderApplet.class"
CODEBASE = "." ARCHIVE = "MyApplet.jar" WIDTH = 400 HEIGHT = 300
NAME = "TestApplet" ALIGN = middle VSPACE = 0 HSPACE = 0>
</APPLET>
-->
<!--"END_CONVERTED_APPLET"-->
大家不要看到这里的写法很复杂,但是这些都是由HTMLConvert工具自动实现的。
这个工具有命令行和图形界面两种运行方式。
好了,现在这个Applet可以运行读写文件的功能了。
如果你要考虑在Internet上实现这个Applet,那么你也不需要在所有的客户端均做上面的步骤,
你只需要在你的服务器上创建一个目录,
例如c:/admin,将这个目录映射为www.testApplet.com/admin。
这里的www.testApplet.com是一个假定的网址,将pepper.cert、pepper.store、
FileReaderApplet.html、MyApplet.jar以及applet.policy放在这个目录中,
然后修改applet.policy文件如下:
keystore "http:// www.testApplet.com/admin/pepper.store",
"JKS";grant signedBy "pepper"{
permission java.io.FilePermission "<<ALL FILES>>", "read";};
3、而每个客户端仅仅需要修改一下它们的${java.home}/jre/lib/security
目录下的java.security文件如下:
policy.url.1=file:${java.home}/lib/security/java.policypolicy.url.2=
file:${user.home}/.java.policypolicy.url.3=
http:// www.testApplet.com/admin/applet.policy
当然每个客户端还是需要安装JRE的。
Height Applet在Html页面上的高度
Name Applet在Html页面上的名称,用于区名一个Html页面上的多个
AppletCode Applet类名,必须带后缀”class”当没有属性archive时,
直接写类名当有属性archive时,必须带包名Codebase Applet的类相对路径,
相对于Html页面位置Archive Applet所在Jar包的文件名
标签< PARAM>的属性介绍
属性 含义
Name Applet传入的参数名
Value Applet传入的参数值
当Applet 为一个Class类文件嵌入的写法
属性Code ==========Applet类名,必须带后缀名
属性CodeBase ---------------Class类文件相对于Html页面的相对 路径
Applet为一个JAR包,嵌入Html的写法
属性Code ==========Applet类名,包括包名
属性CodeBase ----------------Applet JAR包相对于Html页面的相对路径
属性Archive -----------------------Applet Jar包文件名
五、Applet与js调用
javascript与applet之间能够相互通讯给我们带来了很多方便,Java与JavaScript互相补充,
以开发功能更完美的Web应用程序。B/S下能够充分利用java的优势,给我们带来更多的网络体验,
方便用户。我用的比较多的是利用Swing组件开发的应用程序利用applet实现B/s下架构, 这样能
够充分显示Swing组件的优势,便于系统升级,便于维护;还有就是在WEB下,有时客户端要使用
本地的硬件资源,我所知道的是通过applet来实现,通过applet去调用javaAPI
(jni,javacomm20-win32【详见http://www.iteye.com/topic/64859】)来实现。
不知道有没有类似applet的实现方式,我想应该有的。
我们具体来看看javascript与applet之间到底是怎样通讯的呢?
1.JavaScript访问Applet
代码
1.
2. //JavaScript访问Applet属性
3. window.document.appletName.appletField
(属性必须是public的,"window.document."也可以不写)
4. /JavaScript访问Applet方法
5. window.document.appletName.appletMethod
(方法必须是public的,"window.document."也可以不写)
2.Applet访问JavaScript
Live Connect提供了Java与JavaScript的接口,可以允许在Java Applet小程序中使用JavaScript。
需要用到一个jar包,在C:\WINNT\java\Packages目录下找,大概有5M多,
其实就是打开看哪个有netscape.javascript.JSObject。如果没有装个NetScape或从网上下都可以。
可以把它重命名为netscape.jar(不是必须的),一定要加入到classpath,目的是使开发的时候能够编译。
注意:部署时不需要包括netscape.jar,因为整个包会下载到客户端,影响速度。
代码
1. //引入netscape类
2. import netscape.javascript.JSObject;
3. import netscape.javascript.JSException; //可允许在小程序中处理异常事件
4.
5. win=JSObject.getWindow(this); // 获取JavaScript窗口句柄,引用当前文档窗口
6. doc=(JSObject)win.getMember("document"); // 访问JavaScript document对象
7. form=(JSObject)doc.getMember("textForm"); //访问JavaScript form对象
8. textField=(JSObject)form.getMember("textField");访问JavaScript text对象
9. text=(String) textField.getMember("value"); //获取文本区的值
10.
11. // 调用JavaScript的alert()方法
12. win.eval("alert(\"This alert comes from Java!\")");
13.
14. // 调用JavaScript的myFunction(message)方法
15. win.call("myFunction", new Object[]{"Hello"});//参数用数组的形势表示。
注意:你必须在 标记中加入MAYSCRIPT才能够调用JSObject对象,
不然会抛出JSException异常。你也不必初始化他们,在什么地方用就在什么地方用吧。
2011年2月15日星期二
将Ajax 传回的Html中附带的Javascript 变量定义为全局
比如 ajax返回:
var pickerObj_sms_send_time 在全局javascript中不被辨认(undefined).
解决办法:
将var pickerObj_sms_send_time 定义改为:
window.pickerObj_sms_send_time... 即可
2010年9月21日星期二
Cron Job Syntax
field allowed values
----- --------------
minute 0-59
hour 0-23
day of month 1-31
month 1-12 (or names, see below)
day of week 0-7 (0 or 7 is Sun, or use names)
Wenn du den Tag der Woche festlegst, beides Tag 0 und Tag 7 stellen beide den Sonntag da.
Ein feld mit einem Sternchen(*), steht immer für das erste bis letzte.
Namen für ‘Monat’ und ‘Tag der Woche’ können ebenso in den Feldern stehen. Benutze die ersten 3 Buchstaben des jeweiligen Tages oder Monats(die englische Bezeichnung), z.B. sun oder SUN für Sonntag oder mar / MAR für März..
Lasst uns einen blick auf 2 Cron Jobs aus dem Ersten Kapitel werfen:
* * * * * /usr/local/ispconfig/server/server.sh > /dev/null 2>> /var/log/ispconfig/cron.log
Das meint: führe /usr/local/ispconfig/server/server.sh > /dev/null 2>> /var/log/ispconfig/cron.log einmal pro Minute aus.
30 00 * * * /usr/local/ispconfig/server/cron_daily.sh > /dev/null 2>> /var/log/ispconfig/cron.log
Das meint: führe /usr/local/ispconfig/server/cron_daily.sh > /dev/null 2>> /var/log/ispconfig/cron.log einmal pro Tag um 00:30h.
Der Tag an dem das Kommando ausgeführt werden soll, kann in 2 Felder angegeben werden: Tag des Monats und Tag der Woche: Wenn beide Felder beschränkt sind(z.B. kein *), das Kommando wird wenn eins von den beiden in dem Moment zutrifft.Zum Beispiel, 30 4 1,15 * 5 würde ein Kommando bedeuten, welches um 4:30h am ersten und letzen jeden Monats gestartet werden würde, genau wie jeden Freitag.
Du kannst Schritte benutzen um Cron Jobs zu definieren:
Beispiele:
1,2,5,9 - mein jede erste, zweite, fünfte, und neunte (Minute, Stunde, Monat…).
0-4,8-12 - mein alle (Minuten, Stunden, Monate,…) on 0 bis 4 und von 8 bis 12.
*/5 - meint jede fünfte (Minute, Stunde, Monet, …).
1-9/2 ist das gleiche wie 1,3,5,7,9.
Stufen oder Listen von Namen sind nciht erlaubt(Wenn du Namen anstelle der Nummern für Monate und Tage nimmst- z.B., Mon-Wen ist nicht möglich)
1,7,25,47 */2 * * * Kommando
Meint: starte Kommando jede 2. Stunde in der ersten, siebenten, 25. und 47. Minute.
Anstatt der ersten 5 felder, eine on 8 Speziellen Bedingungen können auftauchen:
string meaning
------ -------
@reboot Run once, at startup.
@yearly Run once a year, ”0 0 1 1 *”.
@annually (same as @yearly)
@monthly Run once a month, ”0 0 1 * *”.
@weekly Run once a week, ”0 0 * * 0″.
@daily Run once a day, ”0 0 * * *”.
@midnight (same as @daily)
@hourly Run once an hour, ”0 * * * *”.
Du kannst ebenso name=value paare in einem crontab benutzen um variablen von Cron Jobs zu definieren:
-----------------------------------------------------------------
# benutze /bin/bash um Kommandos zu starten, anstelle der standart /bin/sh
SHELL=/bin/bash
# Maile alle Ausgaben zu exampleuser, egal von wem der crontab ist
MAILTO=exampleuser
# Setze die PATH ariable um sicher zu stellen, das alle Kommandos in einem crontab gefunden werden
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
* * * * * my_command
--------------------------------------------------------------------
Bitte beachte: wenn du keine PATH variable in einem crontab gesetzt hast, benutze immer volle Pfade in dem crontab um sicher zu stellen, das das Kommando gefunden wird und angewendet werden kann. Zum Beispiel, anstatt rsync zu schrieben, solltest du besser /usr/bin/rsync schreiben.Benutze which um den vollen Pfad des Programm herauszufinden:
---------------
which rsync
---------------
server1:~# which rsync
/usr/bin/rsync
server1:~#
Siehe
--------------
man 5 crontab
--------------
Um mehr über die Syntax on Cron jobs zu lernen.
2010年9月20日星期一
Mysql UDF (转贴)
最近公司在做个SNS子项目,需要把交易系统中的交易数据实时地发送到SNS子系统中。最自然的设计是修改各个交易模块,将数据向SNS系统传输。但是在评审和开发的时候遇到了不小的阻力。理由很简单,这些修改直接影响系统的核心交易模块,引入了一定的风险。综合考虑后,决定增加个类似于Memcached Functions for MySQL的备选方案。SNS子系统虽然大量地使用了cache,但是没有使用Memcached或EHCache,原因是这些cache实现无法满足所有的需求。最初的想法是在UDF中使用ActiveMQ CPP,将消息直接发送到SNS子系统的cache中。不过最终还是放弃了这种比较激进的做法,而是在UDF中将数据通过socket发送到某个Java程序,然后再对数据进行分类处理后,转发给SNS cache。
关于user-defined function(UDF),在MySQL的官方文档上有比较详细的说明。为了使用UDF,必须要动态链接mysqld,也就是不能使用--with-mysqld-ldflags=-all-static,而是应该使用--with-mysqld-ldflags=-rdynamic。UDF通常需要用C/C++编写,如果要编写一个名为xxx的UDF,那么需要定义如下的C/C++方法:
- xxx() (required)。这个方法的返回值就是UDF的结果。SQL数据类型和C/C++类型之间的对应关系是:varchar char *;INTEGER long long;REAL double;DECIMAL char *等。
- xxx_init() (optional)。xxx()对应的初始化方法。该方法通常用来检查xxx()方法的参数(或者进行参数类型的转换),分配内存,指定返回值的最大长度等。
- xxx_deinit() (optional)。xxx()对应的清理方法。在这个方法中应该释放之前分配的内存。
当在SQL中调用名为XXX()的UDF时,MySQL会首先尝试调用名为xxx_init() 的方法,如果该方法返回false,那么MySQL会终止SQL的执行,并返回一个error message(在xxx_init()中保存在message参数中的以null结尾的字符串,最大长度为 MYSQL_ERRMSG_SIZE)。否则MySQL会对每个row调用xxx() 方法。在所有的row都被处理后,MySQL会调用xxx_deinit() 方法来执行相应的清理工作。对于那些象SUM()之类的聚集函数,还有一些其他的C/C++函数需要编写。需要注意的是,如果采用C++编写UDF,由于C++的"name mangling"会导致MySQL无法找到对应的C++函数,因此需要将函数声明包含在extern "C" { ... }中。以下是这些函数的例子:
my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
char *xxx(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error);
void xxx_deinit(UDF_INIT *initid);
initid参数会被传递到所有三个函数中(用于在这三个函数中共享数据),它指向一个UDF_INIT结构体。关于该结构体的成员,可以参考MySQL的在线文档。args参数指向一个UDF_ARGS结构体,它有如下成员:
- unsigned int arg_count。参数的个数。
- enum Item_result *arg_type。参数的类型。可选值有STRING_RESULT, INT_RESULT, REAL_RESULT, and DECIMAL_RESULT。DECIMAL_RESULT类型的值是以char *的形式传入到函数中的,因此处理方式同STRING_RESULT类型参数。如果xxx_init()中对该成员赋值,例如args->arg_type[0] = STRING_RESULT;那么MySQl会在调用xxx()是对 相应的参数进行强制地类型转换。
- char **args。参数值。如果参数值是NULL,那么args->args[i]是一个空指针(0)。对于STRING_RESUL类型的参数,那么可以通过 args->args[i]访问该字符串,字符串的长度是args->lengths[i](不要假定该字符串是以null结尾的)。对于INT_RESULT类型的参数,通过long long int_val = *((long long*) args->args[i]);进行访问。对于REAL_RESULT类型参数,通过double real_val = *((double*) args->args[i]);进行访问。对于DECIMAL_RESULT类型参数,处理方式同STRING_RESULT。
- unsigned long *lengths。在xxx_init()函数中,其值是字符串参数的最大长度。在xxx()函数中,其值是字符串参数的实际长度。对于INT_RESULT 或者REAL_RESULT类型参数,其值始终是最大可能值。
- char *maybe_null。在xxx_init()函数中,其值表明该参数是否可以为null。
- char **attributes。参数名。默认情况下是SQL中的表达式文本(同样,不要假定该字符串是以null结尾的)。
- unsigned long *attribute_lengths。参数名的字符串长度。
以下是个UDF C代码的片段:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include "mysql.h"
///////////////////////////////////////////////////
extern "C" {
//
my_bool send_message_open_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
char * send_message_open(UDF_INIT *initid, UDF_ARGS *args, char* result, unsigned long *length, char *is_null, char *error);
void send_message_open_deinit(UDF_INIT *initid);
//
my_bool send_message_close_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
char * send_message_close(UDF_INIT *initid, UDF_ARGS *args, char* result, unsigned long *length, char *is_null, char *error);
void send_message_close_deinit(UDF_INIT *initid);
//
my_bool send_message_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
char * send_message(UDF_INIT *initid, UDF_ARGS *args, char* result, unsigned long *length, char *is_null, char *error);
void send_message_deinit(UDF_INIT *initid);
}
////////////////////////////////////////////////////
// Open
////////////////////////////////////////////////////
my_bool send_message_open_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
// Validation
if(args->arg_count != 2) {
strcpy(message,"usage: select send_message_open('10.15.3.68', 7777)");
return -1;
} else if(args->arg_type[0] != STRING_RESULT || args->arg_type[1] != INT_RESULT){
strcpy(message,"usage: select send_message_open('10.15.3.68', 7777)");
return -1;
} else {
return 0;
}
}
char * send_message_open(UDF_INIT *initid, UDF_ARGS *args, char* result, unsigned long *length, char *is_null, char *error){
...
}
void send_message_open_deinit(UDF_INIT *initid) {
}
...
编译:
g++ -I/usr/local/mysql/include/mysql/ -shared -o send_message.so send_message.c
编译后需要将so文件拷贝到MySQL可以加载的位置,如:
cp send_message.so /usr/local/mysql6320/lib/mysql/plugin/
在MySQL中创建UDF:
DROP FUNCTION IF EXISTS send_message_open;
DROP FUNCTION IF EXISTS send_message_close;
DROP FUNCTION IF EXISTS send_message;
CREATE FUNCTION send_message_open RETURNS STRING SONAME 'send_message.so';
CREATE FUNCTION send_message_close RETURNS STRING SONAME 'send_message.so';
CREATE FUNCTION send_message RETURNS STRING SONAME 'send_message.so';
测试:
select send_message_open('10.15.3.68', 7777);
select send_message('test message');
select send_message_close();
2009年3月27日星期五
Memset,Strcpy, memcpy
例:char a[100];memset(a, '\0', sizeof(a));
memset可以方便的清空一个结构类型的变量或数组。
如:
struct sample_struct
{
char csName[16];
int iSeq;
int iType;
};
对于变量
struct sample_strcut stTest;
一般情况下,清空stTest的方法:
stTest.csName[0]='\0';
stTest.iSeq=0;
stTest.iType=0;
用memset就非常方便:
memset(&stTest,0,sizeof(struct sample_struct));
如果是数组:
struct sample_struct TEST[10];
则
memset(TEST,0,sizeof(struct sample_struct)*10);
memcpy 用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度。
例:char a[100],b[50]; memcpy(b, a, sizeof(b));注意如用sizeof(a),会造成b的内存地址溢出。
Strcpy 就只能拷贝字符串了,它遇到'\0'就结束拷贝。
例:char a[100],b[50];strcpy(a,b);如用strcpy(b,a),要注意a中的字符串长度(第一个‘\0’之前)是否超过50位,如超过,则会造成b的内存地址溢出。
str也可以用用个参数的strncpy(a,b,n)
========================================================
memset主要应用是初始化某个内存空间。
memcpy是用于copy源空间的数据到目的空间中。
strcpy用于字符串copy,遇到‘\0’,将结束。
如果你理解了这些,你应该知道他们的区别:例如你初始化某块空间的时候,用到memcpy,那么应该怎么写,是不是显得很笨。
int m[100]
memset((void*)m,0x00,sizeof(int)*100);//Ok!
memcpy((void*)m,"\0\0\0\0....",sizeof(int)*100);//it’s wrong.
Sizeof与Strlen的区别与联系
该类型保证能容纳实现所建立的最大对象的字节大小。
2.sizeof是算符,strlen是函数。
3.sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以''\0''结尾的。
sizeof还可以用函数做参数,比如:
short f();
printf("%d\n", sizeof(f()));
输出的结果是sizeof(short),即2。
4.数组做sizeof的参数不退化,传递给strlen就退化为指针了。
5.大部分编译程序 在编译的时候就把sizeof计算过了 是类型或是变量的长度这就是sizeof(x)可以用来定义数组维数的原因
char str[20]="0123456789";
int a=strlen(str); //a=10;
int b=sizeof(str); //而b=20;
6.strlen的结果要在运行的时候才能计算出来,时用来计算字符串的长度,不是类型占内存的大小。
7.sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为sizeof是个操作符不是个函数。
8.当适用了于一个结构类型时或变量, sizeof 返回实际的大小,
当适用一静态地空间数组, sizeof 归还全部数组的尺寸。
sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸
9.数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,
如:
fun(char [8])
fun(char [])
都等价于 fun(char *)
在C++里参数传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小
如果想在函数内知道数组的大小, 需要这样做:
进入函数后用memcpy拷贝出来,长度由另一个形参传进去
fun(unsiged char *p1, int len)
{
unsigned char* buf = new unsigned char[len+1]
memcpy(buf, p1, len);
}
我们能常在用到 sizeof 和 strlen 的时候,通常是计算字符串数组的长度
看了上面的详细解释,发现两者的使用还是有区别的,从这个例子可以看得很清楚:
char str[20]="0123456789";
int a=strlen(str); //a=10; >>>> strlen 计算字符串的长度,以结束符 0x00 为字符串结束。
int b=sizeof(str); //而b=20; >>>> sizeof 计算的则是分配的数组 str[20] 所占的内存空间的大小,不受里面存储的内容改变。
上面是对静态数组处理的结果,如果是对指针,结果就不一样了
char* ss = "0123456789";
sizeof(ss) 结果 4 ===》ss是指向字符串常量的字符指针,sizeof 获得的是一个指针的之所占的空间,应该是
长整型的,所以是4
sizeof(*ss) 结果 1 ===》*ss是第一个字符 其实就是获得了字符串的第一位'0' 所占的内存空间,是char类
型的,占了 1 位
strlen(ss)= 10 >>>> 如果要获得这个字符串的长度,则一定要使用 strlen
2009年3月23日星期一
linux OPENSSL 服务器
OpenSSL项目是一个合作的项目,开发一个健壮的、商业等级的、完整的开发源代码的工具包,用强大的加密算法来实现安全的Socket层(Secure Sockets Layer,SSL v2/v3)和传输层的安全性(Transport Layer Security,TLS v1)。
这个项目是由全世界的志愿者管理的,他们通过Internet相互交流、制定计划和开发OpenSSL工具包和相关文档。
加密的优势
数据的保密性
信息加密就是把纯文本的输入文件用加密算法转换成加密的文件以实现数据的保密。加密的过程需要用到密匙来加密数据然后再解密。没有了密匙,就无法解开加密的数据。数据加密之后,只有密匙要用一个安全的方法传送。加密过的数据可以公开地传送。
数据的一致性
加密也能保证数据的一致性。例如:加密的校验码,也叫做消息验证码(Message Authentication Code,MAC),能够校验用户提供的加密信息。加密的数据和MAC一起发送给接收者,接收者就可以用MAC来校验加密数据,保证数据没有被窜改过。
安全验证
加密的另外一个用途是用来作为个人的标识,用户的密匙可以作为他的安全验证的标识。
专利
各种各样的公司在世界各地拥有各种各样算法的专利。在使用加密算法之前必须检查一下这个算法有没有受到本国专利的限制。下面列出一些受到专利保护的算法(可能不确切):
RSA Data Security在美国和日本拥有RSA和RC5算法的专利。必须和RSA Data Security联系以得到许可条例。其主页是:http://www.rsa.com/。
RC4是RSA Data Security的商标,使用这个标志必须得到RSA Data Security的许可。
IDEA算法在澳大利亚、法国、德国、意大利、日本、荷兰、西班牙、瑞典、瑞士、英国和美国受专利保护。如果要使用这个算法必须得到许可,其主页是:http://www.ascom.ch/。
注意事项
下面所有的命令都是Unix兼容的命令。
源路径都为“/var/tmp”(当然在实际情况中也可以用其它路径)。
安装在RedHat linux 6.1下测试通过。
要用“root”用户进行安装。
OpenSSL的版本是0.9.4。
安装软件包需要注意的问题
最好在编译前和编译后都做一张系统中所有文件的列表,然后用“diff”命令去比较它们,找出其中的差别并知道到底把软件安装在哪里。只要简单地在编译之前运行一下命令“find /* >ssl1”,在编译和安装完软件之后运行命令“find /* > ssl2”,最后用命令“diff ssl1 ssl2 > ssl”找出变化。
软件包的来源
OpenSSL的主页是:http://www.openssl.org/。
下载:openssl-0.9.4.tar.gz
编译
把软件包(tar.Z)解压缩:
[root@deep]# cp openssl_version.tar.gz /var/tmp
[root@deep]# cd /var/tmp
[root@deep]# tar xzpf openssl_version.tar.gz
编译与优化
转到OpenSSL目录下。
第一步
编辑“c_rehash”文件(vi +11 tools/c_rehash),把:
DIR=/usr/local/ssl
改为:
DIR=/usr
这个改变是使编译和安装OpenSSL时用“/usr”这个默认目录。
第二步
在默认情况下OpenSSL把Perl程序的目录设置为“/usr/local/bin/perl”目录。必须改变所有脚本中的“#!/usr /local/bin/perl”这一行,因为在RedHat linux中Perl的路径是“/usr/bin”。用下面的命令:
[root@deep]# perl util/perlpath.pl /usr/bin (where your perl program reside).
第三步
为了成功编译OpenSSL,必须知道函数库所在的路径。用下面的命令设置PATH环境变量:
[root@deep]# export LD_LIBRARY_PATH=`pwd`
设置编译器的编译参数:
CC="egcs"
./Configure linux-elf -DSSL_FORBID_ENULL
--prefix=/usr
--openssldir=/etc/ssl
注意:因为安全方面的原因要禁止“不加密”,所以“-DSSL_FORBID_ENULL”参数是必须的。
编辑“Makefile.ssl”文件(vi +52 Makefile.ssl),加入:
CFLAG= -DTHREADS -D_REENTRANT -DSSL_FORBID_ENULL -DL_ENDIAN -DTERMIO -O9 -funroll-loops -ffast-math -malign-double -mcpu=pentiumpro -march=pentiumpro -fomit-frame-pointer -fno-exceptions -Wall -DSHA1_ASM -DMD5_ASM -DRMD160_ASM
这是编译OpenSSL的优化参数。
编辑“Makefile.ssl”文件(vi +77 Makefile.ssl),加入:
PROCESSOR= 686
注意:如果CPU是Pentium,用586表示,PentiumPro/II/III用686,486用486。
[root@deep]# make -f Makefile
[root@deep]# make test
[root@deep]# make install
[root@deep]# mv /etc/ssl../misc/* /usr/bin/
[root@deep]# rm -rf /etc/ssl../misc/
[root@deep]# rm -rf /etc/ssl/lib/
[root@deep]# rm -f /usr/bin/CA.pl
[root@deep]# rm -f /usr/bin/CA.sh
[root@deep]# install -m 644 libRSAglue.a /usr/lib/
[root@deep]# install -m 644 rsaref/rsaref.h /usr/include/openssl/
[root@deep]# strip /usr/bin/openssl
[root@deep]# mkdir -p /etc/ssl/crl
“make -f”命令编译OpenSSL函数库(libcrypto.a和libssl.a)以及OpenSSL的二进制文件“openssl”。编译完之后函数库在顶层目录,二进制程序在“apps”子目录。成编译之后,“make test”测试函数库是否正常。最后,“make install”安装OpenSSL。
“mv”命令把“/etc/ssl../misc”目录下的所有文件移到“/usr/bin”目录下。因为在我们的系统中所有的二进制文件都在“/usr/bin”目录下,所以要把二进制文件都移到这个目录下。
“rm”命令删除“/etc/ssl../misc”和“/etc/ssl/lib”目录,因为这个目录中的文件都在别的地方了。“CA.pl”和 “CA.sh”文件是小的脚本文件用来创建CA认证。这个脚本和“openssl ca”命令相关,而且有一些奇怪的要求。在默认情况下,OpenSSL的配置不能很容易地使用“openssl ca”。所以我们后面会用“sign.sh”脚本来替换它们。
清除不必要的文件
[root@deep]# cd /var/tmp
[root@deep]# rm -rf openssl-version/ openssl_version.tar.gz
“rm”命令删除所有的编译和安装OpenSSL软件所需的源文件,并把OpenSSL软件的压缩包删除。
配置
可以到这去下载“floppy.tgz”文件:http://pages.infinit.net/lotus1/doc/opti /floppy.tgz。把“floppy.tgz”文件解开之后,可以在相应的目录下发现我们在这本书中介绍的所有软件的配置文件。这样就没有必要手工重新生成这些文件,或者用拷贝粘贴的方法把它们粘贴到配置文件中去。不管是打算自己动手生成配置文件还是拷贝现成的,你都要学会自己修改配置文件并且把配置文件拷贝到正确的目录下。下面将具体说明。
为了运行OpenSSL服务器,必须创建或者把下面的文件拷贝到相应的目录下:
l 把“openssl.cnf”文件拷贝到“/etc/ssl”目录下
l 把“sign.sh”文件拷贝到“/usr/bin”目录下
可以把“floppy.tgz”解压之后,找到上面列出来的文件,并拷贝到相应的目录下,或者用拷贝粘贴的方法从本书中直接粘贴出。
配置“/etc/ssl/openssl.cnf”文件
这是openssl程序总的配置文件,可以配置密匙的过期时间、公司的名称、地址,等等。需要改变得配置在[CA_default]和[req_distinguished_name]这两个section里。
编辑“openssl.cnf”文件(vi /etc/ssl/openssl.cnf),加入并改变:
# OpenSSL example configuration file.
# This is mostly being used for generation of certificate requests.
#
RANDFILE = $ENV::HOME/.rnd
oid_file = $ENV::HOME/.oid
oid_section = new_oids
# To use this configuration file with the "-extfile" option of the
# "openssl x509" utility, name here the section containing the
# X.509v3 extensions to use:
# extensions =
# (Alternatively, use a configuration file that has only
# X.509v3 extensions in its main [= default] section.)
[ new_oids ]
# We can add new OIDs in here for use by 'ca' and 'req'.
# Add a simple OID like this:
# testoid1=1.2.3.4
# Or use config file substitution like this:
# testoid2=${testoid1}.5.6
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
####################################################################
[ CA_default ]
dir = /etc/ssl # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/ca.db.index # database index file.
new_certs_dir = $dir/ca.db.certs # default place for new certs.
certificate = $dir/certs/ca.crt # The CA certificate
serial = $dir/ca.db.serial # The current serial number
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/ca.key # The private key
RANDFILE = $dir/ca.db.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crl_extensions = crl_ext
default_days = 365 # how long to certify for
default_crl_days = 30 # how long before next CRL
default_md = md5 # which md to use.
Preserve = no # keep passed DN ordering
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that
policy = policy_match
# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ req ]
default_bits = 1024
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = CA
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Quebec
localityName = Locality Name (eg, city)
localityName_default = Montreal
0.organizationName = Organization Name (eg, company)
0.organizationName_default = Open Network Architecture
# we can do this but it is not needed normally
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = World Wide Web Pty Ltd
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = Internet Department
commonName = Common Name (eg, YOUR name)
commonName_default = www.openarch.com
commonName_max = 64
emailAddress = Email Address
emailAddress_default = admin@openarch.com
emailAddress_max = 40
# SET-ex3 = SET extension number 3
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
unstructuredName = An optional company name
[ usr_cert ]
# These extensions are added when 'ca' signs a request.
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
[ v3_ca]
# Extensions for a typical CA
# PKIX recommendation.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
# This is what PKIX recommends but some broken software chokes on critical
# extensions.
#basicConstraints = critical,CA:true
# So we do this instead.
basicConstraints = CA:true
# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
# keyUsage = cRLSign, keyCertSign
# Some might want this also
# nsCertType = sslCA, emailCA
# Include email address in subject alt name: another PKIX recommendation
# subjectAltName=email:copy
# Copy issuer details
# issuerAltName=issuer:copy
# RAW DER hex encoding of an extension: beware experts only!
# 1.2.3.5=RAW:02:03
# You can even override a supported extension:
# basicConstraints= critical, RAW:30:03:01:01:FF
[ crl_ext ]
# CRL extensions.
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
# issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always,issuer:always
注意:编译和安装完OpenSSL程序之后,“openssl.cnf”文件在服务器上已经存在了,可以在“/et/ssl”目录下找到。没有必要改变这个文件中所有的默认配置,经常需要修改的只是[CA_default]和[req_distinguished_name]这两个section。
创建“/usr/bin/sign.sh”脚本文件
“openssl ca”命令有一些奇怪的要求,OpenSSL默认的配置并不是很容易直接使用“openssl ca”,因此我们用“sign.sh”脚本文件替代它。
创建“sign.sh”脚本(touch /usr/bin/sign.sh),加入:
#!/bin/sh
##
## sign.sh -- Sign a SSL Certificate Request (CSR)
## Copyright (c) 1998-1999 Ralf S. Engelschall, All Rights Reserved.
##
# argument line handling
CSR=$1
if [ $# -ne 1 ]; then
echo "Usage: sign.sign .csr"; exit 1
fi
if [ ! -f $CSR ]; then
echo "CSR not found: $CSR"; exit 1
fi
case $CSR in
*.csr ) CERT="`echo $CSR | sed -e 's/.csr/.crt/'`" ;;
* ) CERT="$CSR.crt" ;;
esac
# make sure environment exists
if [ ! -d ca.db.certs ]; then
mkdir ca.db.certs
fi
if [ ! -f ca.db.serial ]; then
echo '01' >ca.db.serial
fi
if [ ! -f ca.db.index ]; then
cp /dev/null ca.db.index
fi
# create an own SSLeay config
cat >ca.config < [ ca ]
default_ca = CA_own
[ CA_own ]
dir = /etc/ssl
certs = /etc/ssl/certs
new_certs_dir = /etc/ssl/ca.db.certs
database = /etc/ssl/ca.db.index
serial = /etc/ssl/ca.db.serial
RANDFILE = /etc/ssl/ca.db.rand
certificate = /etc/ssl/certs/ca.crt
private_key = /etc/ssl/private/ca.key
default_days = 365
default_crl_days = 30
default_md = md5
preserve = no
policy = policy_anything
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
EOT
# sign the certificate
echo "CA signing: $CSR -> $CERT:"
openssl ca -config ca.config -out $CERT -infiles $CSR
echo "CA verifying: $CERT <-> CA cert"
openssl verify -CAfile /etc/ssl/certs/ca.crt $CERT
# cleanup after SSLeay
rm -f ca.config
rm -f ca.db.serial.old
rm -f ca.db.index.old
# die gracefully
exit 0
现在,让这个脚本可执行并改变它的默认权限:
[root@deep]# chmod 755 /usr/bin/sign.sh
注意:解开“floppy.tgz”文件之后,可以在“mod_ssl-version/pkg.contrib”目录下找到“sign.sh”文件。要根据实际情况改变[CA_own]这一节,而且不要忘了改变“openssl verify -CAfile /etc/ssl/certs/ca.crt $CERT”这一行。
保证OPENSSL的安全
把密匙设置成只能被超级用户“root”可执行和可写。必须保证其他人不能访问这个文件。
用下面的命令使得密匙只能被“root”可执行和可写:
[root@deep]# chmod 600 /etc/ssl/certs/ca.crt
[root@deep]# chmod 600 /etc/ssl/certs/server.crt
[root@deep]# chmod 600 /chroot/httpd/etc/ssl/private/ca.key
[root@deep]# chmod 600 /chroot/httpd/etc/ssl/private/server.key
命令
下面列出的是一些我们经常要用到的命令,当然还有很多其它的命令,更详细的信息可以查看man帮助页或其它文档。
在下面这个例子中,我们指导你如何为Apache Web服务器创建认证:
注意:下面所有的命令都在“/etc/ssl”目录下运行的。
为Apache服务器创建用口令保护的RSA私人密匙。
[root@deep]# openssl genrsa -des3 -out server.key 1024
Generating RSA private key, 1024 bit long modulus
......................+++++
.....+++++
e is 65537 (0x10001)
Enter PEM pass phrase:
Verifying password - Enter PEM pass phrase:
请把“server.key”文件备份起来,记住只有在安全的地方才能输入口令。
用服务器的RSA私人密匙创建Certificate Signing Request(CSR)
[root@deep]# openssl req -new -key server.key -out server.csr
Enter PEM pass phrase:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [CA]:
State or Province Name (full name) [Quebec]:
Locality Name (eg, city) [Montreal]:
Organization Name (eg, company) [Open Network Architecture]:
Organizational Unit Name (eg, section) [Internet Department]:
Common Name (eg, YOUR name) [www.openarch.com]:
Email Address [admin@openarch.com]:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:.
An optional company name []:.
现在可以把这个CSR(Certificate Signing Request)发送给认证机构(Certifying Authority, CA),让它签订这个CSR。CSR被签订之后,就成为真正的证书(Certificate),可以被Apache使用。有下面两种选择。第一:可以让商业的CA,如:Verisign或Thawte签订CSR。通常需要在Web上登记CSR,然后支付签订所需的费用,接着等待签订后的证书,最后收到证书把它存成server.crt文件。第二:可以用自己的CA来签订证书。下面介绍如何用自己的CA签订CSR。
首先确信当OpenSSL提示输入“CommonName”的时候,输入服务器的FQDN(Fully Qualified Domain Name,完全合格的域名)。例如:如果要为今后用http://www.mydomain.com访问的站点创建CSR,在这里就需要输入 www.mydomain.com。
为自己的CA创建RSA私人密匙
[root@deep]# openssl genrsa -des3 -out ca.key 1024
Generating RSA private key, 1024 bit long modulus
...........................+++++
............................................+++++
e is 65537 (0x10001)
Enter PEM pass phrase:
备份好ca.key文件。注意只有在安全的地方才能输入口令。
用CA的RSA密匙创建自我签订的证书(x509 结构)
[root@deep]# openssl req -new -x509 -days 365 -key ca.key -out ca.crt
Enter PEM pass phrase:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [CA]:
State or Province Name (full name) [Quebec]:
Locality Name (eg, city) [Montreal]:
Organization Name (eg, company) [Open Network Architecture]:
Organizational Unit Name (eg, section) [Internet Department]:CA Marketing
Common Name (eg, YOUR name) [www.openarch.com]:
Email Address [admin@openarch.com]:
[root@deep]# mv server.key private/
[root@deep]# mv ca.key private/
[root@deep]# mv ca.crt certs/
注意:当使用“-x509”参数的时候,“req”命令创建了自我签订的证书。
签订一个证书请求(用自己的CA)
准备一个用于签订证书的脚本是必须的,因为“openssl ca”命令有一些很怪的要求而且在默认情况下OpenSSL的配置不是很容易就可以直接使用“openssl ca”。这就需要一个名为“sign.sh”的脚本文件,解开“floppy.tgz”之后就可以在相应的目录中找到。用这个脚本完成签订。
现在用这个CA签订服务器的CSR,这样就能为Apache服务器创建真正的SSL证书(假定你已经有了“server.csr”这个文件)。
[root@deep]# /usr/bin/sign.sh server.csr
Using configuration from ca.config
Enter PEM pass phrase:
Check that the request matches the signature
Signature ok
The Subjects Distinguished Name is as follows
countryName :PRINTABLE:'CA'
stateOrProvinceName :PRINTABLE:'Quebec'
localityName :PRINTABLE:'Montreal'
organizationName :PRINTABLE:'Open Network Architecture'
organizationalUnitName :PRINTABLE:'Internet Department'
commonName :PRINTABLE:'www.openarch.com'
emailAddress :IA5STRING:'admin@openarch.com'
Certificate is to be certified until Dec 1 14:59:29 2000 GMT (365 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
CA verifying: server.crt <-> CA cert
server.crt: OK
上面的命令签订了CSR并把结果存成“server.crt”文件。
[root@deep]# mv server.crt certs/
现在有两个文件:“server.key”和“server.crt”。可以在Apache的配置文件“httpd.conf”文件中加上:
SSLCertificateFile /etc/ssl/certs/server.crt
SSLCertificateKeyFile /etc/ssl/private/server.key
“server.csr”文件可以不要了。
[root@deep]# rm -f server.csr
安装到系统中的文件
> /etc/ssl
> /etc/ssl/crl
> /etc/ssl/certs
> /etc/ssl/private
> /etc/ssl/openssl.cnf
> /usr/bin/openssl
> /usr/bin/c_rehash
> /usr/bin/sign.sh
> /usr/bin/c_hash
> /usr/bin/c_info
> /usr/bin/c_issuer
> /usr/bin/c_name
> /usr/bin/der_chop
> /usr/include/openssl
> /usr/include/openssl/e_os.h
> /usr/include/openssl/e_os2.h
> /usr/include/openssl/crypto.h
> /usr/include/openssl/tmdiff.h
> /usr/include/openssl/opensslv.h
> /usr/include/openssl/opensslconf.h
> /usr/include/openssl/ebcdic.h
> /usr/include/openssl/md2.h
> /usr/include/openssl/md5.h
> /usr/include/openssl/sha.h
> /usr/include/openssl/mdc2.h
> /usr/include/openssl/hmac.h
> /usr/include/openssl/ripemd.h
> /usr/include/openssl/des.h
> /usr/include/openssl/rc2.h
> /usr/include/openssl/rc4.h
> /usr/include/openssl/rc5.h
> /usr/include/openssl/idea.h
> /usr/include/openssl/blowfish.h
> /usr/include/openssl/cast.h
> /usr/include/openssl/bn.h
> /usr/include/openssl/rsa.h
> /usr/include/openssl/dsa.h
> /usr/include/openssl/dh.h
> /usr/include/openssl/buffer.h
> /usr/include/openssl/bio.h
> /usr/include/openssl/stack.h
> /usr/include/openssl/safestack.h
> /usr/include/openssl/lhash.h
> /usr/include/openssl/rand.h
> /usr/include/openssl/err.h
> /usr/include/openssl/objects.h
> /usr/include/openssl/evp.h
> /usr/include/openssl/asn1.h
> /usr/include/openssl/asn1_mac.h
> /usr/include/openssl/pem.h
> /usr/include/openssl/pem2.h
> /usr/include/openssl/x509.h
> /usr/include/openssl/x509_vfy.h
> /usr/include/openssl/x509v3.h
> /usr/include/openssl/conf.h
> /usr/include/openssl/txt_db.h
> /usr/include/openssl/pkcs7.h
> /usr/include/openssl/pkcs12.h
> /usr/include/openssl/comp.h
> /usr/include/openssl/ssl.h
> /usr/include/openssl/ssl2.h
> /usr/include/openssl/ssl3.h
> /usr/include/openssl/ssl23.h
> /usr/include/openssl/tls1.h
> /usr/include/openssl/rsaref.h
> /usr/lib/libcrypto.a
> /usr/lib/libssl.a
> /usr/lib/libRSAglue.a
> /var/lock/subsys/named'(linux知识宝库)
gcc/g++ 命令的常用选项
格式(选项 && 解释 )
linux gcc常用命令集合:
-o FILE && 指定输出文件名,在编译为目标代码时,这一选项不是必须的。如果FILE没有指定,缺省文件名是a.out.
-c && 只编译生成目标文件,不链接
-m486 && 针对 486 进行代码优化。
-O0 && 不进行优化处理。
-O 或 -O1 && 优化生成代码。
-O2 && 进一步优化。
-O3 比 -O2 && 更进一步优化,包括 inline 函数。
-w && 关闭所有警告,建议不要使用此项
-Wall && 允许发出gcc能提供的所有有用的警告,也可以用-W(warning)来标记指定的警告
-werror && 把所有警告转换为错误,以在警告发生时中止编译过程
-MM && 输出一个make兼容的相关列表
-v && 显示在编译过程的每一步中用到的命令
-E && 只运行 C 预编译器。
-shared && 生成共享目标文件。通常用在建立共享库时。
-static && 链接静态库,即执行静态链接
-lFOO && 链接名为libFOO的函数库
-g && 在可执行程序中包含标准调试信息
-ggdb && 在可执行程序中包含只有GNU debugger才能使别的达两条是信息
-O && 优化编译过的代码
-ON && 指定代码优化的级别为N,o<=N<=3
-ansi && 支持ANSI/ISO C的标准语法,取消GNU的语法扩展中与该标准有冲突的部分(但这一选项并不能保证生成ANSI兼容的代码) 这一选项将禁止 GNU C 的某些特色, 例如 asm 或 typeof 关键词。
-pedantic && 允许发出ANSI/ISO C标准所列出的所有警告
-pedantic -errors && 允许发出ANSI/ISO C标准所列出的所有错误
-traditional && 支持Kernighan & Ritchie C语法(如用旧式语法定义函数);如果不知道这个选项的含义,也没有关系
-IDIRECTORY && 指定额外的头文件搜索路径DIRECTORY。
-LDIRECTORY && 指定额外的函数库搜索路径DIRECTORY。
-DFOO=BAR && 在命令行定义预处理宏FOO,其值为BAR
-IDIRNAME && 将DIRNAME加入到头文件的搜索目录列表中
-LDIRNAME && 将DIRNAME加入到库文件的搜索目录列表中,缺省情况下gcc 只链接共享库
-DMACRO && 以字符串“1”定义 MACRO 宏。
-DMACRO=DEFN && 以字符串“DEFN”定义 MACRO 宏。
-UMACRO && 取消对 MACRO 宏的定义。
个人使用:
使用gcc生成可执行文件后使用 ./filename执行
2009年3月14日星期六
解决安装Realtek HD Audio Driver失败的方法.txt
1,进入安全模式
2,进入X:\win\sys32\drivers下,删除Hdaudbus.sys,Hdaudio.sys(hda打头的如果还有也删,);
3,进入设备管理器。先停用在启用"Microsoft UAA Bus Driver for High Definition Audio",再右键-> 点"Microsoft UAA Bus Driver for High Definition Audio",删除,就能成功删掉系统的hd总线驱动了,
4,重启返回正常模式,取消全部“发现新硬件”画面,然后安装Realtek HD声卡的驱动。
5,安装成功,重启,
如果以后遇到类似的HD系列芯片问题,也可以参考这种方法