几个关于PHP的图片验证码

程序中用到的字体请替换成自己喜欢的。不提供下载。

 

1.验证码赋值给$_SESSION['verify']

 

<?php
session_start();
function GetVerify($length)
{
	$strings = Array('3','4','5','6','7','a','b','c','d','e','f','h','i','j','k','m','n','p','r','s','t','u','v','w','x','y');
	$chrNum = "";
	$count = count($strings);
	for ($i = 1; $i <= $length; $i++) { //循环随机取字符生成字符串$chrNum .= $strings[rand(0,$count-1)];
	}
	return $chrNum;
}
$fontSize = 15; //定义字体大小
$length = 4; //定义字符串长度
$strNum = GetVerify($length); //获取一个随机字符串
$_SESSION['verify'] = $strNum; //付值给session
$width = 70; //定义图片宽度
$height = 24; //定义图片高度
$im = imagecreate($width,$height); //生成一张指定宽高的图片
$backgroundcolor = imagecolorallocate ($im, 255, 255, 255); //生成背景色
$frameColor = imageColorAllocate($im, 150, 150, 150); //生成边框色
$font = realpath("arial.ttf"); //提取字体文件,开始写字
for($i = 0; $i < $length; $i++) {
	$charY = ($height+9)/2 + rand(-1,1); //定义字符Y坐标
	$charX = $i*15+8; //定义字符X坐标
	//生成字符颜色
	$text_color = imagecolorallocate($im, mt_rand(50, 200), mt_rand(50, 128), mt_rand(50, 200));
	$angle = rand(-20,20); //生成字符角度
	//写入字符
	imageTTFText($im, $fontSize, $angle, $charX, $charY, $text_color, $font, $strNum[$i]);
}
for($i=0; $i <= 5; $i++) { //循环画背景线
	$linecolor = imagecolorallocate($im, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
	$linex = mt_rand(1, $width-1);
	$liney = mt_rand(1, $height-1);
	imageline($im, $linex, $liney, $linex + mt_rand(0, 4) - 2, $liney + mt_rand(0, 4) - 2, $linecolor);
}
for($i=0; $i <= 32; $i++) { //循环画背景点,生成麻点效果
	$pointcolor = imagecolorallocate($im, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
	imagesetpixel($im, mt_rand(1, $width-1), mt_rand(1, $height-1), $pointcolor);
}
imagerectangle($im, 0, 0, $width-1 , $height-1 , $frameColor); //画边框
ob_clean();
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
/**
* 功能:生成随机字符串 
*/ 
exit;
?>

2.验证码赋值给$_SESSION['lgcode']

 

<?php
//获取随机字符

$rndstring = "";

for($i=0;$i<4;$i++){

	$rndstring .= chr(mt_rand(65,90));

}

//如果支持GD,则绘图

if(function_exists("imagecreate"))

{

	//PutCookie("dd_ckstr",strtolower($rndstring),1800,"/");

	session_register('lgcode');

	$_SESSION['lgcode'] = strtolower($rndstring);

	$rndcodelen = strlen($rndstring);

	//图片大小

	$im = imagecreate(50,20);

	//字体

	$font_type = dirname(__FILE__)."/./ant2.ttf";

	//背景颜色

	$bgcolor = ImageColorAllocate($im, 245,245,245);

	//边框色

	$iborder = ImageColorAllocate($im, 0x71,0x76,0x67);

	//字体色

	//不支持 imagettftext

	$fontColor = ImageColorAllocate($im, 0x50,0x4d,0x47);

	//支持 imagettftext

	$fontColor2 = ImageColorAllocate($im, 0x36,0x38,0x32);

	//阴影

	$fontColor1 = ImageColorAllocate($im, 0xbd,0xc0,0xb8);

	//杂点背景线

	//$lineColor1 = ImageColorAllocate($im, 130,220,245);

	//$lineColor2 = ImageColorAllocate($im, 225,245,255);

	//背景线

	//for($j=3;$j<=16;$j=$j+3) imageline($im,2,$j,48,$j,$lineColor1);

	//for($j=2;$j<52;$j=$j+(mt_rand(3,6))) imageline($im,$j,2,$j-6,18,$lineColor2);

	//边框

	imagerectangle($im, 0, 0, 49, 19, $iborder);

	$strposs = array();

	//文字

	for($i=0;$i<$rndcodelen;$i++){

		if(function_exists("imagettftext")){

			$strposs[$i][0] = $i*10+6;

			$strposs[$i][1] = mt_rand(15,18);

			imagettftext($im, 11, 5, $strposs[$i][0]+1, $strposs[$i][1]+1, $fontColor1, $font_type, $rndstring[$i]);

		}

		else{

			imagestring($im, 5, $i*10+6, mt_rand(2,4), $rndstring[$i], $fontColor);

		}

	}

	//文字

	for($i=0;$i<$rndcodelen;$i++){

		if(function_exists("imagettftext")){

			imagettftext($im, 11,5, $strposs[$i][0]-1, $strposs[$i][1]-1, $fontColor2, $font_type, $rndstring[$i]);

		}

	}

	header("Pragma:no-cache\r\n");

	header("Cache-Control:no-cache\r\n");

	header("Expires:0\r\n");

	//输出特定类型的图片格式,优先级为 gif -> jpg ->png

	if(function_exists("imagejpeg")){

		header("content-type:image/jpeg\r\n");

		imagejpeg($im);

	}else{

		header("content-type:image/png\r\n");

		imagepng($im);

	}

	ImageDestroy($im);

}else{ //不支持GD,只输出字母 ABCD

	//PutCookie("dd_ckstr","abcd",1800,"/");

	session_register('lgcode');

	$_SESSION['lgcode'] = "abcd";

	header("content-type:image/jpeg\r\n");

	header("Pragma:no-cache\r\n");

	header("Cache-Control:no-cache\r\n");

	header("Expires:0\r\n");

	$fp = fopen("./vdcode.jpg","r");

	echo fread($fp,filesize("./vdcode.jpg"));

	fclose($fp);

}

?>

3.需要根据给定点问题给出答案的,适用于留言

 

<?php
session_start();

function getCode ($length = 32, $mode = 0)
{
	switch ($mode) {
		case '1':
			$str = '123456789';
			break;
		case '2':
			$str = 'abcdefghijklmnopqrstuvwxyz';
			break;
		case '3':
			$str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
			break;
		case '4':
			$str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
			break;
		case '5':
			$str = 'ABCDEFGHIJKLMNPQRSTUVWXYZ123456789';
			break;
		case '6':
			$str = 'abcdefghijklmnopqrstuvwxyz1234567890';
			break;
		default:
			$str = 'ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789';
			break;
	}

	$result = '';
	$l = strlen($str)-1;
	for($i = 0;$i < $length;$i ++){
		$num = rand(0, $l);
		$result .= $str[$num];
	}
	return $result;
}
//建立验证图片
function createAuthNumImg($randStr,$imgW=100,$imgH=40,$fontName)
{
	header ("content-type: image/png");
	$image = imagecreate($imgW , $imgH);
	$color_white = imagecolorallocate($image , 255 , 255 , 255);
	$color_gray = imagecolorallocate($image , 228 , 228 , 228);
	$color_black = imagecolorallocate($image , 255 , 102 , 204);
	for ($i = 0 ; $i < 1000 ; $i++)
	{
		imagesetpixel($image , mt_rand(0 , $imgW) , mt_rand(0 , $imgH) , $color_gray);
	}
	imagerectangle($image , 0 , 0 , $imgW - 1 , $imgH - 1 , $color_gray);
	for ($i=10;$i<$imgH;$i+=10)imageline($image, 0, $i, $imgW, $i, $color_gray);
	imagettftext($image,16,5,3,25,$color_black,$fontName,$randStr);
	for ($i=10;$i<$imgW;$i+=10)imageline($image, $i, 0, $i, $imgH, $color_gray);
	imagepng($image);
	imagedestroy($image);
}
$a=GetCode(1,1);
$b=GetCode(1,1);
$c=GetCode(1,1);
$Passport=$a."+".$b."+".$c;
$Total=$a+$b+$c;
$_SESSION[$_GET['Action']]=md5(strtoupper($Total));
createAuthNumImg($Passport,$_GET['imgW'],$_GET['imgH'],"./verdana.ttf");
?>

PHP验证码

验证码示例:
 
调用:

<img src="verify_image.php" alt="点此刷新验证码" name="verify_code" width="65" height="20" border="0" id="verify_code" onclick="document.getElementByid('verify_code').src='verify_image.php?'+Math.random();" style="cursor:pointer;" />; 

程序:

<?php
session_start();

$vi = new vCodeImage;
$vi->SetImage(1,4,65,20,80,1);

class vCodeImage{
	/*******************************************************
	**FILENAME: verify_image.php
	**COPYRIGHT: NONE! (但请保留此信息)
	**AUTHOR: vsFree.Com
	**DATE: 2007-08-08
	********************************************************/

	var $mode;  //1:数字模式,2:字母模式,3:数字字母模式,其他:数字字母优化模式
	var $v_num;  //验证码个数
	var $img_w;  //验证码图像宽度
	var $img_h;  //验证码图像高度
	var $int_pixel_num;  //干扰像素个数
	var $int_line_num;  //干扰线条数
	var $font_dir;   //字体文件相对路径
	var $border;   //图像边框
	var $borderColor;  //图像边框颜色

	function SetImage($made,$v_num,$img_w,$img_h,$int_pixel_num,$int_line_num,$font_dir='../font',$border=true,$borderColor='255,200,85'){
		if(!isset($_SESSION['vCode'])){
			session_register('vCode');
		}
		$_SESSION['vCode']="";

		$this->mode = $made;
		$this->v_num = $v_num;
		$this->img_w = $img_w;
		$this->img_h = $img_h;
		$this->int_pixel_num = $int_pixel_num;
		$this->int_line_num = $int_line_num;
		$this->font_dir = $font_dir;
		$this->border = $border;
		$this->borderColor = $borderColor;
		$this->GenerateImage();
	}

	function GetChar($mode){
		if($mode == "1"){
			$ychar = "0,1,2,3,4,5,6,7,8,9";
		}
		else if($mode == "2"){
			$ychar = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
		}
		else if($mode == "3"){
			$ychar = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
		}
		else
		$ychar = "3,4,5,6,7,8,9,A,B,C,D,H,K,P,R,S,T,W,X,Y";
		return $ychar;
	}

	function RandColor($rs,$re,$gs,$ge,$bs,$be){
		$r = mt_rand($rs,$re);
		$g = mt_rand($gs,$ge);
		$b = mt_rand($bs,$be);
		return array($r,$g,$b);
	}

	function GenerateImage(){
		$im = imagecreate($this->img_w,$this->img_h);

		$black = imagecolorallocate($im, 0,0,0);
		$white = imagecolorallocate($im, 255,255,255);
		$bgcolor = imagecolorallocate($im, 250,250,250);

		imagefill($im,0,0,$bgcolor);

		$fonts = ScanDir($this->font_dir);
		$fmax = count($fonts) - 2;

		$ychar = $this->GetChar($this->mode);
		$list = explode(",",$ychar);

		$x = mt_rand(2,$this->img_w/($this->v_num+2));
		$cmax = count($list) - 1;

		$v_code = '';

		for($i=0;$i<$this->v_num;$i++) //验证码
		{
			$randnum = mt_rand(0,$cmax);
			$this_char = $list[$randnum];
			$v_code .= $this_char;
			$size = mt_rand(intval($this->img_w/5),intval($this->img_w/4));
			$angle = mt_rand(-20,20);
			$y = mt_rand(($size+2),($this->img_h-2));
			if($this->border)
			$y = mt_rand(($size+3),($this->img_h-3));
			$rand_color = $this->RandColor(0,200,0,100,0,250);
			$randcolor = imagecolorallocate($im,$rand_color[0],$rand_color[1],$rand_color[2]);
			$fontrand = mt_rand(2, $fmax);
			$font = "$this->font_dir/".$fonts[$fontrand];
			imagettftext($im, $size, $angle, $x, $y, $randcolor, $font, $this_char);
			$x = $x + intval($this->img_w/($this->v_num+1));
		}

		for($i=0;$i<$this->int_pixel_num;$i++){//干扰像素
			$rand_color = $this->RandColor(50,250,0,250,50,250);
			$rand_color_pixel = imagecolorallocate($im,$rand_color[0],$rand_color[1],$rand_color[2]);
			imagesetpixel($im, mt_rand()%$this->img_w, mt_rand()%$this->img_h, $rand_color_pixel);
		}

		for($i=0;$i<$this->int_line_num;$i++){ //干扰线
			$rand_color = $this->RandColor(0,250,0,250,0,250);
			$rand_color_line = imagecolorallocate($im,$rand_color[0],$rand_color[1],$rand_color[2]);
			imageline($im, mt_rand(0,intval($this->img_w/3)), mt_rand(0,$this->img_h), mt_rand(intval($this->img_w - ($this->img_w/3)),$this->img_w), mt_rand(0,$this->img_h), $rand_color_line);
		}

		if($this->border) //画出边框
		{
			if(preg_match("/^\d{1,3},\d{1,3},\d{1,3}$/",$this->borderColor)){
				$borderColor = explode(',',$this->borderColor);
			}
			$border_color_line = imagecolorallocate($im,$borderColor[0],$borderColor[1],$borderColor[2]);
			imageline($im, 0, 0, $this->img_w, 0, $border_color_line); //上横
			imageline($im, 0, 0, 0, $this->img_h, $border_color_line); //左竖
			imageline($im, 0, $this->img_h-1, $this->img_w, $this->img_h-1, $border_color_line); //下横
			imageline($im, $this->img_w-1, 0, $this->img_w-1, $this->img_h, $border_color_line); //右竖
		}

		imageantialias($im,true); //抗锯齿

		$time = time();
		$_SESSION['vCode'] = $v_code."|".$time; //把验证码和生成时间负值给$_SESSION[vCode]

		//生成图像给浏览器
		if (function_exists("imagegif")) {
			header ("Content-type: image/gif");
			imagegif($im);
		}
		elseif (function_exists("imagepng")) {
			header ("Content-type: image/png");
			imagepng($im);
		}
		elseif (function_exists("imagejpeg")) {
			header ("Content-type: image/jpeg");
			imagejpeg($im, "", 80);
		}
		elseif (function_exists("imagewbmp")) {
			header ("Content-type: image/vnd.wap.wbmp");
			imagewbmp($im);
		}
		else
		die("No Image Support On This Server !");

		imagedestroy($im);
	}
}
?>

 

使用PHP的cURL库

使用PHP的cURL库可以简单和有效地去抓网页。你只需要运行一个脚本,然后分析一下你所抓取的网页,然后就可以以程序的方式得到你想要的数据了。无论是你想从从一个链接上取部分数据,或是取一个XML文件并把其导入数据库,那怕就是简单的获取网页内容,cURL 是一个功能强大的PHP库。本文主要讲述如果使用这个PHP库。

启用 cURL 设置

首先,我们得先要确定我们的PHP是否开启了这个库,你可以通过使用php_info()函数来得到这一信息。

<?php
    phpinfo();
?>

如果你可以在网页上看到下面的输出,那么表示cURL库已被开启。

phpinfo_curl

如果你看到的话,那么你需要设置你的PHP并开启这个库。如果你是在Windows平台下,那么非常简单,你需要改一改你的php.ini文件的设置,找到php_curl.dll,并取消前面的分号注释就行了。如下所示:

//取消下面的注释
extension=php_curl.dll

如果你是在Linux下面,那么,你需要重新编译你的PHP了,编辑时,你需要打开编译参数——在configure命令上加上“–with-curl” 参数。

一个小示例

如果一切就绪,下面是一个小例程:

<?php
// 初始化一个 cURL 对象
$curl = curl_init(); 

// 设置你需要抓取的URL
curl_setopt($curl, CURLOPT_URL, 'http://cocre.com');

// 设置header
curl_setopt($curl, CURLOPT_HEADER, 1);

// 设置cURL 参数,要求结果保存到字符串中还是输出到屏幕上。
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

// 运行cURL,请求网页
$data = curl_exec($curl);

// 关闭URL请求
curl_close($curl);

// 显示获得的数据
var_dump($data);

如何POST数据

上面是抓取网页的代码,下面则是向某个网页POST数据。假设我们有一个处理表单的网址http://www.example.com/sendSMS.php,其可以接受两个表单域,一个是电话号码,一个是短信内容。

<?php
    $phoneNumber = '13912345678';
    $message = 'This message was generated by curl and php';
    $curlPost = 'pNUMBER='  . urlencode($phoneNumber) . '&MESSAGE=' . urlencode($message) . '&SUBMIT=Send';
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'http://www.example.com/sendSMS.php');
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
    $data = curl_exec();
    curl_close($ch);
?>

从上面的程序我们可以看到,使用CURLOPT_POST设置HTTP协议的POST方法,而不是GET方法,然后以CURLOPT_POSTFIELDS设置POST的数据。

关于代理服务器

下面是一个如何使用代理服务器的示例。请注意其中高亮的代码,代码很简单,我就不用多说了。

<?php 
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'http://www.example.com');
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
    curl_setopt($ch, CURLOPT_PROXY, 'fakeproxy.com:1080');
    curl_setopt($ch, CURLOPT_PROXYUSERPWD, 'user:password');
    $data = curl_exec();
    curl_close($ch);
?>

关于SSL和Cookie

关于SSL也就是HTTPS协议,你只需要把CURLOPT_URL连接中的http://变成https://就可以了。当然,还有一个参数叫CURLOPT_SSL_VERIFYHOST可以设置为验证站点。

关于Cookie,你需要了解下面三个参数:

  • CURLOPT_COOKIE,在当面的会话中设置一个cookie
  • CURLOPT_COOKIEJAR,当会话结束的时候保存一个Cookie
  • CURLOPT_COOKIEFILE,Cookie的文件。

HTTP服务器认证

最后,我们来看一看HTTP服务器认证的情况。

<?php 
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'http://www.example.com');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    curl_setopt(CURLOPT_USERPWD, '[username]:[password]')

    $data = curl_exec();
    curl_close($ch);
?>

关于其它更多的内容,请大家参看相关的cURL手册吧。

Linux 的僵尸(zombie)进程

可能很少有人意识到,在一个进程调用了exit之后,该进程 并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构。在Linux进程的5种状态中,僵尸进程是非常特殊的一种,它已经放弃了几乎所 有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集,除此之外,僵尸进程不再占有 任何内存空间。

僵尸进程的来由,要追溯到Unix,Unix的设计者们设计这个东西并非是因为闲来无事想装装酷什么的。上面说到,僵尸进程中保存着很多对程序员和系统管理员非常重要的信息,首先,这个进程是怎么死亡的?是正常退出呢,还是出现了错误,还是被其它进程强迫退出的?也就是说,这个程序的退出码是什么?其次,这个进程占用的总系统CPU时间和总用户CPU时间分别是多少?发生页错误的数目和收到信号的数目。这些信息都被存储在僵尸进程中,试想如果没有僵尸进程,进程执行多长我们并不知道,一旦其退出,所有与之相关的信息都立刻都从系统中清除,而如果此时父进程或系统管理员需要用到,就只好干瞪眼了。

所以,进程退出后,系统会把该进程的状态变成Zombie,然后给上一定的时间等着父进程来收集其退出信息,因为可能父进程正忙于别的事情来不及收集,所以,使用Zombie状态表示进程退出了,正在等待父进程收集信息中。

Zombie进程不可以用kill命令清楚,因为进程已退出,如果需要清除这样的进程,那么需要清除其父进程,或是等很长的时间后被内核清除。因为Zombie的进程还占着个进程ID号呢,这样的进程如果很多的话,不利于系统的进程调度。

下面,让我们来看看一个示例:

/* zombie.c */
#include <sys/types.h>
#include <unistd.h>  main()
{
    pid_t pid; 
    pid=fork();
    if(pid<0) { /* 如果出错 */ 
        printf("error occurred!\n");
    }else if(pid==0){ /* 如果是子进程 */ 
        exit(0);
    }else{  /* 如果是父进程 */ 
        sleep(60);  /* 休眠60秒 */ 
        wait(NULL); /* 收集僵尸进程 */
    }
}

编译这个程序:

$ cc zombie.c -o zombie

后台运行程序,以使我们能够执行下一条命令

$ ./zombie &
[1] 1217

列一下系统内的进程

$ ps -ax
... ...
1137 pts/0 S 0:00 -bash
1217 pts/0 S 0:00 ./zombie
1218 pts/0 Z 0:00 [zombie]
1578 pts/0 R 0:00 ps -ax

其中的”Z”就是僵尸进程的标志,它表示1218号进程现在就是一个僵尸进程。

收集Zombie进程的信息,并终结这些僵尸进程,需要我们在父进程中使用waitpid调用和wait调用。这两者的作用都是收集僵尸进程留下的信息,同时使这个进程彻底消失。

解决两张网卡同时访问内外网问题

route 命令

Route
在本地 IP 路由表中显示和修改条目。使用不带参数的 route 可以显示帮助。

语法
route [-f] [-p] [Command [Destination] [mask Netmask] [Gateway] [metric Metric]] [if Interface]]

参数
-f
清除所有不是主路由(网掩码为 255.255.255.255 的路由)、环回网络路由(目标为 127.0.0.0,网掩码为 255.255.255.0 的路由)或多播路由(目标为 224.0.0.0,网掩码为 240.0.0.0 的路由)的条目的路由表。如果它与命令之一(例如 add、change 或 delete)结合使用,表会在运行命令之前清除。

-p
与 add 命令共同使用时,指定路由被添加到注册表并在启动 TCP/IP 协议的时候初始化 IP 路由表。默认情况下,启动 TCP/IP 协议时不会保存添加的路由。与 print 命令一起使用时,则显示永久路由列表。所有其它的命令都忽略此参数。永久路由存储在注册表中的位置是 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\PersistentRoutes。

Command
下表列出了有效的命令。
add 添加路由
change 更改现存路由
delete 删除路由
print 打印路由

Destination
指定路由的网络目标地址。目标地址可以是一个 IP 网络地址(其中网络地址的主机地址位设置为 0),对于主机路由是 IP 地址,对于默认路由是 0.0.0.0。

mask subnetmask
指定与网络目标地址相关联的网掩码(又称之为子网掩码)。子网掩码对于 IP 网络地址可以是一适当的子网掩码,对于主机路由是 255.255.255.255 ,对于默认路由是 0.0.0.0。如果忽略,则使用子网掩码 255.255.255.255。定义路由时由于目标地址和子网掩码之间的关系,目标地址不能比它对应的子网掩码更为详细。换句话说,如果子网掩码的一位是 0,则目标地址中的对应位就不能设置为 1。

Gateway
指定超过由网络目标和子网掩码定义的可达到的地址集的前一个或下一个跃点 IP 地址。对于本地连接的子网路由,网关地址是分配给连接子网接口的 IP 地址。对于要经过一个或多个路由器才可用到的远程路由,网关地址是一个分配给相邻路由器的、可直接达到的 IP 地址。

metric Metric
为路由指定所需跃点数的整数值(范围是 1 ~ 9999),它用来在路由表里的多个路由中选择与转发包中的目标地址最为匹配的路由。所选的路由具有最少的跃点数。跃点数能够反映跃点的数量、路径的速度、路径可靠性、路径吞吐量以及管理属性。

if Interface
指定目标可以到达的接口的接口索引。使用 route print 命令可以显示接口及其对应接口索引的列表。
对于接口索引可以使用十进制或十六进制的值。对于十六进制值,要在十六进制数的前面加上 0x。忽略if 参数时,接口由网关地址确定。

/?
在命令提示符显示帮助。

注释

路由表中跃点数一列的值较大是由于允许 TCP/IP 根据每个 LAN 接口的 IP 地址、子网掩码和默认网关的配置自动确定路由表中路由的跃点数造成的。默认启动的自动确定接口跃点数确定了每个接口的速度,调整了每个接口的路由跃点数,因此最快接口所创建的路由具有最低的跃点数。要删除大跃点数,请在每个 LAN 连接的 TCP/IP 协议的高级属性中禁用自动确定接口跃点数。

如果在 systemroot\System32\Drivers\Etc 文件夹的本地网络文件中存在适当的条目,名称可以用于Destination。只要名称可以通过“域名系统” (DNS) 查询这样的标准主机名解析技术分解为 IP 地址,就可以将其用于 Gateway,DNS 查询使用存储在 systemroot\System32\Drivers\Etc 文件夹下的本地主机文件和 NetBIOS 名称解析。

如果是 print 或 delete 命令,可以忽略 Gateway 参数,使用通配符来表示目标和网关。Destination 的值可以是由星号 指定的通配符。如果指定目标含有一个星号 或问号 (?),它被看作是通配符,只打印或删除匹配的目标路由。星号代表任意一字符序列,问号代表任一字符。例如, 10.*.1, 192.168.*、 127.* 和 *224* 都是星号通配符的有效使用。

使用了无效的目标和子网掩码(网掩码)值的组合,会显示“Route:bad gateway address netmask”错误消息。目标中有一位或多位设置为 1,而其在子网掩码中的对应位设置为 0 时会发生这个错误。可以通过二进制表示法表示目标和子网掩码来检查这种情况。以二进制表示的子网掩码包括表示目标网络地址部分的一连串的 1 和表示目标主机地址部分的一连串的 0 两个部分。查看目标以确定目标的主机地址部分(由子网掩码所定义)是否有些位设置成了 1。

注:只有 Windows NT 4.0、Windows 2000、Windows Millennium Edition 和 Windows XP 的 route 命令支持 -p 参数。Windows 95 或 Windows 98 的 route 命令不支持该参数。

只有当网际协议 (TCP/IP) 协议在 网络连接中安装为网络适配器属性的组件时,该命令才可用。

范例

要显示 IP 路由表的完整内容,请键入:
route print

要显示 IP 路由表中以 10. 开始的路由,请键入:
route print 10.*

要添加默认网关地址为 192.168.12.1 的默认路由,请键入:
route add 0.0.0.0 mask 0.0.0.0 192.168.12.1

要添加目标为 10.41.0.0,子网掩码为 255.255.0.0,下一个跃点地址为 10.27.0.1 的路由,请键入:
route add 10.41.0.0 mask 255.255.0.0 10.27.0.1

要添加目标为 10.41.0.0,子网掩码为 255.255.0.0,下一个跃点地址为 10.27.0.1 的永久路由,请键
入:
route -p add 10.41.0.0 mask 255.255.0.0 10.27.0.1

要添加目标为 10.41.0.0,子网掩码为 255.255.0.0,下一个跃点地址为 10.27.0.1,跃点数为 7 的路
由,请键入:
route add 10.41.0.0 mask 255.255.0.0 10.27.0.1 metric 7

要添加目标为 10.41.0.0,子网掩码为 255.255.0.0,下一个跃点地址为 10.27.0.1,接口索引为 0x3
的路由,请键入:
route add 10.41.0.0 mask 255.255.0.0 10.27.0.1 if 0x3

要删除目标为 10.41.0.0,子网掩码为 255.255.0.0 的路由,请键入:
route delete 10.41.0.0 mask 255.255.0.0

要删除 IP 路由表中以 10. 开始的所有路由,请键入:
route delete 10.*

要将目标为 10.41.0.0,子网掩码为 255.255.0.0 的路由的下一个跃点地址由 10.27.0.1 更改为
10.27.0.25,请键入:
route change 10.41.0.0 mask 255.255.0.0 10.27.0.25

相关解决方案

1.

有两个ip地址,一个只能上内网, 一个可以上外网。

由于内网和外网必须在物理上隔离,所以不能用一块网卡同时访问内网和外网。
内网和外网分别有自己的网关。
操作步骤:
首先是要准备两块网卡,分别连接内网和外网。我使用的操作系统是winxp,安装好两块网卡的驱动后,分别使用这两个网卡建立网络连接1和2。其中连接1上外网,2上内网。首先配置连接1的tcp/ip属性,填可以上外网的ip地址和外网网关,外网网关跃点数不要自动,改成1。如有需要可填写dns服务器地址。这样配置好的连接1可以直接访问外网。再配置连接2的tcp/ip属性,只要添上ip地址,不要填内网网关。关于网络连接的具体配置步骤不再赘述。
两块网卡都配置完毕以后,建立一个批处理文件。内容如下:
route add xxx.xxx.xxx.xxx mask 255.255.255.255 zzz.zzz.zzz.zzz metric 1
这个文件是用来指定内网上需要访问的特定网址采用的网关。xxx代表需要访问的内网ip,zzz代表内网网关ip。建议对每个需要访问的内网网址都建立一条相同
格式的命令,如果采用route add xxx.0.0.0 mask 255.0.0.0 zzz.zzz.zzz.zzzmetric 1 的方式,实际使用中会有一些网址不能访问。建立批处理文件后,打开
网络连接2,运行批处理文件就可以访问内网上的这些网址。
 
几点说明:
1、在xp下可以安装多块网卡,但是每个网卡必须有单独的ip地址。不能共用同一个ip地址,可以为每个网卡建立一个网络连接且可以同时都打开。但是只有最先打开的那个网络连接可以使用,因为xp默认的只有一个网关。后面的网络连接都会使用最先打开的这个连接的网关,从而导致无法使用。所以在添加网关的时候只能添加连接1的网关,连接2的网关要单独用命令指定。
 
2、route命令在xp的命令提示符状态下可以使用。route /?可以查看详细参数。
使用格式:route add [参数] 需要访问的ip地址 mask 掩码 网关 [参数]
add 后面的参数有-p,-f,-p是永久添加,关机重启后会继续起作用,没有-p需要每次使用的时候都重新指定。但是在使用中发现添加-p指定的ip地址有时不能访问,所以采用每次都运行批处理的方式。-f是清除路由表里面的网关。
网关后面一般加参数meteic 1,意思是指定跃点数是1,保证指定的访问地址和网关匹配,加快访问速度。不加metric参数亦会导致部分内网网址不能访问。
route print命令可以列出网关详细内容。
route delete xxx.xxx.xxx.xxx可以删除一条配置。
 
3、在使用中,一般常开的是外网连接,内网连接只在需要的时候打开,保证访问外网的速度以及网络的安全。因为内网和外网必须从物理上隔断才能保证安
全。如果对网络安全要求很高就不要采用了。

2.
我也曾遇到过这个问题,解决了好长时间没有解决,最后咨询思科的工程师,协助解决。
主要原因是: 2个网卡的优先级一致,导致上内网的时候,到不了外网,而上外网的时候,就进不了内网,因为计算机无法识别同样的默认网关。在设置IP的时候系统就会提示2个网卡一起使用,会使计算机网络不能正常使用。

解决办法就是设置不同的默认网关级别。
外网设置: 打开TCP/IP协议,高级,编辑默认网关的跃点数为10,默认为自动,值为20,用ROUTE PRINT查到的;设置自动跃点数为10。
这样的设置是把外网的优先级提高。内网优先级就比较底了。
用ROUTE PRINT 命令来查看: 未设置以前的值是有两个默认网关0.0.0.0,
Network Destination Netmask Gateway Interface Metric
0.0.0.0 0.0.0.0 192.168.198.66 192.168.198.101 20
0.0.0.0 0.0.0.0 10.172.2.2 10.172.2.222 20
因为两个默认网关的METRIC 值都是20。
修改后的值是:
Network Destination Netmask Gateway Interface Metric
0.0.0.0 0.0.0.0 192.168.198.66 192.168.198.101 10
0.0.0.0 0.0.0.0 10.172.2.2 10.172.2.222 20
METRIC值越高,他的优先级别越低,这样2个默认网关就不会冲突了。
修改完这个以后:
有些时候可能进内网还不正常,你可以手工设置内网的默认网关路由。
如: 要进10.168.8.X,的内网由10.172.2.2这个网关进,通过命令来设置:
route add -p 10.168.8.X mask 255.255.255.0 10.172.2.2
命令解释:
10.168.8.X为目标网段或目标IP,设为目标网段时,X值为0,
255.255.255.0,为网关10.172.2.2的子网。
10.172.2.2,为这个目标IP的默认路由。
MASK的关键字不能少,-P为系统重启后保存设置,不用重新更改或重新增加这条路由。
有关ROUTE ADD/PRINT的相关资料大家可以在网上查查,它的使用办法。
这样问题就可以得以解决。
当然也可以用其它的办法来更改默认网关的值:
1。如ROUTE DELELTE 0.0.0.0,把2个默认网关都删掉,再新增。新增时注意设置METRIC这个值不能一样。
2。用ROUTE CHANGE 来变更两个默认网关的的外网网关的METRIC值。。
不过这2个方法比较的繁锁,也不容易操作。
 

最终解决方案

通过询问同学来解决的。新建一个BAT批处理文件,内容如下

rem start of the file

@echo off
set edu=10.5.20.1
rem 校园网网关的IP地址
set ADSL=192.168.1.1
rem ADSL路由猫的IP地址
route -f
rem 清除所有路由
route add -p 0.0.0.0 mask 0.0.0.0 %ADSL% Metric 10
route add -p 0.0.0.0 mask 0.0.0.0 %edu% Metric 20
rem 添加ADSL和校园网网关并优先使用ADSL
rem 下边代码使访问教育网网站通过校园网
route add -p 10.0.0.0 mask 255.0.0.0 %edu% Metric 20
route add -p 202.115.0.0 mask 255.255.0.0 %edu% Metric 20
rem end of the file

将两张网卡同时启用,都是自动获取IP,其他什么也不要设置,否则画蛇添足。

运行该批处理文件就OK。

DIV设置float后高度不自动增加 - 解决方案

目前用来清除“闭合(清除)浮动”的方法,主要是一下四种:

1. 额外标签法
这种方法就是向父容器的末尾再插入一个额外的标签,并令其清除浮动(clear)以撑大父容器。这种方法浏览器兼容性好,没有什么问题,缺点就是需要额外的(而且通常是无语义的)标签。
我个人不喜欢这种方法,但是它确实是W3C推荐的方法
<div style="clear:both;"></div>
或者使用
<br style="clear:both;" />

2. 使用after伪类
这种方法就是对父容器使用after伪类和内容声明在指定的现在内容末尾添加新的内容。经常的做法就是添加一个“点”,因为它比较小不太引人注意。然后我们再利用它来清除浮动(闭合浮动元素),并隐藏这个内容。
这种方法兼容性一般,但经过各种 hack 也可以应付不同浏览器了,同时又可以保证html 比较干净,所以用得还是比较多的。
#outer:after{
content:".";
height:0;
visibility:hidden;
display:block;
clear:both;
}

3. 设置overflow为hidden或者auto
这种做法就是将父容器的overflow设为hidden或auot就可以在标准兼容浏览器中闭合浮动元素.
不过使用overflow的时候,可能会对页面表现带来影响,而且这种影响是不确定的,你最好是能在多个浏览器上测试你的页面

4. 浮动外部元素,float-in-float
这种做法就是让父容器也浮动,这利用到了浮动元素的一个特性——浮动元素会闭合浮动元素。这种方式在 IE/Win 和标准兼容浏览器中都有较好的效果,但缺点也很明显——父容器未必想浮动就浮动的了,毕竟浮动是一种比较特殊的行为,有时布局不允许其浮动也很正常。

php的mail函数在WinXP+IIS环境下的应用/设置

php在IIS环境中的配置就不多说了,用windows下的php安装文件的话不会遇到什么问题。
 
困难的事情是发送电子邮件的设置,php有个默认的发送邮件的函数mail,这个函数的说明可以在php的官方网站找到(我觉得是官网,也不一定。。。):
貌似这个函数只支持没有身份验证的smtp服务器,所以要把本机上的smtp服务器开成没有身份验证的。
 
配置的过程中有两个问题:一是smtp的配置,二是php方面的配置(php.ini文件)。
 
smtp的配置,最终目标是使得IIS自带的smtp server可以正常的发信,这中间我经过了好几个步骤,还是学了点东西:
 
1. 启动smtp服务。
打开iis,发现我这儿的“默认smtp虚拟目录”居然画了“叉”,不能用啊,右键启动,又说启动不了,请去“事件查看器”看log。这个“事件查看器”在控制面板->管理工具下面,smtp的事件信息在“系统”一栏,“来源”是“SMTPSVC”。
的确是有出错的项目,双击打开看,提示错误号115,请去下面的网站找:
这个是microsoft的技术支持网站,还是挺不错的,不过建议搜索的时候在英文网页中搜索,因为很多中文网页都是英文网页直接用翻译机翻译过来的,不容易看懂。。。
 
搜索smtpsvc 115 最后在这个网页找到了办法:
大致是说25端口被占用了,在cmd下用下面的命令查看,
Netstat -an | find ":25"
 
其实应该用 netstat -ano | find ":25",因为这样可以看到占用的进程id,然后再去任务管理器中查看对应的id,发现是ccproxy(我机器上开的一个代理服务器软件),也提供了smtp代理,占用了25端口,于是禁用ccproxy中的smtp代理服务,终于可以打开“默认smtp虚拟目录”了!

 

2. 调整smtp服务的权限:
这个是网上很多人问的问题,就是用php服务,在smtp服务打开的情况下,调用mail()函数,返回
[function.mail] SMTP server response: 550 5.7.1 Unable to relay
 
这个在下面这个网页找到了解决方案:
关键是:
“据说是中继的问题
然后依照指示
虚拟服务器->属性->访问->中继
将那个复选框选好,然后再添加了127.0.0.1的本地地址
测试,ok”
 
我也是按照这个步骤做的就对了,这个地方实际上是smtp本身的权限设置,就是允许哪些地址来的请求,居然本机地址不在默认允许之列(实际上默认允许之列没有任何地址)。这样就可以发邮件了。

 

3. php的配置:php.ini
找到windows目录下的php.ini文件,这是php的动态配置文件,里面内容很详细了,关于mail配置的是这一段:
[mail function]
; For Win32 only.
SMTP = localhost ; for Win32 only
smtp_port = 25
sendmail_from= me@localhost ; for Win32 only
 
其中sendmail_from是提交给smtp服务器的发信人地址,如果这封信没发到,那么smtp会根据这个地址把信退回来,并附上错误信息。我就是第一次没发到,结果去smtp的路径C:\Inetpub\mailroot\Queue下面一看,发现一封名字无法识别的邮件,打开一看才知道是发向me@localhost的退信。
 
到这里mail函数相关的配置就都有了,不过我这里还有个问题:就是那封退信的内容,退信是发到邮箱了,但是原信为什么没发到呢?看了退信的内容才知道,原来是对方的邮件服务器拒掉了,理由是Diagnostic-Code: smtp;554 Connection refused(mx). MAIL FROM [me@localhost] mismatches client IP [xxx.xxx.xxx.xxx]. 这个是为什么我还不清楚,我猜是因为我的机器在内网?总之是这个邮箱有检测,要不然退信就发不到我另一个邮箱了。

PHPMailer使用介绍

发送邮件是一个经常使用的功能,但是php的默认支持并不是很好,这里介绍一个很好的开源模块:phpmailer,此模块功能比较全面,支持SMTP验证。下面就简单介绍一下它的使用方法:

1 下载phpmailer模块: 官方网站 http://www.phpdoc.org/

2 解压到一个文件夹

3 在php文件中包含 require_once("class.phpmailer.php");

4 使用SMTP发送邮件:

以上是针对SMTP服务器的,在LINUX下(比如我当前使用的LINUX虚拟主机)可以直接使用mail函数发送,也就是说可以不使用SMTP:

PHP FPDF类库应用实现代码

PHP测试网络连通性

假如使用file_get_contents类似的函数,代码就会终止执行下去而在那里卡住,因为相关函数在网络不连通的情况下会超时而不是马上返回。

这里使用fopen...

参考函数:

仅做参考。