shell脚本测试多服务器网络速度

经常需要对多台服务器进行测试,以便选择对我们最优的服务器使用,需测的服务器不多时,手工跑跑就行了,但到几十上百台的时候,就需要写个脚本了。

服务器测试的url为:http://server/speedtesting.zip,speedtesting.zip文件需要上传到服务器上。

/root/shell/vpn.txt文件内存放服务器的域名,一行一个。

测试结果存放在:/root/shell/result.txt

脚本如下:

#!/bin/sh

vpnlist="/root/shell/vpn.txt"
testfile="/speedtesting.zip"
result="/root/shell/result.txt"

echo "" > $result

cat $vpnlist | while read vpnserver
do
        url="http://$vpnserver$testfile"
        wget -o /tmp/vpn.log $url -O /dev/null

        speed=`cat /tmp/vpn.log | grep ‘saved’ | awk -F ‘{print $3}’ | cut -c2-`
        unit=`cat /tmp/vpn.log | grep ‘saved’ | awk -F ‘{print $4}’ | cut -c-2`

        if [ "$unit" == "MB" ]; then
                speed=`echo $speed*1024 | bc`
                unit="KB"
        fi

        echo "$url      $speed $unit/s" >> $result
        echo "$url      $speed $unit/s"

done

echo "VPN speed test finish,sort result display:"

cat $result | sort -k2 -rn

javadoc 在 Java 的注释上做文章(转)

转自:http://tanzek.blog.51cto.com/95629/15808

作者:边城狂人

目录

  前言
一. Java 文档和 javadoc
二. 文档注释的格式
1. 文档注释的格式化
2. 文档注释的三部分
三. 使用 javadoc 标记
1. @see 的使用
2. 使用 @author、@version 说明类
3. 使用 @param、@return 和 @exception 说明方法
四. javadoc 命令

前言

  Java 的语法与 C++ 及为相似,那么,你知道 Java 的注释有几种吗?是两种?

  // 注释一行
/* …… */ 注释若干行

  不完全对,除了以上两种之外,还有第三种,文档注释:

  /** …… */ 注释若干行,并写入 javadoc 文档

  通常这种注释的多行写法如下:

  /**
* ………
* ………
*/

  暂停,暂停!这第三种注释有什么用?javadoc 又是什么东西?

  好,那就让我告诉你——

一. Java 文档和 javadoc

  Java 程序员都应该知道使用 JDK 开发,最好的帮助信息就来自 SUN 发布的 Java 文档。它分包、分类详细的提供了各方法、属性的帮助信息,具有详细的类树信息、索引信息等,并提供了许多相关类之间的关系,如继承、实现接口、引用等。

  Java 文档全是由一些 html 文件组织起来的,在 SUM 的站点上可以下载它们的压缩包。但是你肯定想不到,这些文档我们可以自己生成。——就此打住,再吊一次胃口。

  安装了 JDK 之后,安装目录下有一个 src.jar 文件或者 src.zip 文件,它们都是以 ZIP 格式压缩的,可以使用 WinZip 解压。解压之后,我们就可以看到分目录放的全是 .java 文件。是了,这些就是 Java 运行类的源码了,非常完整,连注释都写得一清二楚……不过,怎么看这些注释都有点似曾相识的感觉?

  这就不奇怪了,我们的迷底也快要揭开了。如果你仔细对比一下 .java 源文件中的文档注释 (/** … */) 和 Java 文档的内容,你会发现它们就是一样的。Java 文档只是还在格式和排版上下了些功夫。再仔细一点,你会发现 .java 源文件中的注释还带有 HTML 标识,如 <B>、<BR>、<Code> 等,在 Java 文档中,该出现这些标识的地方,已经按标识的的定义进行了排版。

  终于真像大白了,原来 Java 文档是来自这些注释。难怪这些注释叫做文档注释呢!不过,是什么工具把这些注释变成文档的呢?

  是该请出 javadoc 的时候了。在 JDK 的 bin 目录下你可以找到 javadoc,如果是 Windows 下的 JDK,它的文件名为 javadoc.exe。使用 javdoc 编译 .java 源文件时,它会读出 .java 源文件中的文档注释,并按照一定的规则与 Java 源程序一起进行编译,生成文档。

  介绍 javadoc 的编译命令之前,还是先了解一下文档注释的格式吧。不过为了能够编译下面提到的若干例子,这里先介绍一条 javadoc 命令:

  javadoc -d 文档存放目录 -author -version 源文件名.java

  这条命令编译一个名为 “源文件名.java”的 java 源文件,并将生成的文档存放在“文档存放目录”指定的目录下,生成的文档中 index.html 就是文档的首页。-author 和 -version 两个选项可以省略。

二. 文档注释的格式

  文档注释可以用于对类、属性、方法等进行说明。写文档注释时除了需要使用 /** …. */ 限定之外,还需要注意注释内部的一些细节问题。

  1. 文档和文档注释的格式化

  生成的文档是 HTML 格式,而这些 HTML 格式的标识符并不是 javadoc 加的,而是我们在写注释的时候写上去的。比如,需要换行时,不是敲入一个回车符,而是写入 <br>,如果要分段,就应该在段前写入 <p>。

  因此,格式化文档,就是在文档注释中添加相应的 HTML 标识。

  文档注释的正文并不是直接复制到输出文件 (文档的 HTML 文件),而是读取每一行后,删掉前导的 * 号及 * 号以前的空格,再输入到文档的。如

  /**
* This is first line. <br>
***** This is second line. <br>
This is third line.
*/

  编译输出后的 HTML 源码则是

  This is first line. <br>
This is second line. <br>
This is third line.

  前导的 * 号允许连续使用多个,其效果和使用一个 * 号一样,但多个 * 号前不能有其它字符分隔,否则分隔符及后面的 * 号都将作为文档的内容。* 号在这里是作为左边界使用,如上例的第一行和第二行;如果没有前导的 * 号,则边界从第一个有效字符开始,而不包括前面的空格,如上例第三行。

  还有一点需要说明,文档注释只说明紧接其后的类、属性或者方法。如下例:

  /** comment for class */
public class Test {

/** comment for a attribute */
int number;

/** comment for a method */
public void myMethod() { …… }

……
}

  上例中的三处注释就是分别对类、属性和方法的文档注释。它们生成的文档分别是说明紧接其后的类、属性、方法的。“紧接”二字尤其重要,如果忽略 了这一点,就很可能造成生成的文档错误。如

  import java.lang.*;

/** commnet for class */

public class Test { …… }

// 此例为正确的例子

  这个文档注释将生成正确的文档。但只需要改变其中两行的位置,变成下例,就会出错:

  /** commnet for class */

import java.lang.*;

public class Test { …… }

// 此例为错误的例子

  这个例子只把上例的 import 语句和文档注释部分交换了位置,结果却大不相同——生成的文档中根本就找不到上述注释的内容了。原因何在?

  “/** commnet for class */”是对 class Test 的说明,把它放在“public class Test { …… }”之前时,其后紧接着 class Test,符合规则,所以生成的文档正确。但是把它和“import java.lang.*;”调换了位置后,其后紧接的就是不 class Test 了,而是一个 import 语句。由于文档注释只能说明类、属性和方法,import 语句不在此列,所以这个文档注释就被当作错误说明省略掉了。

  2. 文档注释的三部分

  根据在文档中显示的效果,文档注释分为三部分。先举例如下,以便说明。

  /**
* show 方法的简述.
* <p>show 方法的详细说明第一行<br>
* show 方法的详细说明第二行
* @param b true 表示显示,false 表示隐藏
* @return 没有返回值
*/
public void show(boolean b) {
frame.show(b);
}

  第一部分是简述。文档中,对于属性和方法都是先有一个列表,然后才在后面一个一个的详细的说明。列表中属性名或者方法名后面那段说明就是简述。 如下图中被红框框选的部分:

  简述部分写在一段文档注释的最前面,第一个点号 (.) 之前 (包括点号)。换句话说,就是用第一个点号分隔文档注释,之前是简述,之后是第二部分和第三部分。如上例中的 “* show 方法的简述.”。

  有时,即使正确地以一个点号作为分隔,javadoc 仍然会出错,把点号后面的部分也做为了第一部分。为了解决这个问题,我们可以使用一个 <p> 标志将第二分部分开为下一段,如上例的“* <p>show 方法的详细说明第一行 ….”。除此之外,我们也可以使用 <br> 来分隔。

  第二部分是详细说明部分。该部分对属性或者方法进行详细的说明,在格式上没有什么特殊的要求,可以包含若干个点号。它在文档中的位置如 下图所示:

  这部分文档在上例中相应的代码是:

  * show 方法的简述.
* <p>show 方法的详细说明第一行<br>
* show 方法的详细说明第二行

  发现什么了?对了,简述也在其中。这一点要记住了,不要画蛇添足——在详细说明部分中再写一次简述哦!

  第三部分是特殊说明部分。这部分包括版本说明、参数说明、返回值说明等。它在文档中的位置:

  第三部分在上例中相应的代码是

  * @param b true 表示显示,false 表示隐藏
* @return 没有返回值

  除了 @param 和 @return 之外,还有其它的一些特殊标记,分别用于对类、属性和方法的说明……不要推我,我马上就说。

三. 使用 javadoc 标记

  javadoc 标记是插入文档注释中的特殊标记,它们用于标识代码中的特殊引用。javadoc 标记由“@”及其后所跟的标记类型和专用注释引用组成。记住了,三个部分——@、标记类型、专用注释引用。不过我宁愿把它分成两部分:@ 和标记类型、专用注释引用。虽然 @ 和 标记类型之间有时可以用空格符分隔,但是我宁愿始终将它们紧挨着写,以减少出错机会。

  javadoc 标记有如下一些:

标记 用于 作用 @author 对类的说明 标明开发该类模块的作者 @version 对类的说明 标明该类模块的版本 @see 对类、属性、方法的说明 参考转向,也就是相关主题 @param 对方法的说明 对方法中某参数的说明 @return 对方法的说明 对方法返回值的说明 @exception 对方法的说明 对方法可能抛出的异常进行说明

  下面详细说明各标记。

  1. @see 的使用

  @see 的句法有三种:

  @see 类名
@see #方法名或属性名
@see 类名#方法名或属性名

  类名,可以根据需要只写出类名 (如 String) 或者写出类全名 (如 java.lang.String)。那么什么时候只需要写出类名,什么时候需要写出类全名呢?

  如果 java 源文件中的 import 语句包含了的类,可以只写出类名,如果没有包含,则需要写出类全名。java.lang 也已经默认被包含了。这和 javac 编译 java 源文件时的规定一样,所以可以简单的用 javac 编译来判断,源程序中 javac 能找到的类,javadoc 也一定能找到;javac 找不到的类,javadoc 也找不到,这就需要使用类全名了。

  方法名或者属性名,如果是属性名,则只需要写出属性名即可;如果是方法名,则需要写出方法名以及参数类型,没有参数的方法,需要写出一 对括号。如

成员类型 成员名称及参数 @see 句法 属性 number @see number 属性 count @see count 方法 count() @see count() 方法 show(boolean b) @see show(boolean) 方法 main(String[] args) @see main(String[])

  有时也可以偷懒:假如上例中,没有 count 这一属性,那么参考方法 count() 就可以简写成 @see count。不过,为了安全起见,还是写全 @see count() 比较好。

  @see 的第二个句法和第三个句法都是转向方法或者属性的参考,它们有什么区别呢?

  第二个句法中没有指出类名,则默认为当前类。所以它定义的参考,都转向本类中的属性或者方法。而第三个句法中指出了类名,则还可以转向 其它类的属性或者方法。

  关于 @see 标记,我们举个例说明。由于 @see 在对类说明、对属性说明、对方法说明时用法都一样,所以这里只以对类说明为例。

  /**
* @see String
* @see java.lang.StringBuffer
* @see #str
* @see #str()
* @see #main(String[])
* @see Object#toString()
*/
public class TestJavaDoc {

}

  生成的文档的相关部分如下图:

  String 和 StringBuffer 都是在 java.lang 包中,由于这个包是默认导入了的,所以这两个类可以直接写类名,也可以写类全名。str、str() 为同名属性和方法,所以方法名需要用 () 区分。main 是带参数的方法,所以在 () 中指明了参数类型。toString() 虽然在本类中也有 (从 Object 继承的),但我们是想参考 Object 类的 toString() 方法,所以使用了 Object#toString()。

  奇怪的是,为什么其中只有 str、str() 和 main(String[]) 变成了链接呢?那是因为编译时没有把 java.lang 包或者 Stirng、StringBuffer、Object 三个类的源文件一起加入编译,所以,生成的文档没有关于那三个类的信息,也就不可以建立链接了。后面讲解 javadoc 编译命令的时候还会详细说明。

  上例中如果去把类中的 str 属性去掉,那么生成的文档又会有什么变化呢?你会发现,原来是 str, str(),而现在变成了 str(), str(),因为 str 属性已经没有了,所以 str 也表示方法 str()。

  2. 使用 @author、@version 说明类

  这两个标记分别用于指明类的作者和版本。缺省情况下 javadoc 将其忽略,但命令行开关 -author 和 -version 可以修改这个功能,使其包含的信息被输出。这两个标记的句法如下:

  @author 作者名
@version 版本号

  其中,@author 可以多次使用,以指明多个作者,生成的文档中每个作者之间使用逗号 (,) 隔开。@version 也可以使用多次,只有第一次有效,生成的文档中只会显示第一次使用 @version 指明的版本号。如下例

  /**
* @author Fancy
* @author Bird
* @version Version 1.00
* @version Version 2.00
*/
public class TestJavaDoc {

}

  生成文档的相关部分如图:

  从生成文档的图示中可以看出,两个 @author 语句都被编译,在文档中生成了作者列表。而两个 @version 语句中只有第一句被编译了,只生成了一个版本号。

  从图上看,作者列表是以逗号分隔的,如果我想分行显示怎么办?另外,如果我想显示两个以上的版本号又该怎么办?

  ——我们可以将上述两条 @author 语句合为一句,把两个 @version 语句也合为一句:

  @author Fancy<br>Bird
@version Version 1.00<br>Version 2.00

  结果如图:

  我们这样做即达到了目的,又没有破坏规则。@author 之后的作者名和 @version 之后的版本号都可以是用户自己定义的任何 HTML 格式,所以我们可以使用 <br> 标记将其分行显示。同时,在一个 @version 中指明两个用 <br> 分隔的版本号,也没有破坏只显示第一个 @version 内容的规则。

  3. 使用 @param、@return 和 @exception 说明方法

  这三个标记都是只用于方法的。@param 描述方法的参数,@return 描述方法的返回值,@exception 描述方法可能抛出的异常。它们的句法如下:

  @param 参数名 参数说明
@return 返回值说明
@exception 异常类名 说明

  每一个 @param 只能描述方法的一个参数,所以,如果方法需要多个参数,就需要多次使用 @param 来描述。

  一个方法中只能用一个 @return,如果文档说明中列了多个 @return,则 javadoc 编译时会发出警告,且只有第一个 @return 在生成的文档中有效。

  方法可能抛出的异常应当用 @exception 描述。由于一个方法可能抛出多个异常,所以可以有多个 @exception。每个 @exception 后面应有简述的异常类名,说明中应指出抛出异常的原因。需要注意的是,异常类名应该根据源文件的 import 语句确定是写出类名还是类全名。   示例如下:

  public class TestJavaDoc {

/**
* @param n a switch
* @param b excrescent parameter
* @return true or false
* @return excrescent return
* @exception java.lang.Exception throw when switch is 1
* @exception NullPointerException throw when parameter n is null
*/
public boolean fun(Integer n) throws Exception {
switch (n.intValue()) {
case 0:
break;
case 1:
throw new Exception("Test Only");
default:
return false;
}
return true;
}

}

  使用 javadoc 编译生成的文档相关部分如下图:

  可以看到,上例中 @param b excrescent parameter 一句是多余的,因为参数只是一个 n,并没有一个 b 但是 javadoc 编译时并没有检查。因此,写文档注释时一定要正确匹配参数表与方法中正式参数表的项目。如果方法参数表中的参数是 a,文档中却给出对参数 x 的解释,或者再多出一个参数 i,就会让人摸不着头脑了。@exceptin 也是一样。

  上例程序中并没有抛出一个 NullPointerException,但是文档注释中为什么要写上这么一句呢,难道又是为了演示?这不是为了演示描述多余的异常也能通过编译,而是 为了说明写异常说明时应考运行时 (RunTime) 异常的可能性。上例程序中,如果参数 n 是给的一个空值 (null),那么程序会在运行的时候抛出一个 NullPointerException,因此,在文档注释中添加了对 NullPointerException 的说明。

  上例中的 @return 语句有两个,但是根据规则,同一个方法中,只有第一个 @return 有效,其余的会被 javadoc 忽略。所以生成的文档中没有出现第二个 @return 的描述。

  讲到这里,该怎么写文档注释你应该已经清楚了,下面就开始讲解 javadoc 的常用命令。

四. javadoc 命令

  运行 javadoc -help 可以看到 javadoc 的用法,这里列举常用参数如下:

用法:
javadoc [options] [packagenames] [sourcefiles]

选项:

  -public 仅显示 public 类和成员   -protected 显示 protected/public 类和成员 (缺省)   -package 显示 package/protected/public 类和成员   -private 显示所有类和成员   -d <directory> 输出文件的目标目录   -version 包含 @version 段   -author 包含 @author 段   -splitindex 将索引分为每个字母对应一个文件   -windowtitle <text> 文档的浏览器窗口标题

  javadoc 编译文档时可以给定包列表,也可以给出源程序文件列表。例如在 CLASSPATH 下有两个包若干类如下:

  fancy.Editor
fancy.Test
fancy.editor.ECommand
fancy.editor.EDocument
fancy.editor.EView

  这里有两个包 (fancy 和 fancy.editor) 和 5 个类。那么编译时 (Windows 环境) 可以使用如下 javadoc 命令:

  javadoc fancyTest.java fancyEditor.java fancyeditorECommand.java fancyeditorEDocument.java fancyeditorEView.java

  这是给出 java 源文件作为编译参数的方法,注意命令中指出的是文件路径,应该根据实际情况改变。也可以是给出包名作为编译参数,如:

  javadoc fancy fancy.editor

  用浏览器打开生成文档的 index.html 文件即可发现两种方式编译结果的不同,如下图:

  用第二条命令生成的文档被框架分成了三部分:包列表、类列表和类说明。在包列表中选择了某个包之后,类列表中就会列出该包中的所有类;在类列表 中选择了某个类之后,类说明部分就会显示出该类的详细文档。而用第一条命令生成的文档只有两部分,类列表和类说明,没有包列表。这就是两种方式生成文档的 最大区别了。

  下面再来细说选项。

  -public、-protected、-package、-private 四个选项,只需要任选其一即可。它们指定的显示类成员的程度。它们显示的成员多少是一个包含的关系,如下表:

-private (显示所有类和成员) -package (显示 package/protected/public 类和成员) -protected (显示 protected/public 类和成员) -public (仅显示 public 类和成员)

  -d 选项允许你定义输出目录。如果不用 -d 定义输出目录,生成的文档文件会放在当前目录下。-d 选项的用法是

  -d 目录名

  目录名为必填项,也就是说,如果你使用了 -d 参数,就一定要为它指定一个目录。这个目录必须已经存在了,如果还不存在,请在运行 javadoc 之前创建该目录。

  -version 和 -author 用于控制生成文档时是否生成 @version 和 @author 指定的内容。不加这两个参数的情况下,生成的文档中不包含版本和作者信息。

  -splitindex 选项将索引分为每个字母对应一个文件。默认情况下,索引文件只有一个,且该文件中包含所有索引内容。当然生成文档内容不多的时候,这样做非常合适,但是, 如果文档内容非常多的时候,这个索引文件将包含非常多的内容,显得过于庞大。使用 -splitindex 会把索引文件按各索引项的第一个字母进行分类,每个字母对应一个文件。这样,就减轻了一个索引文件的负担。

  -windowtitle 选项为文档指定一个标题,该标题会显示在窗口的标题栏上。如果不指定该标题,而默认的文档标题为“生成的文档(无标题)”。该选项的用法是:

  -windowtitle 标题

  标题是一串没有包含空格的文本,因为空格符是用于分隔各参数的,所以不能包含空格。同 -d 类似,如果指定了 -windowtitle 选项,则必须指定标题文本。

  到此为止,Java 文档和 javadoc 就介绍完了。javadoc 真的能让我们在 Java 注释上做文章——生成开发文档。

PHP错误: Exception thrown without a stack frame in Unknown on line 0

就目前我的了解,在两种情况下,PHP会报 Exception thrown without a stack frame in Unknown on line 0这种错误:

1)异常捕捉用了set_exception_handler导向,Exception里面执行另一个Exception

如下面这段代码,就会出现这种问题:

http://de.php.net/manual/de/function.set-exception-handler.php#88082

<?php
function error_handler($code, $message, $file, $line)
{
if (0 == error_reporting())
{
return;
}
throw new ErrorException($message, 0, $code, $file, $line);
}
function exception_handler($e)
{
// ... normal exception stuff goes here
print $undefined; // This is the underlying problem
}
set_error_handler("error_handler");
set_exception_handler("exception_handler");
throw new Exception("Just invoking the exception handler");
?>


exception_handler函数内print $undefined;这行本身会抛出一个异常,而他又去调用set_exception_handler的exception_handler函数,死循环了。

解决办法:不要在一个Exception里面执行另一个Exception

上面的问题可以用try ...
catch的方式,如exception_handler改成下面这样
<?php
function exception_handler($e)
{
try
{
// ... normal exception stuff goes here
print $undefined; // This is the underlying problem
}
catch (Exception $e)
{
print get_class($e)." thrown within the exception handler. Message: ".$e->getMessage()." on line ".$e->getLine();
}
}
?>

2) 在析构函数抛出异常

参考这个bug:http://bugs.php.net/bug.php?id=33598

下面的代码就会报这个错误:

class test {
function __construct() {
echo "Constructn";
}

function greet() {
echo "Hello Worldn";
}

function __destruct() {
echo "Destructn";
throw new Exception( ‘test’ );
}
}

$test = new test();
$test->greet();目前的解决办法:

1.不要在析构函数中抛出异常.

2.由于析构函数是在退出时执行的,所以要手动unset这种类,并catch该异常。

比如上面的例子,在最后加一行unset($test),这时程序就会报throw new Exception( ‘test’ ); 这行有错误,再catch这个异常就行了。

上面两种情况在php 5.2.11版本上都会出现,至于原因我认为PHP可能就是这样处理的,php bug 33598 2005年就报上去了,bug Status为Closed,说明官方并不认为这是一个bug,或不当一个bug处理了。

JAVA版PKCS5填充模式3DES加解密类

DESCoder.java:

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package des;
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/**
*
* @author FarmerLuo
*/
public class DESCoder {
    private static BASE64Encoder base64 = new BASE64Encoder();
    private static byte[] myIV = { 50, 51, 52, 53, 54, 55, 56, 57 };
    //private static String strkey = "W9qPIzjaVGKUp7CKRk/qpCkg/SCMkQRu"; // 字节数必须是8的倍数
    private static String strkey = "01234567890123456789012345678912";
    public static String desEncrypt(String input) throws Exception
    {

        BASE64Decoder base64d = new BASE64Decoder();
        DESedeKeySpec p8ksp = null;
        p8ksp = new DESedeKeySpec(base64d.decodeBuffer(strkey));
        Key key = null;
        key = SecretKeyFactory.getInstance("DESede").generateSecret(p8ksp);

        byte[] plainBytes = (byte[])null;
        Cipher cipher = null;
        byte[] cipherText = (byte[])null;

        plainBytes = input.getBytes("UTF8");
        cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        SecretKeySpec myKey = new SecretKeySpec(key.getEncoded(), "DESede");
        IvParameterSpec ivspec = new IvParameterSpec(myIV);
        cipher.init(1, myKey, ivspec);
        cipherText = cipher.doFinal(plainBytes);
        return removeBR(base64.encode(cipherText));

    }

    public static String desDecrypt(String cipherText) throws Exception
    {

        BASE64Decoder base64d = new BASE64Decoder();
        DESedeKeySpec p8ksp = null;
        p8ksp = new DESedeKeySpec(base64d.decodeBuffer(strkey));
        Key key = null;
        key = SecretKeyFactory.getInstance("DESede").generateSecret(p8ksp);

        Cipher cipher = null;
        byte[] inPut = base64d.decodeBuffer(cipherText);
        cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        SecretKeySpec myKey = new SecretKeySpec(key.getEncoded(), "DESede");
        IvParameterSpec ivspec = new IvParameterSpec(myIV);
        cipher.init(2, myKey, ivspec);
        byte[] output = cipher.doFinal(inPut);
        return new String(output, "UTF8");

    }

    private static String removeBR(String str) {
        StringBuffer sf = new StringBuffer(str);

        for (int i = 0; i < sf.length(); ++i)
        {
          if (sf.charAt(i) == ‘n’)
          {
            sf = sf.deleteCharAt(i);
          }
        }
        for (int i = 0; i < sf.length(); ++i)
          if (sf.charAt(i) == ‘r’)
          {
            sf = sf.deleteCharAt(i);
          }

        return sf.toString();
      }
}

Main.java:

package des;

/**
*
* @author FarmerLuo
*/
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        try {
            String desstr = DESCoder.desEncrypt("12354");
            String pstr = DESCoder.desDecrypt(desstr);
            System.out.println("plainText:12354");
            System.out.println("Encode:"+desstr);
            System.out.println("Decode:"+pstr);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

运行结果:

run:
plainText:12354
Encode:pzilYggKgBU=
Decode:12354
成功生成(总时间:1 秒)

PHP版3DES加解密类更新成PKCS5填充模式

以前写的3DES加解密类是配合java程序做的,用的是no-pading模式,这次在以前的基础上做了修改,改成了pkcs5填充模式。

以前的类:
http://hi.baidu.com/farmerluo/blog/item/6154a7effd4dd011fdfa3c8b.html

<?php

/**
*
* PHP版3DES加解密类
*
* 可与java的3DES(DESede)加密方式兼容
*
* @Author: Luo Hui (farmer.luo at gmail.com)
*
* @version: v0.2 2010.04.16
*
* @changelogs:
* V0.2 : 由之前的no-pading方式改为pkcs5方式
* V0.1 : 2008.12.04
*
*/

class Crypt3Des
{  
    public $key    = "01234567890123456789012345678912";
    public $iv    = "23456789"; //like java: private static byte[] myIV = { 50, 51, 52, 53, 54, 55, 56, 57 };
  
    //加密
    public function encrypt($input)
    {
   $size = mcrypt_get_block_size(‘tripledes’, ‘cbc’);
   $input = $this->pkcs5_pad($input, $size); //pkcs5填充方式
        $key = base64_decode($this->key);
        $td = mcrypt_module_open( MCRYPT_3DES, ”, MCRYPT_MODE_CBC, ”);
        //使用MCRYPT_3DES算法,cbc模式
        mcrypt_generic_init($td, $key, $this->iv);
        //初始处理
        $data = mcrypt_generic($td, $input);
        //加密
        mcrypt_generic_deinit($td);
        //结束
        mcrypt_module_close($td);
        $data = $this->removeBR(base64_encode($data));
        return $data;
    }
  
    //解密
    public function decrypt($encrypted)
    {
        $encrypted = base64_decode($encrypted);
        $key = base64_decode($this->key);
        $td = mcrypt_module_open( MCRYPT_3DES,”,MCRYPT_MODE_CBC,”);
        //使用MCRYPT_3DES算法,cbc模式
        mcrypt_generic_init($td, $key, $this->iv);
        //初始处理
        $decrypted = mdecrypt_generic($td, $encrypted);
        //解密
        mcrypt_generic_deinit($td);
        //结束
        mcrypt_module_close($td);
   $decrypted = $this->pkcs5_unpad($decrypted); //pkcs5填充方式
        return $decrypted;
    }
  
    //删除回车和换行
    public function removeBR( $str )
    {
        $len = strlen( $str );
        $newstr = "";
        $str = str_split($str);
        for ($i = 0; $i < $len; $i++ )
        {
            if ($str[$i] != ‘n’ and $str[$i] != ‘r’)
            {
                $newstr .= $str[$i];
            }
        }
  
        return $newstr;
    }

public function pkcs5_pad($text, $blocksize)
{
   $pad = $blocksize – (strlen($text) % $blocksize);
   return $text . str_repeat(chr($pad), $pad);
}

public function pkcs5_unpad($text)
{
   $pad = ord($text{strlen($text)-1});

   if ($pad > strlen($text)) return false;
  
   if (strspn($text, chr($pad), strlen($text) – $pad) != $pad) return false;
  
   return substr($text, 0, -1 * $pad);
}

}

//test
$input = "12354";
echo "plainText:" . $input."<br/>";
$crypt = new Crypt3Des();
echo "Encode:".$crypt->encrypt($input)."<br/>";
echo "Decode:".$crypt->decrypt($crypt->encrypt($input));
?>

运行结果:

plainText:12354
Encode:pzilYggKgBU=
Decode:12354

php pdo扩展连ms sql server有一个Bug

大部分时候都能连上,但每天会有一些连接不上的情况,会报下面的错误:

"PHP Fatal error:  Uncaught exception ‘PDOException’ with message ‘SQLSTATE[] (null) (severity 0)’

或:

PHP Fatal error:  Uncaught exception ‘PDOException’ with message ‘SQLSTATE[01002] Adaptive Server connection failed (severity 9)

PHP 5.2.9 及 PHP 5.2.11都有这个问题,Bug目前还没有解决。

准备用php的ms sql server扩展试试。

BUG信息如下:

http://bugs.php.net/bug.php?id=48539

http://bugs.php.net/bug.php?id=49344

初窥curl(下)

CURLOPT_FTPSSLAUTH
The FTP authentication method (when is activated): CURLFTPAUTH_SSL (try SSL first), CURLFTPAUTH_TLS (try TLS first), or CURLFTPAUTH_DEFAULT (let cURL decide).

CURLOPT_HTTP_VERSION
设置curl使用的HTTP协议,CURL_HTTP_VERSION_NONE(让curl自己判断),CURL_HTTP_VERSION_1_0(HTTP/1.0),CURL_HTTP_VERSION_1_1(HTTP/1.1)

CURLOPT_HTTPAUTH
使用的HTTP验证方法,可选的值 有:CURLAUTH_BASIC,CURLAUTH_DIGEST,CURLAUTH_GSSNEGOTIATE,CURLAUTH_NTLM,CURLAUTH_ANY,CURLAUTH_ANYSAFE, 可以使用“|”操作符分隔多个值,curl让服务器选择一个支持最好的值,CURLAUTH_ANY等价于CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_GSSNEGOTIATE | CURLAUTH_NTLM,CURLAUTH_ANYSAFE等价于CURLAUTH_DIGEST | CURLAUTH_GSSNEGOTIATE | CURLAUTH_NTLM

CURLOPT_INFILESIZE
设定上传文件的大小

CURLOPT_LOW_SPEED_LIMIT
当传输速度小于CURLOPT_LOW_SPEED_LIMIT时,PHP会根据CURLOPT_LOW_SPEED_TIME来判断是否因太慢而取消传输。

CURLOPT_LOW_SPEED_TIME
The number of seconds the transfer should be below CURLOPT_LOW_SPEED_LIMIT for PHP to consider the transfer too slow and abort.
当传输速度小于CURLOPT_LOW_SPEED_LIMIT时,PHP会根据CURLOPT_LOW_SPEED_TIME来判断是否因太慢而取消传输。

CURLOPT_MAXCONNECTS
允许的最大连接数量,超过是会通过CURLOPT_CLOSEPOLICY决定应该停止哪些连接

CURLOPT_MAXREDIRS
指定最多的HTTP重定向的数量,这个选项是和CURLOPT_FOLLOWLOCATION一起使用的。

CURLOPT_PORT
一个可选的用来指定连接端口的量

CURLOPT_PROXYAUTH
The HTTP authentication method(s) to use for the proxy connection. Use the same bitmasks as described in CURLOPT_HTTPAUTH. For proxy authentication, only CURLAUTH_BASIC and CURLAUTH_NTLM are currently supported.

CURLOPT_PROXYPORT
The port number of the proxy to connect to. This port number can also be set in CURLOPT_PROXY.

CURLOPT_PROXYTYPE
Either CURLPROXY_HTTP (default) or CURLPROXY_SOCKS5.

CURLOPT_RESUME_FROM
在恢复传输时传递一个字节偏移量(用来断点续传)

CURLOPT_SSL_VERIFYHOST
1 to check the existence of a common name in the SSL peer certificate.
2 to check the existence of a common name and also verify that it matches the hostname provided.

CURLOPT_SSLVERSION
The SSL version (2 or 3) to use. By default PHP will try to determine this itself, although in some cases this must be set manually.

CURLOPT_TIMECONDITION
如果在CURLOPT_TIMEVALUE指定的某个时间以后被编辑过,则使用CURL_TIMECOND_IFMODSINCE返回页面,如果没有被修 改过,并且CURLOPT_HEADER为true,则返回一个”304 Not Modified”的header,CURLOPT_HEADER为false,则使用CURL_TIMECOND_ISUNMODSINCE,默认值为 CURL_TIMECOND_IFMODSINCE

CURLOPT_TIMEOUT
设置curl允许执行的最长秒数

CURLOPT_TIMEVALUE
设置一个CURLOPT_TIMECONDITION使用的时间戳,在默认状态下使用的是CURL_TIMECOND_IFMODSINCE

CURLOPT_CAINFO
The name of a file holding one or more certificates to verify the peer with. This only makes sense when used in combination with CURLOPT_SSL_VERIFYPEER.

CURLOPT_CAPATH
A directory that holds multiple CA certificates. Use this option alongside CURLOPT_SSL_VERIFYPEER.

CURLOPT_COOKIE
设定HTTP请求中“Set-Cookie:”部分的内容。

CURLOPT_COOKIEFILE
包含cookie信息的文件名称,这个cookie文件可以是Netscape格式或者HTTP风格的header信息。

CURLOPT_COOKIEJAR
连接关闭以后,存放cookie信息的文件名称

CURLOPT_CUSTOMREQUEST
A custom request method to use instead of “GET” or “HEAD” when doing a HTTP request. This is useful for doing “DELETE” or other, more obscure HTTP requests. Valid values are things like “GET”, “POST”, “CONNECT” and so on; i.e. Do not enter a whole HTTP request line here. For instance, entering “GET /index.html HTTP/1.0rnrn” would be incorrect.
Note: Don’t do this without making sure the server supports the custom request method first.

CURLOPT_EGBSOCKET
Like CURLOPT_RANDOM_FILE, except a filename to an Entropy Gathering Daemon socket.

CURLOPT_ENCODING
header中“Accept-Encoding: ”部分的内容,支持的编码格式为:”identity”,”deflate”,”gzip”。如果设置为空字符串,则表示支持所有的编码格式

CURLOPT_FTPPORT
The value which will be used to get the IP address to use for the FTP “POST” instruction. The “POST” instruction tells the remote server to connect to our specified IP address. The string may be a plain IP address, a hostname, a network interface name (under Unix), or just a plain ‘-’ to use the systems default IP address.

CURLOPT_INTERFACE
在外部网络接口中使用的名称,可以是一个接口名,IP或者主机名。

CURLOPT_KRB4LEVEL
KRB4(Kerberos 4)安全级别的设置,可以是一下几个值之一:”clear”,”safe”,”confidential”,”private”。默认的值 为”private”,设置为null的时候表示禁用KRB4,现在KRB4安全仅能在FTP传输中使用。

CURLOPT_POSTFIELDS
在HTTP中的“POST”操作。如果要传送一个文件,需要一个@开头的文件名

CURLOPT_PROXY
设置通过的HTTP代理服务器

CURLOPT_PROXYUSERPWD
连接到代理服务器的,格式为“[username]:[password]”的用户名和密码。

CURLOPT_RANDOM_FILE
设定存放SSL用到的随机数种子的文件名称

CURLOPT_RANGE
设置HTTP传输范围,可以用“X-Y”的形式设置一个传输区间,如果有多个HTTP传输,则使用逗号分隔多个值,形如:”X-Y,N-M”。

CURLOPT_REFERER
设置header中”Referer: ” 部分的值。

CURLOPT_SSL_CIPHER_LIST
A list of ciphers to use for SSL. For example, RC4-SHA and TLSv1 are valid cipher lists.

CURLOPT_SSLCERT
传递一个包含PEM格式证书的字符串。

CURLOPT_SSLCERTPASSWD
传递一个包含使用CURLOPT_SSLCERT证书必需的密码。

CURLOPT_SSLCERTTYPE
The format of the certificate. Supported formats are “PEM” (default), “DER”, and “ENG”.

CURLOPT_SSLENGINE
The identifier for the crypto engine of the private SSL key specified in CURLOPT_SSLKEY.

CURLOPT_SSLENGINE_DEFAULT
The identifier for the crypto engine used for asymmetric crypto operations.

CURLOPT_SSLKEY
The name of a file containing a private SSL key.

CURLOPT_SSLKEYPASSWD
The secret password needed to use the private SSL key specified in CURLOPT_SSLKEY.
Note: Since this option contains a sensitive password, remember to keep the PHP script it is contained within safe.

CURLOPT_SSLKEYTYPE
The key type of the private SSL key specified in CURLOPT_SSLKEY. Supported key types are “PEM” (default), “DER”, and “ENG”.

CURLOPT_URL
需要获取的URL地址,也可以在PHP的curl_init()函数中设置。

CURLOPT_USERAGENT
在HTTP请求中包含一个”user-agent”头的字符串。

CURLOPT_USERPWD
传递一个连接中需要的用户名和密码,格式为:“[username]:[password]”。

CURLOPT_HTTP200ALIASES
设置不再以error的形式来处理HTTP 200的响应,格式为一个数组。

CURLOPT_HTTPHEADER
设置一个header中传输内容的数组。

CURLOPT_POSTQUOTE
An array of FTP commands to execute on the server after the FTP request has been performed.

CURLOPT_QUOTE
An array of FTP commands to execute on the server prior to the FTP request.

CURLOPT_FILE
设置输出文件的位置,值是一个资源类型,默认为STDOUT (浏览器)。

CURLOPT_INFILE
在上传文件的时候需要读取的文件地址,值是一个资源类型。

CURLOPT_STDERR
设置一个错误输出地址,值是一个资源类型,取代默认的STDERR。

CURLOPT_WRITEHEADER
设置header部分内容的写入的文件地址,值是一个资源类型。

CURLOPT_HEADERFUNCTION
设置一个回调函数,这个函数有两个参数,第一个是curl的资源句柄,第二个是输出的header数据。header数据的输出必须依赖这个函数,返回已写入的数据大小。

CURLOPT_PASSWDFUNCTION
设置一个回调函数,有三个参数,第一个是curl的资源句柄,第二个是一个密码提示符,第三个参数是密码长度允许的最大值。返回密码的值。

CURLOPT_READFUNCTION
设置一个回调函数,有两个参数,第一个是curl的资源句柄,第二个是读取到的数据。数据读取必须依赖这个函数。返回读取数据的大小,比如0或者EOF。

CURLOPT_WRITEFUNCTION
设置一个回调函数,有两个参数,第一个是curl的资源句柄,第二个是写入的数据。数据写入必须依赖这个函数。返回精确的已写入数据的大小

view plaincopy to clipboardprint?

  1. $ch = curl_init("http://www.bringsir.com/");  
  2. $another = curl_copy_handle($ch);  
  3. curl_exec($another);  
  4. curl_close($another);  

$ch = curl_init("http://www.bringsir.com/"); $another = curl_copy_handle($ch); curl_exec($another); curl_close($another);

curl_error()函数的作用是返回一个包含当前会话错误信息的字符串。
curl_errno()函数的作用是返回一个包含当前会话错误信息的数字编号。

curl_multi_init()函数的作用是初始化一个curl批处理句柄资源。
curl_multi_add_handle()函数的作用是向curl批处理会话中添加单独的curl句柄资源。curl_multi_add_handle()函数有两个参数,第一个参数表示一个curl批处理句柄资源,第二个参数表示一个单独的curl句柄资源。
curl_multi_exec()函数的作用是解析一个curl批处理句柄,curl_multi_exec()函数有两个参数,第一个参数表示一个批处理句柄资源,第二个参数是一个引用值的参数,表示剩余需要处理的单个的curl句柄资源数量。
curl_multi_remove_handle()函数表示移除curl批处理句柄资源中的某个句柄资源,curl_multi_remove_handle()函数有两个参数,第一个参数表示一个curl批处理句柄资源,第二个参数表示一个单独的curl句柄资源。
curl_multi_close()函数的作用是关闭一个批处理句柄资源。

view plaincopy to clipboardprint?

  1. $ch1 = curl_init();  
  2. $ch2 = curl_init();  
  3. curl_setopt($ch1, CURLOPT_URL, "http://www.baidu.com/");  
  4. curl_setopt($ch1, CURLOPT_HEADER, 0);  
  5. curl_setopt($ch2, CURLOPT_URL, "http://www.google.com/");  
  6. curl_setopt($ch2, CURLOPT_HEADER, 0);  
  7. $mh = curl_multi_init();  
  8. curl_multi_add_handle($mh,$ch1);  
  9. curl_multi_add_handle($mh,$ch2);  
  10. do {  
  11.  curl_multi_exec($mh,$flag);  
  12. } while ($flag > 0);  
  13. curl_multi_remove_handle($mh,$ch1);  
  14. curl_multi_remove_handle($mh,$ch2);  
  15. curl_multi_close($mh);  

$ch1 = curl_init(); $ch2 = curl_init(); curl_setopt($ch1, CURLOPT_URL, "http://www.baidu.com/"); curl_setopt($ch1, CURLOPT_HEADER, 0); curl_setopt($ch2, CURLOPT_URL, "http://www.google.com/"); curl_setopt($ch2, CURLOPT_HEADER, 0); $mh = curl_multi_init(); curl_multi_add_handle($mh,$ch1); curl_multi_add_handle($mh,$ch2); do { curl_multi_exec($mh,$flag); } while ($flag > 0); curl_multi_remove_handle($mh,$ch1); curl_multi_remove_handle($mh,$ch2); curl_multi_close($mh);

curl_multi_getcontent()函数的作用是在设置了CURLOPT_RETURNTRANSFER的情况下,返回获取的输出的文本流。

curl_multi_info_read()函数的作用是获取当前解析的curl的相关传输信息。

curl_multi_select()
Get all the sockets associated with the cURL extension, which can then be “selected”

这些例子很简单,就是用来理解函数用的,看的不爽,对吧?来一个实战的~

刷论坛代码(从其他地方拔出来的~嘿嘿)
1、抓cookies程序:

view plaincopy to clipboardprint?

  1. $URL="http://www.yoururl.com/bbs/login.asp?action=chk";  
  2. //填入论坛的登陆页面地址  
  3. $ch = curl_init();  
  4. curl_setopt($ch,CURLOPT_URL,$URL);  
  5.   
  6. curl_setopt($ch,CURLOPT_REFERER,"http://www.hxfoods.com/bbs/login.asp");  
  7. //设置,访问页面的来源地址  
  8.   
  9. curl_setopt($ch,CURLOPT_POST,1);  
  10. curl_setopt($ch,CURLOPT_POSTFIELDS,’username=→→敢死队→&password=168168′);  
  11. //分析登陆页面,把用户名,密码分别对应起来  
  12.   
  13. curl_setopt ($ch, CURLOPT_HEADER,true);  
  14. //使能显示http头  
  15.   
  16. curl_exec($ch);  
  17.   
  18. if (curl_errno($ch))  
  19. {  
  20. print curl_error($ch);  
  21. }  
  22. else  
  23. {  
  24. curl_close($ch);  
  25. }  

$URL="http://www.yoururl.com/bbs/login.asp?action=chk"; //填入论坛的登陆页面地址 $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,$URL); curl_setopt($ch,CURLOPT_REFERER,"http://www.hxfoods.com/bbs/login.asp"); //设置,访问页面的来源地址 curl_setopt($ch,CURLOPT_POST,1); curl_setopt($ch,CURLOPT_POSTFIELDS,’username=→→敢死队→&password=168168′); //分析登陆页面,把用户名,密码分别对应起来 curl_setopt ($ch, CURLOPT_HEADER,true); //使能显示http头 curl_exec($ch); if (curl_errno($ch)) { print curl_error($ch); } else { curl_close($ch); }

2、刷楼了:

view plaincopy to clipboardprint?

  1. set_time_limit(0);  
  2. //设置程序执行时间无限制  
  3. $i=10000;  
  4. //耍10000次  
  5. for($j=0;$j<$i;$j++)  
  6. {  
  7.   
  8. $URL="http://www.yoururl.com/bbs/savepost.asp";  
  9. //这个地址是回复表单里面action的url地址  
  10.   
  11. $ch = curl_init();  
  12. curl_setopt($ch,CURLOPT_URL,$URL);  
  13. curl_setopt($ch,CURLOPT_REFERER,"http://www.hxfoods.com/bbs/dispbbs.asp?boardid=14&replyid=672709&id=127437&page=1&skin=0&Star=53");  
  14. //设置来源地址,如果不设置,论坛服务器有可能有验证不允许回复  
  15.   
  16. curl_setopt($ch,CURLOPT_COOKIESESSION,true);  
  17. //能保存cookie  
  18. curl_setopt($ch,CURLOPT_COOKIE,"DvForum=userid=24122&usercookies=0&userhidden=2&password=w0reu3g775VrY745&userclass=%96%7C&username=%A1%FA%A1%FA%B8%D2%CB%C0%B6%D3%A1%FA&StatUserID=2194783945 ");  
  19. //这儿就是设置cookie了  
  20.   
  21. curl_setopt($ch,CURLOPT_POST,1);  
  22. curl_setopt($ch,CURLOPT_NOBODY,1);  
  23. //不显示内容,因为有很多论坛回复后要自动跳转。  
  24.   
  25. curl_setopt($ch,CURLOPT_POSTFIELDS,’Body=gfdfgdfgasdfgdfgdfgdfg& amp; followup=672709&RootID=127437&star=58& TotalUseTable=Dv_bbs3& amp;UserName=→→敢死队→&signflag=1& total=65535′);  
  26. //把你分析的回复表单的参数分别赋值  
  27.   
  28. curl_setopt ($ch, CURLOPT_HEADER,true);  
  29. curl_exec($ch);  
  30. if (curl_errno($ch))  
  31. {  
  32. print curl_error($ch);  
  33. }  
  34. else  
  35. {  
  36. curl_close($ch);  
  37. }  

初窥curl(上)

  1. function isRealUrl($url){  
  2.     $ch = curl_init();  
  3.     $options = array(  
  4.        CURLOPT_URL => $url,  
  5.        CURLOPT_HEADER => true,  
  6.        CURLOPT_RETURNTRANSFER => true,  
  7.        CURLOPT_NOBODY => true  
  8.        );  
  9.     curl_setopt_array($ch, $options);  
  10.     curl_exec($ch);  
  11.     if(!curl_errno($ch)){  
  12.         return 200==curl_getinfo($ch,CURLINFO_HTTP_CODE)? ’yes’:’no’;  
  13.     }else{  
  14.         return curl_error($ch);  
  15.     }  
  16.     curl_close($ch);  
  17. }  

function isRealUrl($url){ $ch = curl_init(); $options = array( CURLOPT_URL => $url, CURLOPT_HEADER => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_NOBODY => true ); curl_setopt_array($ch, $options); curl_exec($ch); if(!curl_errno($ch)){ return 200==curl_getinfo($ch,CURLINFO_HTTP_CODE)? ‘yes’:’no’; }else{ return curl_error($ch); } curl_close($ch); }

上面这个函数是用来判断所给的链接是不是可以访问!

网上看到的一些资料:
函数列表CURL库一共有17个函数:
curl_close:关闭CURL会话
curl_copy_handle:复制一个CURL会话句柄,同时3复制其所有参数
curl_errno:返回最后一个错误码
curl_error:返回一个字符串,用以描述当前会话的最后一个错误
curl_exec:执行当前会话
curl_getinfo:获取特定信息
curl_init:初始化CURL会话
curl_multi_add_handle:在一个多连接会话中添加一个句柄
curl_multi_close:关闭一个多句柄CRUL会话
curl_multi_exec:执行一个多句柄CURL会话
curl_multi_getcontent:返回一个句柄执行后的内容,如果设置了CURLOPT_RETURNTRANSFER
curl_multi_info_read:获取当前所有连接的信息
curl_multi_init:初始化一个多句柄会话
curl_multi_remove_handle:从一个多句柄会话中删除一个句柄
curl_multi_select:获取所有绑定的套接字
curl_setopt:设置CURL传输选项
curl_version:获取CURL版本

常用设置选项布尔值选项:
CURLOPT_AUTOREFERER:当返回的信息头含有转向信息时,自动设置前向连接
CURLOPT_BINARYTRANSFER:TRUEtoreturntherawoutputwhenCURLOPT_RETURNTRANSFERisused.
CURLOPT_COOKIESESSION:标志为新的cookie会话,忽略之前设置的cookie会话
CURLOPT_CRLF:将Unix系统的换行符转换为Dos换行符
CURLOPT_DNS_USE_GLOBAL_CACHE:使用全局的DNS缓存
CURLOPT_FAILONERROR:忽略返回错误
CURLOPT_FILETIME:获取请求文档的修改日期,该日期可以用curl_getinfo()获取。
CURLOPT_FOLLOWLOCATION:紧随服务器返回的所有重定向信息
CURLOPT_FORBID_REUSE:当进程处理完毕后强制关闭会话,不再缓存供重用
CURLOPT_FRESH_CONNECT:强制建立一个新的会话,而不是重用缓存的会话
CURLOPT_HEADER:在返回的输出中包含响应头信息
CURLOPT_HTTPGET:设置HTTP请求方式为GET
CURLOPT_HTTPPROXYTUNNEL:经由一个HTTP代理建立连接
CURLOPT_NOBODY:返回的输出中不包含文档信息.
CURLOPT_NOPROGRESS:如果你不会PHP为CURL传输显示一个进程条,设置这个选项为一个非零值。注意:PHP自动设置这个选项为非零值,你应该仅仅为了调试的目的来改变这个选项。
CURLOPT_NOSIGNAL:忽略所有发往PHP的信息
CURLOPT_POST:设置POST方式提交数据,POST格式为application/x-www-form-urlencoded
CURLOPT_PUTTRUE:设置PUT方式上传文件,同时设置CURLOPT_INFILE和CURLOPT_INFILESIZE
CURLOPT_RETURNTRANSFER:返回字符串,而不是调用curl_exec()后直接输出
CURLOPT_SSL_VERIFYPEER:SSL验证开启
CURLOPT_UNRESTRICTED_AUTH:一直链接后面附加用户名和密码,同时设置CURLOPT_FOLLOWLOCATION
CURLOPT_UPLOAD:准备上传

整数值选项:
CURLOPT_BUFFERSIZE:缓存大小
CURLOPT_CONNECTTIMEOUT:连接时间设置,默认0为无限制
CURLOPT_DNS_CACHE_TIMEOUT:内存中保存DNS信息的时间,默认2分钟
CURLOPT_INFILESIZE:上传至远程站点的文件尺寸
CURLOPT_LOW_SPEED_LIMIT:传输最低速度限制andabort.
CURLOPT_LOW_SPEED_TIME:传输时间限制
CURLOPT_MAXCONNECTS:最大持久连接数
CURLOPT_MAXREDIRS:最大转向数
CURLOPT_PORT:连接端口
CURLOPT_PROXYAUTH:代理服务器验证方式
CURLOPT_PROXYPORT:代理服务器端口
CURLOPT_PROXYTYPE:代理服务器类型
CURLOPT_TIMEOUT:CURL函数的最大执行时间
CURLOPT_VERBOSE:如果你想CURL报告每一件意外的事情,设置这个选项为一个非零值

字符串选项:
CURLOPT_COOKIE:HTTP头中set-cookie中的cookie信息
CURLOPT_COOKIEFILE:包含cookie信息的文件,cookie文件的格式可以是Netscape格式,或者只是HTTP头的格式
CURLOPT_COOKIEJAR:连接结束后保存cookie信息的文件
CURLOPT_CUSTOMREQUEST:自定义请求头,使用相对地址
CURLOPT_ENCODING:HTTP请求头中Accept-Encoding的值
CURLOPT_POSTFIELDS:POST格式提交的数据内容
CURLOPT_PROXY:代理通道
CURLOPT_PROXYUSERPWD:代理认证用户名和密码
CURLOPT_RANGE:返回数据的范围,以字节记
CURLOPT_REFERER:前向链接
CURLOPT_URL:要连接的URL地址,可以在curl_init()中设置
CURLOPT_USERAGENT:HTTP头中User-Agent的值
CURLOPT_USERPWD:连接种使用的验证信息

数组选项:
CURLOPT_HTTP200ALIASES:200响应码数组,数组中的响应吗被认为是正确的响应
CURLOPT_HTTPHEADER:自定义请求头信息

只能是流句柄的选项:
CURLOPT_FILE:传输要写入的晚间句柄,默认是标准输出
CURLOPT_INFILE:传输要读取的文件句柄
CURLOPT_STDERR:作为标准错误输出的一个替换选项
CURLOPT_WRITEHEADER:传输头信息要写入的文件

回调函数选项:
CURLOPT_HEADERFUNCTION:拥有两个参数的回调函数,第一个是参数是会话句柄,第二是HTTP响应头信息的字符串。使用此回调函数,将自行处理响应头信息。响应头信息按行返回。设置返回值为字符串长度。
CURLOPT_READFUNCTION:拥有两个参数的回调函数,第一个是参数是会话句柄,第二是HTTP响应头信息的字符串。使用此函数,将自行处理返回的数据。返回值为数据尺寸。
CURLOPT_WRITEFUNCTION:拥有两个参数的回调函数,第一个是参数是会话句柄,第二是HTTP响应头信息的字符串。使用此回调函数,将自行处理响应头信息。响应头信息是整个字符串。设置返回值为字符串长度。

上面稀里哗啦这么多东西,头晕吧??一开始接触这个,也感觉很混乱~而且手边也没有书籍教程专门来讲这个~GG了一番,筛选了几篇不错的资料整理一下~上面提到的就是curl比较常用的参数~
咱们继续看一些例子:

view plaincopy to clipboardprint?

  1. $ch = curl_init("http://www.bringsir.com/");  
  2. curl_exec($ch);  
  3. curl_close($ch);  
  4. //上面这个例子就不讲了吧?~  
  5.   
  6. $ch = curl_init("http://www.bringsir.com/");  
  7. print_r(curl_getinfo($ch));  
  8. //curl_getinfo()函数获取一个curl廉洁资源句柄的信息,它有两个参数:第一个参数是curl的资源句柄,第二个参数是下面一些常量:  

$ch = curl_init("http://www.bringsir.com/"); curl_exec($ch); curl_close($ch); //上面这个例子就不讲了吧?~ $ch = curl_init("http://www.bringsir.com/"); print_r(curl_getinfo($ch)); //curl_getinfo()函数获取一个curl廉洁资源句柄的信息,它有两个参数:第一个参数是curl的资源句柄,第二个参数是下面一些常量:

可选的常量包括:

CURLINFO_EFFECTIVE_URL
最后一个有效的url地址

CURLINFO_HTTP_CODE
最后一个收到的HTTP代码

CURLINFO_FILETIME
远程获取文档的时间,如果无法获取,则返回值为“-1”

CURLINFO_TOTAL_TIME
最后一次传输所消耗的时间

CURLINFO_NAMELOOKUP_TIME
名称解析所消耗的时间

CURLINFO_CONNECT_TIME
建立连接所消耗的时间

CURLINFO_PRETRANSFER_TIME
从建立连接到准备传输所使用的时间

CURLINFO_STARTTRANSFER_TIME
从建立连接到传输开始所使用的时间

CURLINFO_REDIRECT_TIME
在事务传输开始前重定向所使用的时间

CURLINFO_SIZE_UPLOAD
上传数据量的总值

CURLINFO_SIZE_DOWNLOAD
下载数据量的总值

CURLINFO_SPEED_DOWNLOAD
平均下载速度

CURLINFO_SPEED_UPLOAD
平均上传速度

CURLINFO_HEADER_SIZE
header部分的大小

CURLINFO_HEADER_OUT
发送请求的字符串

CURLINFO_REQUEST_SIZE
在HTTP请求中有问题的请求的大小

CURLINFO_SSL_VERIFYRESULT
Result of SSL certification verification requested by setting CURLOPT_SSL_VERIFYPEER

CURLINFO_CONTENT_LENGTH_DOWNLOAD
从Content-Length: field中读取的下载内容长度

CURLINFO_CONTENT_LENGTH_UPLOAD
上传内容大小的说明

CURLINFO_CONTENT_TYPE
下载内容的“Content-type”值,NULL表示服务器没有发送有效的“Content-Type: header”

curl_setopt()函数的作用是为一个curl设置会话参数。curl_setopt_array()函数的作用是以数组的形式为一个curl设置会话参数:

view plaincopy to clipboardprint?

  1. ch = curl_init();  
  2. $fp = fopen("example_homepage.txt", "w");  
  3. curl_setopt($ch, CURLOPT_FILE, $fp);  
  4. $options = array(  
  5.  CURLOPT_URL => ’http://www.bringsir.com/’,  
  6.  CURLOPT_HEADER => false  
  7.  );  
  8. curl_setopt_array($ch, $options);  
  9. curl_exec($ch);  
  10. curl_close($ch);  
  11. fclose($fp);  

ch = curl_init(); $fp = fopen("example_homepage.txt", "w"); curl_setopt($ch, CURLOPT_FILE, $fp); $options = array( CURLOPT_URL => ‘http://www.bringsir.com/’, CURLOPT_HEADER => false ); curl_setopt_array($ch, $options); curl_exec($ch); curl_close($ch); fclose($fp);

可设置的参数有:

CURLOPT_AUTOREFERER
自动设置header中的referer信息

CURLOPT_BINARYTRANSFER
在启用CURLOPT_RETURNTRANSFER时候将获取数据返回

CURLOPT_COOKIESESSION
启用时curl会仅仅传递一个session cookie,忽略其他的cookie,默认状况下curl会将所有的cookie返回给服务端。session cookie是指那些用来判断服务器端的session是否有效而存在的cookie。

CURLOPT_CRLF
启用时将Unix的换行符转换成回车换行符。

CURLOPT_DNS_USE_GLOBAL_CACHE
启用时会启用一个全局的DNS缓存,此项为线程安全的,并且默认为true。

CURLOPT_FAILONERROR
显示HTTP状态码,默认行为是忽略编号小于等于400的HTTP信息

CURLOPT_FILETIME
启用时会尝试修改远程文档中的信息。结果信息会通过curl_getinfo()函数的CURLINFO_FILETIME选项返回。

CURLOPT_FOLLOWLOCATION
启用时会将服务器服务器返回的“Location:”放在header中递归的返回给服务器,使用CURLOPT_MAXREDIRS可以限定递归返回的数量。

CURLOPT_FORBID_REUSE
在完成交互以后强迫断开连接,不能重用。

CURLOPT_FRESH_CONNECT
强制获取一个新的连接,替代缓存中的连接。

CURLOPT_FTP_USE_EPRT
TRUE to use EPRT (and LPRT) when doing active FTP downloads. Use FALSE to disable EPRT and LPRT and use PORT only.
Added in PHP 5.0.0.

CURLOPT_FTP_USE_EPSV
TRUE to first try an EPSV command for FTP transfers before reverting back to PASV. Set to FALSE to disable EPSV.

CURLOPT_FTPAPPEND
TRUE to append to the remote file instead of overwriting it.

CURLOPT_FTPASCII
An alias of CURLOPT_TRANSFERTEXT. Use that instead.

CURLOPT_FTPLISTONLY
TRUE to only list the names of an FTP directory.

CURLOPT_HEADER
启用时会将头文件的信息作为数据流输出。

CURLOPT_HTTPGET
启用时会设置HTTP的method为GET,因为GET是默认是,所以只在被修改的情况下使用。

CURLOPT_HTTPPROXYTUNNEL
启用时会通过HTTP代理来传输。

CURLOPT_MUTE
讲curl函数中所有修改过的参数恢复默认值。

CURLOPT_NETRC
在连接建立以后,访问~/.netrc文件获取用户名和密码信息连接远程站点。

CURLOPT_NOBODY
启用时将不对HTML中的body部分进行输出。

CURLOPT_NOPROGRESS
启用时关闭curl传输的进度条,此项的默认设置为true

CURLOPT_NOSIGNAL
启用时忽略所有的curl传递给php进行的信号。在SAPI多线程传输时此项被默认打开。

CURLOPT_POST
启用时会发送一个常规的POST请求,类型为:application/x-www-form-urlencoded,就像表单提交的一样。

CURLOPT_PUT
启用时允许HTTP发送文件,必须同时设置CURLOPT_INFILE和CURLOPT_INFILESIZE

CURLOPT_RETURNTRANSFER
讲curl_exec()获取的信息以文件流的形式返回,而不是直接输出。

CURLOPT_SSL_VERIFYPEER
FALSE to stop cURL from verifying the peer’s certificate. Alternate certificates to verify against can be specified with the CURLOPT_CAINFO option or a certificate directory can be specified with the CURLOPT_CAPATH option. CURLOPT_SSL_VERIFYHOST may also need to be TRUE or FALSE if CURLOPT_SSL_VERIFYPEER is disabled (it defaults to 2). TRUE by default as of cURL 7.10. Default bundle installed as of cURL 7.10.

CURLOPT_TRANSFERTEXT
TRUE to use ASCII mode for FTP transfers. For LDAP, it retrieves data in plain text instead of HTML. On Windows systems, it will not set STDOUT to binary mode.

CURLOPT_UNRESTRICTED_AUTH
在使用CURLOPT_FOLLOWLOCATION产生的header中的多个locations中持续追加用户名和密码信息,即使域名已发生改变。

CURLOPT_UPLOAD
启用时允许文件传输

CURLOPT_VERBOSE
启用时会汇报所有的信息,存放在STDERR或指定的CURLOPT_STDERR中

CURLOPT_BUFFERSIZE
每次获取的数据中读入缓存的大小,这个值每次都会被填满。

CURLOPT_CLOSEPOLICY
不是CURLCLOSEPOLICY_LEAST_RECENTLY_USED就是CURLCLOSEPOLICY_OLDEST,还存在另外三个,但是curl暂时还不支持。.

CURLOPT_CONNECTTIMEOUT
在发起连接前等待的时间,如果设置为0,则不等待。

CURLOPT_DNS_CACHE_TIMEOUT
设置在内存中保存DNS信息的时间,默认为120秒。

lsof 命令详解

lsof全名list opened files,也就是列举系统中已经被打开的文件。我们都知道,linux环境中,任何事物都是文件,设备是文件,目录是文件,甚至sockets也是文 件。所以,用好lsof命令,对日常的linux管理非常有帮助。以下的说明,大部分内容来自lsof的manual文档。我所做的只是在中文翻译的基础 上,进行简单的分类说明,并列举最常用的参数。

一、输出说明
lsof是linux最常用的命令之一,通常的输出格式为:

引用
COMMAND     PID   USER   FD      TYPE     DEVICE     SIZE       NODE NAME

常见包括如下几个字段:更多的可见manual。
1、COMMAND
默认以9个字符长度显示的命令名称。可使用+c参数指定显示的宽度,若+c后跟的参数为零,则显示命令的全名
2、PID:进程的ID号
3、PPID
父进程的IP号,默认不显示,当使用-R参数可打开。
4、PGID
进程组的ID编号,默认也不会显示,当使用-g参数时可打开。
5、USER
命令的执行UID或系统中登陆的用户名称。默认显示为用户名,当使用-l参数时,可显示UID。
6、FD
是文件的File Descriptor number,或者如下的内容:
(这里很难翻译对应的意思,保留英文)

引用
cwd  current working directory;
Lnn  library references (AIX);
jld  jail directory (FreeBSD);
ltx  shared library text (code and data);
Mxx  hex memory-mapped type number xx.
m86  DOS Merge mapped file;
mem  memory-mapped file;
mmap memory-mapped device;
pd   parent directory;
rtd  root directory;
tr   kernel trace file (OpenBSD);
txt  program text (code and data);
v86  VP/ix mapped file;

文件的File Descriptor number显示模式有:

引用
r for read access;
w for write access;
u for read and write access;
N for a Solaris NFS lock of unknown type;
r for read lock on part of the file;
R for a read lock on the entire file;
w for a write lock on part of the file;
W for a write lock on the entire file;
u for a read and write lock of any length;
U for a lock of unknown type;
x for an SCO OpenServer Xenix lock on part  of the file;
X  for an SCO OpenServer Xenix lock on the entire file;
space if there is no lock.

7、TYPE

引用
IPv4 IPv4的包;
IPv6 使用IPv6格式的包,即使地址是IPv4的,也会显示为IPv6,而映射到IPv6的地址;
DIR 目录
LINK 链接文件

详情请看manual中更多的注释。
8、DEVICE
使用character special、block special表示的设备号
9、SIZE
文件的大小,如果不能用大小表示的,会留空。使用-s参数控制。
10、NODE
本地文件的node码,或者协议,如TCP等
11、NAME
挂载点和文件的全路径(链接会被解析为实际路径),或者连接双方的地址和端口、状态等

二、参数
1、不带额外参数运行

lsof path/filename

显示已打开该目录或文件的所有进程信息

lsof `which httpd`

显示指定命令的信息
2、参见参数
-c w 显示以w开头命令的已打开文件的信息

lsof -c sshd

-p PID 显示指定PID已打开文件的信息

lsof -p 4401

+d dir 依照文件夹dir来搜寻,但不会打开子目录

lsof +d /root

+D dir 打开dir文件夹以及其子目录搜寻

lsof +D /root/

-d s 以FD列的信息进行匹配,可使用3-10,表示范围,3,10表示某些值

lsof -d 3-10

-u 显示某用户的已经打开的文件(或该用户执行程序已经打开的文件)

lsof -u root
lsof -u 0

◎可配合正规表达式使用
表示不包括root用户的信息:

lsof -u ^root

-i 监听指定的协议、端口、主机等的网络信息,格式为:

引用
[46][proto][@host|addr][:svc_list|port_list]

例如:

lsof -i为防备电子邮件地址收集器,这个 E-mail 地址被隐藏,你的浏览器必须支持 Javascript 才可看到这个邮件地址
lsof -i:22

还可以使用一些参数控制显示结果:

引用
-l 禁止将userID转换为登陆名称,即显示UID
-n 禁止将IP地址转换为hostname主机文件
-P 不显示端口名称

-g s 从PGID列进行匹配

lsof -g 3-10

3、其他参数
+f 所有路径参数都必须是文件系统,否则不能执行
-f 所有路径参数都将作为普通的文件,例如:"-f — /"中的/,只会匹配单个/路径,而不会是根目录中的所有文件
+f和-f后都应加上“–”表终结符:

lsof -f — /

+L/-L 打开或关闭文件的连结数计算,当+L没有指定时,所有的连结数都会显示(默认);若+L后指定数字,则只要连结数小于该数字的信息会显示;连结数会显示在NLINK列。
例如:+L1将显示没有unlinked的文件信息;+aL1,则显示指定文件系统所有unlinked的文件信息
-L 默认参数,其后不能跟数字,将不显示连结数信息

lsof +L1

-t 仅打印进程,方便shell脚本调用

lsof -t -c sshd

-F 指定输出那个列,可通过lsof -F?查看
-r 不断执行lsof命令,默认每15秒间隔执行一次
+r 也是不断执行lsof命令,但直到没有接受到文件信息,则停止

nmap 命令的用法

nmap
nmap是一个网络探测和安全扫描程序,系统管理者和个人可以使用这个软件扫描大型的网络,获取那台主机正在运行以及提供什么服务 等信息。nmap支持很多扫描技术,例如:UDP、TCP connect()、TCP SYN(半开扫描)、ftp代理(bounce攻击)、反向标志、ICMP、FIN、ACK扫描、圣诞树(Xmas Tree)、SYN扫描和null扫描。从扫描类型一节可以得到细节。nmap还提供了一些高级的特征,例如:通过TCP/IP协议栈特征探测操作系统类 型,秘密扫描,动态延时和重传计算,并行扫描,通过并行ping扫描探测关闭的主机,诱饵扫描,避开端口过滤检测,直接RPC扫描(无须端口影射),碎片 扫描,以及灵活的目标和端口设定.

——————————————————————————–
1.名称

nmap-网络探测和安全扫描工具

2.语法

nmap [Scan Type(s)] [Options]

3.描述

  nmap是一个网络探测和安全扫描程序,系统管理者和个人可以使用这个软件扫描大型的网络,获取那台主机正在运行以及提供什么服务等信息。 nmap支持很多扫描技术,例如:UDP、TCP connect()、TCP SYN(半开扫描)、ftp代理(bounce攻击)、反向标志、ICMP、FIN、ACK扫描、圣诞树(Xmas Tree)、SYN扫描和null扫描。从扫描类型一节可以得到细节。nmap还提供了一些高级的特征,例如:通过TCP/IP协议栈特征探测操作系统类 型,秘密扫描,动态延时和重传计算,并行扫描,通过并行ping扫描探测关闭的主机,诱饵扫描,避开端口过滤检测,直接RPC扫描(无须端口影射),碎片 扫描,以及灵活的目标和端口设定。

  为了提高nmap在non-root状态下的性能,软件的设计者付出了很大的努力。很不幸,一些内核界面(例如raw socket)需要在root状态下使用。所以应该尽可能在root使用nmap。

  nmap运行通常会得到被扫描主机端口的列表。nmap总会给出well known端口的服务名(如果可能)、端口号、状态和协议等信息。每个端口的状态有:open、filtered、unfiltered。open状态意 味着目标主机能够在这个端口使用accept()系统调用接受连接。filtered状态表示:防火墙、包过滤和其它的网络安全软件掩盖了这个端口,禁止 nmap探测其是否打开。unfiltered表示:这个端口关闭,并且没有防火墙/包过滤软件来隔离nmap的探测企图。通常情况下,端口的状态基本都 是unfiltered状态,只有在大多数被扫描的端口处于filtered状态下,才会显示处于unfiltered状态的端口。

  根据使用的功能选项,nmap也可以报告远程主机的下列特征:使用的操作系统、TCP序列、运行绑定到每个端口上的应用程序的用户名、DNS名、主机地址是否是欺骗地址、以及其它一些东西。

4.功能选项

  功能选项可以组合使用。一些功能选项只能够在某种扫描模式下使用。nmap会自动识别无效或者不支持的功能选项组合,并向用户发出警告信息。

  如果你是有经验的用户,可以略过结尾的示例一节。可以使用nmap -h快速列出功能选项的列表。

4.1 扫描类型

  -sT
TCP connect()扫描:这是最基本的TCP扫描方式。connect()是一种系统调用,由操作系统提供,用来打开一个连接。如果目标端口有程序监听, connect()就会成功返回,否则这个端口是不可达的。这项技术最大的优点是,你勿需root权限。任何UNIX用户都可以自由使用这个系统调用。这 种扫描很容易被检测到,在目标主机的日志中会记录大批的连接请求以及错误信息。
-sS
TCP同步扫描(TCP SYN):因为不必全部打开一个TCP连接,所以这项技术通常称为半开扫描(half-open)。你可以发出一个TCP同步包(SYN),然后等待回 应。如果对方返回SYN|ACK(响应)包就表示目标端口正在监听;如果返回RST数据包,就表示目标端口没有监听程序;如果收到一个SYN|ACK包, 源主机就会马上发出一个RST(复位)数据包断开和目标主机的连接,这实际上有我们的操作系统内核自动完成的。这项技术最大的好处是,很少有系统能够把这 记入系统日志。不过,你需要root权限来定制SYN数据包。
-sF -sF -sN
秘密FIN数据包扫描、圣诞树(Xmas Tree)、空(Null)扫描模式:即使SYN扫描都无法确定的情况下使用。一些防火墙和包过滤软件能够对发送到被限制端口的SYN数据包进行监视,而 且有些程序比如synlogger和courtney能够检测那些扫描。这些高级的扫描方式可以逃过这些干扰。这些扫描方式的理论依据是:关闭的端口需要 对你的探测包回应RST包,而打开的端口必需忽略有问题的包(参考RFC 793第64页)。FIN扫描使用暴露的FIN数据包来探测,而圣诞树扫描打开数据包的FIN、URG和PUSH标志。不幸的是,微软决定完全忽略这个标 准,另起炉灶。所以这种扫描方式对Windows95/NT无效。不过,从另外的角度讲,可以使用这种方式来分别两种不同的平台。如果使用这种扫描方式可 以发现打开的端口,你就可以确定目标注意运行的不是Windows系统。如果使用-sF、-sX或者-sN扫描显示所有的端口都是关闭的,而使用SYN扫 描显示有打开的端口,你可以确定目标主机可能运行的是Windwos系统。现在这种方式没有什么太大的用处,因为nmap有内嵌的操作系统检测功能。还有 其它几个系统使用和windows同样的处理方式,包括Cisco、BSDI、HP/UX、MYS、IRIX。在应该抛弃数据包时,以上这些系统都会从打 开的端口发出复位数据包。
-sP
ping扫描:有时你只是想知道此时网络上哪些主机正在运行。通过向你指定的网络内的每个IP地 址发送ICMP echo请求数据包,nmap就可以完成这项任务。如果主机正在运行就会作出响应。不幸的是,一些站点例如:microsoft.com阻塞ICMP echo请求数据包。然而,在默认的情况下nmap也能够向80端口发送TCP ack包,如果你收到一个RST包,就表示主机正在运行。nmap使用的第三种技术是:发送一个SYN包,然后等待一个RST或者SYN/ACK包。对于 非root用户,nmap使用connect()方法。
在默认的情况下(root用户),nmap并行使用ICMP和ACK技术。
注意,nmap在任何情况下都会进行ping扫描,只有目标主机处于运行状态,才会进行后续的扫描。如果你只是想知道目标主机是否运行,而不想进行其它扫描,才会用到这个选项。
-sU
UDP扫描:如果你想知道在某台主机上提供哪些UDP(用户数据报协议,RFC768)服务,可以使用这种扫描方法。nmap首先向目标主机的每个端口发出一个0字节的UDP包,如果我们收到端口不可达的ICMP消息,端口就是关闭的,否则我们就假设它是打开的。
有些人可能会想UDP扫描是没有什么意思的。但是,我经常会想到最近出现的solaris rpcbind缺陷。rpcbind隐藏在一个未公开的UDP端口上,这个端口号大于32770。所以即使端口111(portmap的众所周知端口号) 被防火墙阻塞有关系。但是你能发现大于30000的哪个端口上有程序正在监听吗?使用UDP扫描就能!cDc Back Orifice的后门程序就隐藏在Windows主机的一个可配置的UDP端口中。不考虑一些通常的安全缺陷,一些服务例如:snmp、tftp、NFS 使用UDP协议。不幸的是,UDP扫描有时非常缓慢,因为大多数主机限制ICMP错误信息的比例(在RFC1812中的建议)。例如,在Linux内核中 (在net/ipv4/icmp.h文件中)限制每4秒钟只能出现80条目标不可达的ICMP消息,如果超过这个比例,就会给1/4秒钟的处罚。 solaris的限制更加严格,每秒钟只允许出现大约2条ICMP不可达消息,这样,使扫描更加缓慢。nmap会检测这个限制的比例,减缓发送速度,而不 是发送大量的将被目标主机丢弃的无用数据包。
不过Micro$oft忽略了RFC1812的这个建议,不对这个比例做任何的限制。所以我们可以能够快速扫描运行Win95/NT的主机上的所有65K个端口。
-sA
ACK扫描:这项高级的扫描方法通常用来穿过防火墙的规则集。通常情况下,这有助于确定一个防火墙是功能比较完善的或者是一个简单的包过滤程序,只是阻塞进入的SYN包。
这种扫描是向特定的端口发送ACK包(使用随机的应答/序列号)。如果返回一个RST包,这个端口就标记为unfiltered状态。如果什么都没有返 回,或者返回一个不可达ICMP消息,这个端口就归入filtered类。注意,nmap通常不输出unfiltered的端口,所以在输出中通常不显示 所有被探测的端口。显然,这种扫描方式不能找出处于打开状态的端口。
-sW
对滑动窗口的扫描:这项高级扫描技术非常类似于ACK 扫描,除了它有时可以检测到处于打开状态的端口,因为滑动窗口的大小是不规则的,有些操作系统可以报告其大小。这些系统至少包括:某些版本的AIX、 Amiga、BeOS、BSDI、Cray、Tru64 UNIX、DG/UX、OpenVMS、Digital UNIX、OpenBSD、OpenStep、QNX、Rhapsody、SunOS 4.x、Ultrix、VAX、VXWORKS。从nmap-hackers邮件3列表的文档中可以得到完整的列表。
-sR
RPC扫描。这种方法和nmap的其它不同的端口扫描方法结合使用。选择所有处于打开状态的端口向它们发出SunRPC程序的NULL命令,以确定它们是 否是RPC端口,如果是,就确定是哪种软件及其版本号。因此你能够获得防火墙的一些信息。诱饵扫描现在还不能和RPC扫描结合使用。
-b
FTP反弹攻击(bounce attack):FTP协议(RFC 959)有一个很有意思的特征,它支持代理FTP连接。也就是说,我能够从evil.com连接到FTP服务器target.com,并且可以要求这台 FTP服务器为自己发送Internet上任何地方的文件!1985年,RFC959完成时,这个特征就能很好地工作了。然而,在今天的Internet 中,我们不能让人们劫持FTP服务器,让它向Internet上的任意节点发送数据。如同Hobbit在1995年写的文章中所说的,这个协议"能够用来 做投递虚拟的不可达邮件和新闻,进入各种站点的服务器,填满硬盘,跳过防火墙,以及其它的骚扰活动,而且很难进行追踪"。我们可以使用这个特征,在一台代 理FTP服务器扫描TCP端口。因此,你需要连接到防火墙后面的一台FTP服务器,接着进行端口扫描。如果在这台FTP服务器中有可读写的目录,你还可以 向目标端口任意发送数据(不过nmap不能为你做这些)。
传递给-b功能选项的参数是你要作为代理的FTP服务器。语法格式为:
-b username:password@server:port。
除了server以外,其余都是可选的。如果你想知道什么服务器有这种缺陷,可以参考我在Phrack 51发表的文章。还可以在nmap的站点得到这篇文章的最新版本。

4.2 通用选项

  这些内容不是必需的,但是很有用。

  -P0
在扫描之前,不必ping主机。有些网络的防火墙不允许ICMP echo请求穿过,使用这个选项可以对这些网络进行扫描。microsoft.com就是一个例子,因此在扫描这个站点时,你应该一直使用-P0或者-PT 80选项。
-PT
扫描之前,使用TCP ping确定哪些主机正在运行。nmap不是通过发送ICMP echo请求包然后等待响应来实现这种功能,而是向目标网络(或者单一主机)发出TCP ACK包然后等待回应。如果主机正在运行就会返回RST包。只有在目标网络/主机阻塞了ping包,而仍旧允许你对其进行扫描时,这个选项才有效。对于非 root用户,我们使用connect()系统调用来实现这项功能。使用-PT <端口号>来设定目标端口。默认的端口号是80,因为这个端口通常不会被过滤。
-PS
对于root用户,这个选项让nmap使用SYN包而不是ACK包来对目标主机进行扫描。如果主机正在运行就返回一个RST包(或者一个SYN/ACK包)。
-PI
设置这个选项,让nmap使用真正的ping(ICMP echo请求)来扫描目标主机是否正在运行。使用这个选项让nmap发现正在运行的主机的同时,nmap也会对你的直接子网广播地址进行观察。直接子网广 播地址一些外部可达的IP地址,把外部的包转换为一个内向的IP广播包,向一个计算机子网发送。这些IP广播包应该删除,因为会造成拒绝服务攻击(例如 smurf)。
-PB
这是默认的ping扫描选项。它使用ACK(-PT)和ICMP(-PI)两种扫描类型并行扫描。如果防火墙能够过滤其中一种包,使用这种方法,你就能够穿过防火墙。
-O
这个选项激活对TCP/IP指纹特征(fingerprinting)的扫描,获得远程主机的标志。换句话说,nmap使用一些技术检测目标主机操作系 统网络协议栈的特征。nmap使用这些信息建立远程主机的指纹特征,把它和已知的操作系统指纹特征数据库做比较,就可以知道目标主机操作系统的类型。
-I
这个选项打开nmap的反向标志扫描功能。Dave Goldsmith 1996年向bugtap发出的邮件注意到这个协议,ident协议(rfc 1413)允许使用TCP连接给出任何进程拥有者的用户名,即使这个进程并没有初始化连接。例如,你可以连接到HTTP端口,接着使用identd确定这 个服务器是否由root用户运行。这种扫描只能在同目标端口建立完全的TCP连接时(例如:-sT扫描选项)才能成功。使用-I选项是,远程主机的 identd精灵进程就会查询在每个打开的端口上监听的进程的拥有者。显然,如果远程主机没有运行identd程序,这种扫描方法无效。
-f
这个选项使nmap使用碎片IP数据包发送SYN、FIN、XMAS、NULL。使用碎片数据包增加包过滤、入侵检测系统的难度,使其无法知道你的企 图。不过,要慎重使用这个选项!有些程序在处理这些碎片包时会有麻烦,我最喜欢的嗅探器在接受到碎片包的头36个字节时,就会发生 segmentation faulted。因此,在nmap中使用了24个字节的碎片数据包。虽然包过滤器和防火墙不能防这种方法,但是有很多网络出于性能上的考虑,禁止数据包的 分片。
注意这个选项不能在所有的平台上使用。它在Linux、FreeBSD、OpenBSD以及其它一些UNIX系统能够很好工作。
-v
冗余模式。强烈推荐使用这个选项,它会给出扫描过程中的详细信息。使用这个选项,你可以得到事半功倍的效果。使用-d选项可以得到更加详细的信息。
-h
快速参考选项。
-oN
把扫描结果重定向到一个可读的文件logfilename中。
-oM
把扫描结果重定向到logfilename文件中,这个文件使用主机可以解析的语法。你可以使用-oM -来代替logfilename,这样输出就被重定向到标准输出stdout。在这种情况下,正常的输出将被覆盖,错误信息荏苒可以输出到标准错误 stderr。要注意,如果同时使用了-v选项,在屏幕上会打印出其它的信息。
-oS    thIs l0gz th3 r3suLtS of YouR ScanZ iN a s|   THe fiL3 U sPecfy 4s an arGuMEnT! U kAn gIv3 the 4rgument –
(wItHOUt qUOteZ) to sh00t output iNT0 stDouT!@!! 莫名其妙,下面是我猜着翻译的,相形字?
把扫描结果重定向到一个文件logfilename中,这个文件使用一种"黑客方言"的语法形式(作者开的玩笑?)。同样,使用-oS -就会把结果重定向到标准输出上。
-resume
某个网络扫描可能由于control-C或者网络损失等原因被中断,使用这个选项可以使扫描接着以前的扫描进行。logfilename是被取消扫描的 日志文件,它必须是可读形式或者机器可以解析的形式。而且接着进行的扫描不能增加新的选项,只能使用与被中断的扫描相同的选项。nmap会接着日志文件中 的最后一次成功扫描进行新的扫描。
-iL
从inputfilename文件中读取扫描的目标。在这个文件中要有一个主机或者网络的列表,由空格键、制表键或者回车键作为分割符。如果使用-iL -,nmap就会从标准输入stdin读取主机名字。你可以从指定目标一节得到更加详细的信息。
-iR
让nmap自己随机挑选主机进行扫描。
-p <端口范围>
这个选项让你选择要进行扫描的端口号的范围。例如,-p 23表示:只扫描目标主机的23号端口。-p 20-30,139,60000-表示:扫描20到30号端口,139号端口以及所有大于60000的端口。在默认情况下,nmap扫描从1到1024号 以及nmap-services文件(如果使用RPM软件包,一般在/usr/share/nmap/目录中)中定义的端口列表。
-F
快速扫描模式,只扫描在nmap-services文件中列出的端口。显然比扫描所有65535个端口要快。
-D
使用诱饵扫描方法对目标网络/主机进行扫描。如果nmap使用这种方法对目标网络进行扫描,那么从目标主机/网络的角度来看,扫描就象从其它主机 (decoy1,等)发出的。从而,即使目标主机的IDS(入侵检测系统)对端口扫描发出报警,它们也不可能知道哪个是真正发起扫描的地址,哪个是无辜 的。这种扫描方法可以有效地对付例如路由跟踪、response-dropping等积极的防御机制,能够很好地隐藏你的IP地址。
每个诱饵 主机名使用逗号分割开,你也可以使用ME选项,它代表你自己的主机,和诱饵主机名混杂在一起。如果你把ME放在第六或者更靠后的位置,一些端口扫描检测软 件几乎根本不会显示你的IP地址。如果你不使用ME选项,nmap会把你的IP地址随机夹杂在诱饵主机之中。
注意:你用来作为诱饵的主机应该 正在运行或者你只是偶尔向目标发送SYN数据包。很显然,如果在网络上只有一台主机运行,目标将很轻松就会确定是哪台主机进行的扫描。或许,你还要直接使 用诱饵的IP地址而不是其域名,这样诱饵网络的域名服务器的日志上就不会留下关于你的记录。
还要注意:一些愚蠢的端口扫描检测软件会拒绝路由试图进行端口扫描的主机。因而,你需要让目标主机和一些诱饵断开连接。如果诱饵是目标主机的网关或者就是其自己时,会给目标主机造成很大问题。所以你需要慎重使用这个选项。
诱饵扫描既可以在起始的ping扫描也可以在真正的扫描状态下使用。它也可以和-O选项组合使用。
使用太多的诱饵扫描能够减缓你的扫描速度甚至可能造成扫描结果不正确。同时,有些ISP会把你的欺骗包过滤掉。虽然现在大多数的ISP不会对此进行限制。
-S <IP_Address>
在一些情况下,nmap可能无法确定你的源地址(nmap会告诉你)。在这种情况下,可以使用这个选项给出你的IP地址。
在欺骗扫描时,也使用这个选项。使用这个选项可以让目标认为是其它的主机对自己进行扫描。
-e
告诉nmap使用哪个接口发送和接受数据包。nmap能够自动对此接口进行检测,如果无效就会告诉你。
-g
设置扫描的源端口。一些天真的防火墙和包过滤器的规则集允许源端口为DNS(53)或者FTP-DATA(20)的包通过和实现连接。显然,如果攻击者 把源端口修改为20或者53,就可以摧毁防火墙的防护。在使用UDP扫描时,先使用53号端口;使用TCP扫描时,先使用20号端口。注意只有在能够使用 这个端口进行扫描时,nmap才会使用这个端口。例如,如果你无法进行TCP扫描,nmap会自动改变源端口,即使你使用了-g选项。
对于一些扫描,使用这个选项会造成性能上的微小损失,因为我有时会保存关于特定源端口的一些有用的信息。
-r
告诉nmap不要打乱被扫描端口的顺序。
–randomize_hosts
使nmap在扫描之前,打乱每组扫描中的主机顺序,nmap每组可以扫描最多2048台主机。这样,可以使扫描更不容易被网络监视器发现,尤其和–scan_delay 选项组合使用,更能有效避免被发现。
-M
设置进行TCP connect()扫描时,最多使用多少个套接字进行并行的扫描。使用这个选项可以降低扫描速度,避免远程目标宕机。

4.3 适时选项

  通常,nmap在运行时,能够很好地根据网络特点进行调整。扫描时,nmap会尽量减少被目标检测到的机会,同时尽可能加快扫描速度。然而,nmap默认的适时策略有时候不太适合你的目标。使用下面这些选项,可以控制nmap的扫描timing:

-T
设置nmap的适时策略。Paranoid:为了避开IDS的检测使扫描速度极慢,nmap串行所有的扫描,每隔至少5分钟发送一 个包; Sneaky:也差不多,只是数据包的发送间隔是15秒;Polite:不增加太大的网络负载,避免宕掉目标主机,串行每个探测,并且使每个探测有0.4 秒种的间隔;Normal:nmap默认的选项,在不是网络过载或者主机/端口丢失的情况下尽可能快速地扫描;Aggressive:设置5分钟的超时限 制,使对每台主机的扫描时间不超过5分钟,并且使对每次探测回应的等待时间不超过1.5秒钟;b>Insane:只适合快速的网络或者你不在意丢失 某些信息,每台主机的超时限制是75秒,对每次探测只等待0.3秒钟。你也可是使用数字来代替这些模式,例如:-T 0等于-T Paranoid,-T 5等于-T Insane。
这些适时模式不能下面的适时选项组合使用。
–host_timeout
设置扫描一台主机的时间,以毫秒为单位。默认的情况下,没有超时限制。
–max_rtt_timeout
设置对每次探测的等待时间,以毫秒为单位。如果超过这个时间限制就重传或者超时。默认值是大约9000毫秒。
–min_rtt_timeout
当目标主机的响应很快时,nmap就缩短每次探测的超时时间。这样会提高扫描的速度,但是可能丢失某些响应时间比较长的包。使用这个选项,可以让nmap对每次探测至少等待你指定的时间,以毫秒为单位。
–initial_rtt_timeout
设置初始探测的超时值。一般这个选项只在使用-P0选项扫描有防火墙保护的主机才有用。默认值是6000毫秒。
–max_parallelism
设置最大的并行扫描数量。–max_parallelism 1表示同时只扫描一个端口。这个选项对其它的并行扫描也有效,例如ping sweep, RPC scan。
–scan_delay
设置在两次探测之间,nmap必须等待的时间。这个选项主要用于降低网络的负载。

4.4 目标设定

  在nmap的所有参数中,只有目标参数是必须给出的。其最简单的形式是在命令行直接输入一个主机名或者一个IP地址。如果你希望扫描某个IP地 址的一个子网,你可以在主机名或者IP地址的后面加上/掩码。掩码在0(扫描整个网络)到32(只扫描这个主机)。使用/24扫描C类地址,/16扫描B 类地址。

  除此之外,nmap还有更加强大的表示方式让你更加灵活地指定IP地址。例如,如果要扫描这个B类网络128.210.*.*,你可以使用下面 三种方式来指定这些地址:128.210.*.*、128.21-.0-255.0-255或者128.210.0.0/16这三种形式是等价的。

5.例子

  本节将由浅入深地举例说明如何使用nmap。

nmap -v target.example.com
扫描主机target.example.com的所有TCP端口。-v打开冗余模式。

nmap -sS -O target.example.com/24
发起对target.example.com所在网络上的所有255个IP地址的秘密SYN扫描。同时还探测每台主机操作系统的指纹特征。需要root权限。

nmap -sX -p 22,53,110,143,4564 128.210.*.1-127
对B类IP地址128.210中255个可能的8位子网的前半部分发起圣诞树扫描。确定这些系统是否打开了sshd、DNS、pop3d、imapd和4564端口。注意圣诞树扫描对Micro$oft的系统无效,因为其协议栈的TCP层有缺陷。

nmap -v –randomize_hosts -p 80 *.*.2.3-5
只扫描指定的IP范围,有时用于对这个 Internet进行取样分析。nmap将寻找Internet上所有后两个字节是.2.3、.2.4、.2.5的 IP地址上的WEB服务器。如果你想发现更多有意思的主机,你可以使用127-222,因为在这个范围内有意思的主机密度更大。

host -l company.com | cut -d -f 4 | ./nmap -v -iL –
列出company.com网络的所有主机,让nmap进行扫描。注意:这项命令在GNU/Linux下使用。如果在其它平台,你可能要使用 其它的命令/选项。

原文地址 http://wuqinzhong.blog.163.com/blog/static/45222312006113144944229/