<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title><![CDATA[IDC笔记]]></title>
<link>http://www.idcnote.com/</link>
<description><![CDATA[创造机会的人是勇者；等待机会的人是愚者]]></description>
<language>zh-cn</language>
<copyright><![CDATA[Copyright 2005 PBlog2 v2.4]]></copyright>
<webMaster><![CDATA[wentaiyou@126.com(Kevin)]]></webMaster>
<generator>PBlog2 v2.4</generator> 
<image>
	<title>IDC笔记</title> 
	<url>http://www.idcnote.com/images/logos.gif</url> 
	<link>http://www.idcnote.com/</link> 
	<description>IDC笔记</description> 
</image>

			<item>
			<link>http://www.idcnote.com/default.asp?id=79</link>
			<title><![CDATA[AJAX中文乱码PHP完美解决（IE和Firefox兼容）]]></title>
			<author>wentaiyou@126.com(kevin)</author>
			<category><![CDATA[编程学习]]></category>
			<pubDate>Thu,25 Aug 2011 12:28:16 +0800</pubDate>
			<guid>http://www.idcnote.com/default.asp?id=79</guid>	
		<description><![CDATA[近来使用AJAX发现发送给服务器端及服务器返回都会在中文字符上出现乱码.在网上找了一些解决办法.下以这个比较实际可行转来以便今后使用<br/><br/><br/>众所周知，使用AJAX传送和接收中文参数时，如果不在客户端和服务器做相应的处理就会出现乱码问题，在网上相应的文章也不少，但是有的情况下很难从中找到符合自己理想的答案，我今天就是在网上找了很多，但是都差不多，讲ASP和JSP的比较多（我是用的PHP），所以到最后都没找到自己满意的答案。<br/><br/>AJAX的中文乱码可以大概分为两中，第一种是向服务器端发送中文参数时（xmlhttp.open(“get|post”,url,true)）,服务器端接收到的为乱码，这个也是我今天遇到的问题，没做处理之前，在IE里是正常的，但是在Firefox里面就出现了乱码，我先把接收到参数输出到一个文本里，没有发现什么问题，郁闷了，然后我就把查询语句在输出来观察（我这里是要从数据库里查出与参数相关的东西），终于发现问题，IE和Firefox输出的参数不一样，虽然汉字上都一样，但是和前后连接上有细小的区别，于是认定了是编码问题，在网上查找了相关资料，都没能解决问题，但是得到一些启示，因为AJAX发送数据都是采用UTF-8编码的方式发送的，所以要在服务器端进行编码转换（我这里页面是采用GB2312编码的，如果是采用UTF-8的话应该不会有这步的问题），所以我在服务器端进行了UTF-8转GB2312，<br/><br/> <br/><br/>$str=iconv(&#34;UTF-8&#34;,&#34;GB2312&#34;,$str);<br/><br/> <br/><br/>然后测试，在Firefox上顺利解决了问题，以为大公告成了，可是再到IE下测试，发现IE又出现了问题，服务器端接收到的参数没值，这下就郁闷了，突然看到发送头设置了setRequestHeader(&#34;Content-Type&#34;,&#34;application/x-www-form-urlencoded&#34;);，就找到问题所在了，然后就在发送那里进行了参数编码：<br/><br/> <br/><br/>geturl=encodeURI(geturl);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; geturl=encodeURI(geturl); //两次也可以写成geturl=encodeURI(encodeURI(geturl));<br/><br/>xmlhttp.open(&#34;GET&#34;,geturl,true);<br/><br/> <br/><br/>然后再到服务器端进行URL解码：<br/><br/>&nbsp;&nbsp;<br/><br/>&nbsp;&nbsp; $str=urldecode($str); //解码&nbsp;&nbsp;<br/><br/>$ str =iconv(&#34;UTF-8&#34;,&#34;GB2312&#34;,$ str);&nbsp;&nbsp;//编码转换<br/><br/> <br/><br/>&nbsp;&nbsp; 注意：解码必须在编码转换前面，不然得不到正确值<br/><br/> <br/><br/>保存测试，IE和Firefox都能正常了。<br/><br/> <br/><br/>第二种就是服务器端向客户端输出中文时出现乱码，这类问题网上的答案就比较多了，也都能解决，为了避免各位再去查找，我在这里就COPY下J<br/><br/> <br/><br/>原因：AJAX在接收responseText或responseXML的值的时候是按照UTF-8的格式来解码的，如果服务器段发送的数据不是UTF-8的格式，那么接收responseText或responseXML的值有可能为乱码。<br/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;解决办法：<br/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;在服务器指定发送数据的格式：<br/>&nbsp;&nbsp;&nbsp;&nbsp;在jsp文件中：<br/>&nbsp;&nbsp;&nbsp;&nbsp;response.setContentType(&#34;text/text;charset=UTF-8&#34;);//返回的是txt文本文件<br/>&nbsp;&nbsp;&nbsp;&nbsp;或是<br/>&nbsp;&nbsp;&nbsp;&nbsp;response.setContentType(&#34;text/xml;charset=UTF-8&#34;);//返回的xml文件<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; PHP:header(&#39;Content-Type:text/html;charset=GB2312&#39;);<br/>&nbsp;&nbsp;&nbsp;&nbsp; ASP:Response.Charset(&#34;GB2312&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp; JSP:response.setHeader(&#34;Charset&#34;,&#34;GB2312&#34;);<br/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.idcnote.com/default.asp?id=78</link>
			<title><![CDATA[简单制作LINUX网络安装U盘]]></title>
			<author>wentaiyou@126.com(kevin)</author>
			<category><![CDATA[工作日记]]></category>
			<pubDate>Wed,27 Jul 2011 14:29:19 +0800</pubDate>
			<guid>http://www.idcnote.com/default.asp?id=78</guid>	
		<description><![CDATA[相关下载<br/><a href="http://syslinux.zytor.com/wiki/index.php/The_Syslinux_Project" target="_blank">http://syslinux.zytor.com/wiki/index.php/The_Syslinux_Project</a><br/><br/>制作教程<br/><a href="http://www.cnblogs.com/5tao/archive/2010/01/31/1660481.html" target="_blank">http://www.cnblogs.com/5tao/archive/2010/01/31/1660481.html</a><br/><br/><br/>参照以上自己所做的如下：<br/>1、把u盘格式化，采用fat32格式。你可以用windows或者HP优盘格式化工具进行。<br/>2、在u盘的根创建boot文件夹，在boot下创建syslinux子文件夹<br/>3、把下载得到的syslinux-x.xx.zip解压缩到syslinux-x.xx文件夹，在其中的win32下有syslinux.exe文件。拷贝syslinux.exe到u盘的/boot/syslinux文件夹下<br/>4、打开命令行，切换到u盘根目录，进入/boot/syslinux文件夹，执行syslinux.exe，假设u盘的盘符为j：<br/>在命令行下依次运行下列命令：<br/>C:\Documents and Settings\xxxxx&gt; J:<br/>J:\&gt;cd boot/syslinux<br/>J:\boot\syslinux&gt; syslinux.exe -ma -d /boot/syslinux j:<br/>其中 -d /boot/syslinux是把命令生成的启动系统文件ldlinux.sys放到/boot/syslinux目录新建一个syslinux.cfg配制内容如下。<br/>调整BIOS就可以启动了(以下面配制文件是安装centos5.6_32位系统。源来自于163，可以根据不同要求来编写自己的CFG)<br/><br/>配制文件syslinux.cfg<br/>prompt 1<br/>timeout 100<br/>default vesamenu.c32<br/><br/>F1 readme.txt<br/>F2 syslinux.cfg<br/><br/>label centos5.6_32<br/>kernel /boot/os/centos5.6_32-vmlinuz&nbsp;&nbsp;method=http://mirrors.163.com/centos/5.6/os/i386/<br/>append initrd=/boot/os/centos5.6_32-initrd.img<br/><br/>LABEL boothd<br/>MENU LABEL Boot System of HD1<br/>kernel /boot/syslinux/chain.c32<br/>append hd1<br/>TEXT HELP<br/>More about currently sel&#101;cted:<br/>Boot System of HD1.<br/>ENDTEXT <br/><br/>LABEL boothd<br/>MENU LABEL Boot System of HD2<br/>kernel /boot/syslinux/chain.c32<br/>append hd2<br/>TEXT HELP<br/>More about currently sel&#101;cted:<br/>Boot System of HD2.<br/>ENDTEXT<br/><br/>LABEL reboot<br/>MENU LABEL&nbsp;&nbsp;Reboot<br/>kernel /boot/syslinux/reboot.c32<br/>TEXT HELP<br/>More about currently sel&#101;cted:<br/>reboot.<br/>ENDTEXT]]></description>
		</item>
		
			<item>
			<link>http://www.idcnote.com/default.asp?id=77</link>
			<title><![CDATA[linux的启动过程(redhat)]]></title>
			<author>wentaiyou@126.com(kevin)</author>
			<category><![CDATA[GNU/Linux]]></category>
			<pubDate>Wed,01 Jun 2011 14:01:16 +0800</pubDate>
			<guid>http://www.idcnote.com/default.asp?id=77</guid>	
		<description><![CDATA[随着Linux的应用日益广泛，特别是在网络应用方面，有大量的网络服务器使用Linux操作系统。由于Linux的桌面应用和Windows相比还有一定的差距，所以在企业应用中往往是Linux和Windows操作系统共存形成异构网络。在服务器端大多使用Linux和Unix的，目前Linux的擅长应用领域是单一应用的基础服务器应用，譬如DNS和DHCP服务器、Web服务器、目录服务器、防火墙、文件和打印服务器、Intranet代理服务器 。启动 Linux 系统的过程包括很多阶段。不管您是引导一个标准的 x86 处理器，还是PowerPC 机器，很多流程都惊人地相似。本文将描述了从开机到登录的 Linux 启动全过程。<br/><br/>（1） 从BIOS到内核<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;BIOS自检<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;计算机在接通电源之后首先由BIOS进行自检，即进行所谓的POST（Power On Self <br/>Test），然后依据BIOS内设置的引导顺序从硬盘、软盘或CDROM中读入“引导块”。 在 PC 中，引导 Linux 是从 BIOS 中的地址 0xFFFF0 处开始的。BIOS 的第一个步骤是加电自检（POST）。POST 的工作是对硬件进行检测。BIOS 的第二个步骤是进行本地设备的枚举和初始化。给定 BIOS 功能的不同用法之后，BIOS 由两部分组成：POST 代码和运行时服务。当 POST 完成之后，它被从内存中清理了出来，但是 BIOS 运行时服务依然保留在内存中，目标操作系统可以使用这些服务。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;要引导一个操作系统，BIOS 运行时会按照 CMOS 的设置定义的顺序来搜索处于活动状态并且可以引导的设备。引导设备可以是软盘、CD-ROM、硬盘上的某个分区、网络上的某个设备，甚至是 USB 闪存。通常，Linux 都是从硬盘上引导的，其中主引导记录（MBR）中包含主引导加载程序。MBR 是一个 512 字节大小的扇区，位于磁盘上的第一个扇区中（0 道 0 柱面 1 扇区）。当 MBR 被加载到 RAM 中之后，BIOS 就会将控制权交给 MBR。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;提取 MBR 的信息<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;要查看 MBR 的内容，请使用下面的命令：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;# dd if=/dev/hda of=mbr.bin bs=512 count=1 # od -xa mbr.bin <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;这个 dd 命令需要以 root 用户的身份运行，它从 /dev/hda（第一个 IDE 盘） 上读取前 512 个字节的内容，并将其写入 mbr.bin 文件中。od 命令会以十六进制和 ASCII 码格式打印这个二进制文件的内容。<br/>（2）启动GRUB/LILO<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;GRUB和LILO都是引导加载程序。最简单地讲，引导加载程序（boot loader） 会引导操作系统。当机器引导它的操作系统时，BIOS 会读取引导介质上最前面的 512 字节（即人们所知的 主引导记录（master boot record，MBR））。在单一的 MBR 中只能存储一个操作系统的引导记录，所以当需要多个操作系统时就会出现问题。所以需要更灵活的引导加载程序。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;GRUB 与 LILO 的比较<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;如本文开始处所述，所有引导加载程序都以类似的方式工作，满足共同的目的。不过，LILO 和 GRUB 之间有很多不同之处：<br/><br/>LILO 没有交互式命令界面，而 GRUB 拥有。 <br/>LILO 不支持网络引导，而 GRUB 支持。 <br/>LILO 将关于可以引导的操作系统位置的信息物理上存储在 MBR 中。如果修改了 LILO 配置文件，必须将 LILO 第一阶段引导加载程序重写到 MBR。相对于 GRUB，这是一个更为危险的选择，因为错误配置的 MBR 可能会让系统无法引导。使用 GRUB，如果配置文件配置错误，则只是默认转到 GRUB 命令行界面。<br/>&nbsp;&nbsp;&nbsp;&nbsp;安全提示：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;关于安全性，任何可以接触到引导磁盘/CD 的人，只需要使用没有设置安全性的 grub.conf 或 lilo.conf，就可以绕过本文中提及的所有安全措施。特别是使用 GRUB 时，因为能够引导到单用户模式，所以是一个严重的安全漏洞。解决此问题的一个简单方法是在机器的 BIOS 中禁止通过 CD 和软盘进行引导，并确保为 BIOS 设置了一个口令，使得其他人不能修改这些设置。<br/>&nbsp;&nbsp; （3）加载内核<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;当内核映像被加载到内存之后，内核阶段就开始了。内核映像并不是一个可执行的内核，而是一个压缩过的内核映像。通常它是一个 zImage（压缩映像，小于 512KB）或一个 bzImage（较大的压缩映像，大于 512KB），它是提前使用 zlib 进行压缩过的。在这个内核映像前面是一个例程，它实现少量硬件设置，并对内核映像中包含的内核进行解压，然后将其放入高端内存中，如果有初始 RAM 磁盘映像，就会将它移动到内存中，并标明以后使用。然后该例程会调用内核，并开始启动内核引导的过程。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;GRUB 中的手工引导<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;在 GRUB 命令行中，我们可以使用 initrd 映像引导一个特定的内核，方法如下：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;grub&gt; kernel /bzImage-2.6.14.2<br/>&nbsp;&nbsp; [Linux-bzImage, setup=0x1400, size=0x29672e]<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;grub&gt; initrd /initrd-2.6.14.2.img<br/>&nbsp;&nbsp; [Linux-initrd @ 0x5f13000, 0xcc199 bytes]<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;grub&gt; boot<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;Uncompressing Linux... Ok, booting the kernel.<br/>如果您不知道要引导的内核的名称，只需使用斜线（/）然后按下 Tab 键即可。GRUB 会显示内核和 initrd 映像列表。<br/>&nbsp;&nbsp; （4）执行init进程<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;init进程是系统所有进程的起点，内核在完成核内引导以后，即在本线程（进程）空间内加载init程序，它的进程号是1。init进程是所有进程的发起者和控制者。因为在任何基于Unix的系统（比如Linux）中，它都是第一个运行的进程，所以init进程的编号（Process ID，PID）永远是1。如果init出现了问题，系统的其余部分也就随之而垮掉了。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;init进程有两个作用。第一个作用是扮演终结父进程的角色。因为init进程永远不会被终止，所以系统总是可以确信它的存在，并在必要的时候以它为参照。如果某个进程在它衍生出来的全部子进程结束之前被终止，就会出现必须以init为参照的情况。此时那些失去了父进程的子进程就都会以init作为它们的父进程。快速执行一下ps -af 命令，可以列出许多父进程ID（Parent Process ID，PPID）为1的进程来。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;init的第二个角色是在进入某个特定的运行级别（Runlevel）时运行相应的程序，以此对各种运行级别进行管理。它的这个作用是由/etc/inittab文件定义的。<br/>（5）通过/etc/inittab文件进行初始化<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;init的工作是根据/etc/inittab来执行相应的脚本进行系统初始化，如设置键盘、字体， 装载模块，设置网络，等等。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;对于RedhatLinux来说，执行的顺序为： <br/><br/>/etc/rc.d/rc.sysinit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 由init执行的第一个脚本 <br/>/etc/rc.d/rc.sysinit主要做在各个运行模式中相同的初始化工作，包括： <br/>设置初始的$PATH变量。<br/>配置网络。<br/>为虚拟内存启动交换。<br/>设置系统的主机名。<br/>检查root文件系统，以进行必要的修复。<br/>检查root文件系统的配额。<br/>为root文件系统打开用户和组的配额。<br/>以读/写的方式重新装载root文件系统。<br/>清除被装载的文件系统表/etc/mtab。<br/>把root文件系统输入到mtab。<br/>使系统为装入模块做准备。<br/>查找模块的相关文件。<br/>检查文件系统，以进行必要的修复。<br/>加载所有其他文件系统。<br/>清除几个/etc文件：/etc/mtab、/etc/fastboot和/etc/nologin。<br/>删除UUCP的lock文件。<br/>删除过时的子系统文件。<br/>删除过时的pid文件。<br/>设置系统时钟。<br/>打开交换。<br/>初始化串行端口。<br/>装入模块。<br/>/etc/rc.d/rcX.d/[KS]<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;首先终止“K”开头的服务，然后启动“S”开头的服务。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; 对每一个运行级别来说，在/etc/rc.d子目录中都有一个对应的下级目录。这些运行级别的下级子目录的命名方法是rcX.d，其中的X就是代表运行级别的数字。比如说，运行级别3的全部命令脚本程序都保存在/etc/rc.d/rc3.d子目录中。在各个运行级别的子目录中，都建立有到/etc/rc.d/init.d子目录中命令脚本程序的符号链接，但是，这些符号链接并不使用命令脚本程序在 /etc/rc.d/init.d子目录中原来的名字。如果命令脚本程序是用来启动一个服务的，其符号链接的名字就以字母S打头；如果命令脚本程序是用来关闭一个服务的，其符号链接的名字就以字母K打头。许多情况下，这些命令脚本程序的执行顺序都很重要。如果没有先配置网络接口，就没有办法使用DNS服务解析主机名！为了安排它们的执行顺序，在字母S或者 K的后面紧跟着一个两位数字，数值小的在数值大的前面执行。比如：/etc/rc.d/rc3.d/S50inet就会在 /etc/rc.d/rc3.d/S55named之前执行。存放在/etc/rc.d/init.d子目录中的、被符号链接上的命令脚本程序是真正的实干家，是它们完成了启动或者停止各种服务的操作过程。当 /etc/rc.d/rc运行通过每个特定的运行级别子目录的时候，它会根据数字的顺序依次调用各个命令脚本程序执行。它先运行以字母K打头的命令脚本程序，然后再运行以字母S打头的命令脚本程序。对以字母K打头的命令脚本程序来说，会传递Stop参数；类似地对以字母S打头的命令脚本程序来说，会传递 Start参数。<br/>执行/etc/ec.d/rc.local<br/>Redhat Linux中的运行模式2、3、5都把/etc/rc.d/rc.local做为初始化脚本中的最后一个，所以用户可以自己在这个文件中添加一些需要在其他初始化工作之后，登录之前执行的命令。在维护Linux系统运转的日子里，肯定会遇到需要系统管理员对开机或者关机命令脚本进行修改的情况。如果所做的修改只在引导开机的时候起作用，并且改动不大的话，可以考虑简单地编辑一下/etc/rc.d/rc.local脚本。这个命令脚本程序是在引导过程的最后一步被执行的。<br/>执行 /bin/login 程式&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>login 程序会提示使用者需输入账号及密码, 接着编码并确认密码的正确性, 若二者相合, 则为使用者进行初始化环境, 并将控制权交给 shell，即等待用户登录。<br/>到此为止Linux启动过程全部结束。<br/>&nbsp;&nbsp;&nbsp;&nbsp;最后笔者使用图1解释全部过程<br/><br/><img src="http://www.idcnote.com/attachments/month_1106/e20116114047.jpg" border="0" alt=""/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.idcnote.com/default.asp?id=76</link>
			<title><![CDATA[TCP三次握手]]></title>
			<author>wentaiyou@126.com(kevin)</author>
			<category><![CDATA[NetWork]]></category>
			<pubDate>Tue,24 May 2011 10:24:22 +0800</pubDate>
			<guid>http://www.idcnote.com/default.asp?id=76</guid>	
		<description><![CDATA[在TCP/IP协议中，TCP协议提供可靠的连接服务，采用三次握手建立一个连接。 <br/><br/>　　第一次握手：建立连接时，客户端发送syn包(syn=j)到服务器，并进入SYN_SEND状态，等待服务器确认； <br/><br/>　　第二次握手：服务器收到syn包，必须确认客户的SYN（ack=j+1），同时自己也发送一个SYN包（syn=k），即SYN+ACK包，此时服务器进入SYN_RECV状态； <br/><br/>　　第三次握手：客户端收到服务器的SYN＋ACK包，向服务器发送确认包ACK(ack=k+1)，此包发送完毕，客户端和服务器进入ESTABLISHED状态，完成三次握手。 <br/><br/>　　完成三次握手，客户端与服务器开始传送数据，在上述过程中，还有一些重要的概念： <br/><br/>未连接队列：在三次握手协议中，服务器维护一个未连接队列，该队列为每个客户端的SYN包（syn=j）开设一个条目，该条目表明服务器已收到 SYN包，并向客户发出确认，正在等待客户的确认包。这些条目所标识的连接在服务器处于Syn_RECV状态，当服务器收到客户的确认包时，删除该条目，服务器进入ESTABLISHED状态。<br/>Backlog参数：表示未连接队列的最大容纳数目。 <br/><br/>　　SYN-ACK 重传次数　服务器发送完SYN－ACK包，如果未收到客户确认包，服务器进行首次重传，等待一段时间仍未收到客户确认包，进行第二次重传，如果重传次数超过系统规定的最大重传次数，系统将该连接信息从半连接队列中删除。注意，每次重传等待的时间不一定相同。 <br/><br/>　　半连接存活时间：是指半连接队列的条目存活的最长时间，也即服务从收到SYN包到确认这个报文无效的最长时间，该时间值是所有重传请求包的最长等待时间总和。有时我们也称半连接存活时间为Timeout时间、SYN_RECV存活时间<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.idcnote.com/default.asp?id=75</link>
			<title><![CDATA[/proc/sys/net/ipv4/参数说明]]></title>
			<author>wentaiyou@126.com(kevin)</author>
			<category><![CDATA[NetWork]]></category>
			<pubDate>Tue,24 May 2011 10:23:28 +0800</pubDate>
			<guid>http://www.idcnote.com/default.asp?id=75</guid>	
		<description><![CDATA[tcp_syn_retries ：INTEGER<br/>默认值是5<br/>对于一个新建连接，内核要发送多少个 SYN 连接请求才决定放弃。不应该大于255，默认值是5，对应于180秒左右时间。(对于大负载而物理通信良好的网络而言,这个值偏高,可修改为2.这个值仅仅是针对对外的连接,对进来的连接,是由tcp_retries1 决定的)<br/><br/>tcp_synack_retries ：INTEGER<br/>默认值是5<br/>对于远端的连接请求SYN，内核会发送SYN ＋ ACK数据报，以确认收到上一个 SYN连接请求包。这是所谓的三次握手( threeway handshake)机制的第二个步骤。这里决定内核在放弃连接之前所送出的 SYN+ACK 数目。不应该大于255，默认值是5，对应于180秒左右时间。(可以根据上面的 tcp_syn_retries 来决定这个值)<br/><br/>tcp_keepalive_time ：INTEGER<br/>默认值是7200(2小时)<br/>当keepalive打开的情况下，TCP发送keepalive消息的频率。(由于目前网络攻击等因素,造成了利用这个进行的攻击很频繁,曾经也有cu的朋友提到过,说如果2边建立了连接,然后不发送任何数据或者rst/fin消息,那么持续的时间是不是就是2小时,空连接攻击? tcp_keepalive_time就是预防此情形的.我个人在做nat服务的时候的修改值为1800秒)<br/><br/>tcp_keepalive_probes：INTEGER<br/>默认值是9<br/>TCP发送keepalive探测以确定该连接已经断开的次数。(注意:保持连接仅在SO_KEEPALIVE套接字选项被打开是才发送.次数默认不需要修改,当然根据情形也可以适当地缩短此值.设置为5比较合适)<br/><br/>tcp_keepalive_intvl：INTEGER<br/>默认值为75<br/>探测消息发送的频率，乘以tcp_keepalive_probes就得到对于从开始探测以来没有响应的连接杀除的时间。默认值为75秒，也就是没有活动的连接将在大约11分钟以后将被丢弃。(对于普通应用来说,这个值有一些偏大,可以根据需要改小.特别是web类服务器需要改小该值,15是个比较合适的值)<br/><br/>tcp_retries1 ：INTEGER<br/>默认值是3<br/>放弃回应一个TCP连接请求前﹐需要进行多少次重试。RFC 规定最低的数值是3﹐这也是默认值﹐根据RTO的值大约在3秒 - 8分钟之间。(注意:这个值同时还决定进入的syn连接)<br/><br/>tcp_retries2 ：INTEGER<br/>默认值为15<br/>在丢弃激活(已建立通讯状况)的TCP连接之前﹐需要进行多少次重试。默认值为15，根据RTO的值来决定，相当于13-30分钟(RFC1122规定，必须大于100秒).(这个值根据目前的网络设置,可以适当地改小,我的网络内修改为了5)<br/><br/>tcp_orphan_retries ：INTEGER<br/>默认值是7<br/>在近端丢弃TCP连接之前﹐要进行多少次重试。默认值是7个﹐相当于 50秒 - 16分钟﹐视 RTO 而定。如果您的系统是负载很大的web服务器﹐那么也许需要降低该值﹐这类 sockets 可能会耗费大量的资源。另外参的考 tcp_max_orphans 。(事实上做NAT的时候,降低该值也是好处显著的,我本人的网络环境中降低该值为3)<br/><br/>tcp_fin_timeout ：INTEGER<br/>默认值是 60<br/>对于本端断开的socket连接，TCP保持在FIN-WAIT-2状态的时间。对方可能会断开连接或一直不结束连接或不可预料的进程死亡。默认值为 60 秒。过去在2.2版本的内核中是 180 秒。您可以设置该值﹐但需要注意﹐如果您的机器为负载很重的web服务器﹐您可能要冒内存被大量无效数据报填满的风险﹐FIN-WAIT-2 sockets 的危险性低于 FIN-WAIT-1 ﹐因为它们最多只吃 1.5K 的内存﹐但是它们存在时间更长。另外参考 tcp_max_orphans。(事实上做NAT的时候,降低该值也是好处显著的,我本人的网络环境中降低该值为30)<br/><br/>tcp_max_tw_buckets ：INTEGER<br/>默认值是180000<br/>系 统在同时所处理的最大 timewait sockets 数目。如果超过此数的话﹐time-wait socket 会被立即砍除并且显示警告信息。之所以要设定这个限制﹐纯粹为了抵御那些简单的 DoS 攻击﹐千万不要人为的降低这个限制﹐不过﹐如果网络条件需要比默认值更多﹐则可以提高它(或许还要增加内存)。(事实上做NAT的时候最好可以适当地增加该值)<br/><br/>tcp_tw_recycle ：BOOLEAN<br/>默认值是0<br/>打开快速 TIME-WAIT sockets 回收。除非得到技术专家的建议或要求﹐请不要随意修改这个值。(做NAT的时候，建议打开它)<br/><br/><br/>tcp_tw_reuse：BOOLEAN<br/>默认值是0<br/>该文件表示是否允许重新应用处于TIME-WAIT状态的socket用于新的TCP连接(这个对快速重启动某些服务,而启动后提示端口已经被使用的情形非常有帮助)<br/><br/>tcp_max_orphans ：INTEGER<br/>缺省值是8192<br/>系统所能处理不属于任何进程的TCP sockets最大数量。假如超过这个数量﹐那么不属于任何进程的连接会被立即reset，并同时显示警告信息。之所以要设定这个限制﹐纯粹为了抵御那些简单的 DoS 攻击﹐千万不要依赖这个或是人为的降低这个限制(这个值Redhat AS版本中设置为32768,但是很多防火墙修改的时候,建议该值修改为2000)<br/><br/>tcp_abort_on_overflow ：BOOLEAN<br/>缺省值是0<br/>当守护进程太忙而不能接受新的连接，就象对方发送reset消息，默认值是false。这意味着当溢出的原因是因为一个偶然的猝发，那么连接将恢复状态。只有在你确信守护进程真的不能完成连接请求时才打开该选项，该选项会影响客户的使用。(对待已经满载的sendmail,apache这类服务的时候,这个可以很快让客户端终止连接,可以给予服务程序处理已有连接的缓冲机会,所以很多防火墙上推荐打开它)<br/><br/>tcp_syncookies ：BOOLEAN<br/>默认值是0<br/>只有在内核编译时选择了CONFIG_SYNCOOKIES时才会发生作用。当出现syn等候队列出现溢出时象对方发送syncookies。目的是为了防止syn flood攻击。<br/>注意：该选项千万不能用于那些没有收到攻击的高负载服务器，如果在日志中出现synflood消息，但是调查发现没有收到synflood攻击，而是合法用户的连接负载过高的原因，你应该调整其它参数来提高服务器性能。参考:<br/>tcp_max_syn_backlog<br/>tcp_synack_retries<br/>tcp_abort_on_overflow<br/>syncookie严重的违背TCP协议，不允许使用TCP扩展，可能对某些服务导致严重的性能影响(如SMTP转发)。(注意,该实现与BSD上面使用的tcp proxy一样,是违反了RFC中关于tcp连接的三次握手实现的,但是对于防御syn-flood的确很有用.)<br/><br/>tcp_stdurg ：BOOLEAN<br/>默认值为0<br/>使用 TCP urg pointer 字段中的主机请求解释功能。大部份的主机都使用老旧的 BSD解释，因此如果您在 Linux 打开它﹐或会导致不能和它们正确沟通。<br/><br/><br/>tcp_max_syn_backlog ：INTEGER<br/>对于那些依然还未获得客户端确认的连接请求﹐需要保存在队列中最大数目。对于超过 128Mb 内存的系统﹐默认值是 1024 ﹐低于 128Mb 的则为 128。如果服务器经常出现过载﹐可以尝试增加这个数字。警告﹗假如您将此值设为大于 1024﹐最好修改 include/net/tcp.h 里面的 TCP_SYNQ_HSIZE ﹐以保持 TCP_SYNQ_HSIZE*16&lt;=tcp_max_syn_backlog ﹐并且编进核心之内。(SYN Flood攻击利用TCP协议散布握手的缺陷，伪造虚假源IP地址发送大量TCP-SYN半打开连接到目标系统，最终导致目标系统Socket队列资源耗 尽而无法接受新的连接。为了应付这种攻击，现代Unix系统中普遍采用多连接队列处理的方式来缓冲(而不是解决)这种攻击，是用一个基本队列处理正常的完 全连接应用(Connect()和Accept() )，是用另一个队列单独存放半打开连接。这种双队列处理方式和其他一些系统内核措施(例如Syn-Cookies/Caches)联合应用时，能够比较有效的缓解小规模的SYN Flood攻击(事实证明&lt;1000p/s)加大SYN队列长度可以容纳更多等待连接的网络连接数，所以对Server来说可以考虑增大该值.)<br/><br/>tcp_window_scaling ：INTEGER<br/>缺省值为1<br/>该 文件表示设置tcp/ip会话的滑动窗口大小是否可变。参数值为布尔值，为1时表示可变，为0时表示不可变。tcp/ip通常使用的窗口最大可达到 65535 字节，对于高速网络，该值可能太小，这时候如果启用了该功能，可以使tcp/ip滑动窗口大小增大数个数量级，从而提高数据传输的能力(RFC 1323)。（对普通地百M网络而言，关闭会降低开销，所以如果不是高速网络，可以考虑设置为0）<br/><br/>tcp_timestamps ：BOOLEAN<br/>缺省值为1<br/>Timestamps 用在其它一些东西中﹐可以防范那些伪造的 sequence 号码。一条1G的宽带线路或许会重遇到带 out-of-line数值的旧sequence 号码(假如它是由于上次产生的)。Timestamp 会让它知道这是个 &#39;旧封包&#39;。(该文件表示是否启用以一种比超时重发更精确的方法（RFC 1323）来启用对 RTT 的计算；为了实现更好的性能应该启用这个选项。)<br/><br/>tcp_sack ：BOOLEAN<br/>缺省值为1<br/>使 用 Sel&#101;ctive ACK﹐它可以用来查找特定的遗失的数据报--- 因此有助于快速恢复状态。该文件表示是否启用有选择的应答（Sel&#101;ctive Acknowledgment），这可以通过有选择地应答乱序接收到的报文来提高性能（这样可以让发送者只发送丢失的报文段）。(对于广域网通信来说这个选项应该启用，但是这会增加对 CPU 的占用。)<br/><br/>tcp_fack ：BOOLEAN<br/>缺省值为1<br/>打开FACK拥塞避免和快速重传功能。(注意，当tcp_sack设置为0的时候，这个值即使设置为1也无效)<br/><br/>tcp_dsack ：BOOLEAN<br/>缺省值为1<br/>允许TCP发送&#34;两个完全相同&#34;的SACK。]]></description>
		</item>
		
			<item>
			<link>http://www.idcnote.com/default.asp?id=74</link>
			<title><![CDATA[HASH表和SYN计算的TCP会话重组--理论]]></title>
			<author>wentaiyou@126.com(kevin)</author>
			<category><![CDATA[NetWork]]></category>
			<pubDate>Wed,13 Apr 2011 12:33:42 +0800</pubDate>
			<guid>http://www.idcnote.com/default.asp?id=74</guid>	
		<description><![CDATA[在网站看到一个关于TCP会话重组的理论文章感觉适用转下来以便后续研究 <img src="http://www.idcnote.com/images/smilies/Face_06.gif" border="0" style="margin:0px 0px -2px 0px" alt=""/><br/><br/> 本文提出一种基于HASH表和SYN计算的TCP会话重组方法，它利用HASH表快速定位的特征和TCP包头中的SYN进行多连接TCP会话重组，可解决IP数据包乱序到达和TCP数据包重传问题。 <br/><br/>一、 引言 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;在网络安全领域，TCP会话重组是一个必须解决的关键技术，它广泛应用在入侵检测系统、病毒监控系统、远程监控系统等产品中。只有重组后的数据包才能成为程序可理解的信息，从而对其进行监控。当前大部分入侵检测系统都实现了高效的TCP会话重组，它的难点在于解决多连接问题、IP包乱序到达和TCP会话重传问题。笔者在实际工程经验中摸索了一种基于HASH表和SYN计算的TCP会话重组方法。 <br/><br/>二、TCP会话重组 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;传输控制协议TCP（Transmission Control Protocol，RFC 793，RFC 1122，RFC 813，RFC 816，RFC 879，RFC 896，RFC 889，RFC 964）是一个在网络中提供主机到主机高可靠性通信的协议，根据RFC793规定，TCP头的结构如图1所示：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;图1 TCP包首部 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;RFC793中规定，TCP头中的序号（Sequence Number）用于指定该数据包在整个会话中的位置，该序号是TCP会话重组的关键。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;图2 TCP会话重组流程 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;图2中描述的流程简单地说明了利用HASH表和SYN计算进行TCP会话重组的过程，最终程序将每一个会话完整地保存到不同的文件中。在重组过程中，程序主要用到了两种关键技术：“HASH表”和TCP会话文件写指针“SYN计算”方法。“HASH表”解决了同时处理多个TCP会话的问题。“SYN计算”可以快速地计算TCP会话写入重组数据文件的位置，同时可以有效地解决IP包乱序到达和TCP会话重传问题。 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;1.HASH表 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;由于程序经常需要同一时刻监控多个TCP会话数据包，这些数据包掺杂在一起，因而程序在进行会话重组时需要同时处理这些不同连接的TCP包。为达到这个目的，我们采用一个HASH表来记录不同的连接信息。HASH表每个节点内包含以下信息：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; ■ TCP_Session_IDT：TCP会话标识。由TCP协议可知，每个TCP会话由源IP地址、目的IP地址、源TCP端口号和目的TCP端口号惟一标识，我们的TCP会话标识也由这四个元素组成，HASH表查找也是基于这四个元素实现。 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;■ File_IDT：文件标识。将不同TCP会话数据保存在不同名的重组数据文件内，因此每个会话都有一个文件标识相对应。 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;■ File_Init_Write_Pointer：写文件初始指针。该初始指针并不表示每个重组数据文件由此指针指向的位置开始写，而是用来计算后续文件指针的。 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;■ File_Last_Visit_time：文件最近一次被访问的时间，用于计算TCP会话超时。基于现有网络状况的考虑，TCP会话超时是不可避免的情况，应当有专门的机制来对此进行处理。我们设置了一个专门的进程来判断TCP会话是否超时，当某个文件长时间没有被访问则说明该文件对应的TCP会话已经超时，可以结束有关此会话的收集。 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;利用HASH表快速查找定位的特性，我们解决了多个TCP会话同时处理的问题以及快速对多个会话进行处理的问题。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; 2.SYN计算方法 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;(1)Sequence Number <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;本节将分析TCP头中Sequence Number在TCP数据传输过程中的作用。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;初始阶段，TCP连接刚建立时，会为后续TCP数据传输设定一个初始Sequence Number，本文用Init_Seq_NUM表示。每传送一个包含有效数据的TCP包，后续紧接着传送的TCP数据包Sequence Number会作相应的修改，如果前一个TCP包的长度为N字节，则这个包的Sequence Number为前一个包的Sequence Number加N字节。表1描述了这一过程。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;表1：TCP Sequence Number在TCP数据包传输过程中的作用。 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;可以看出，Sequence Number是为了保证TCP数据包按序传输来设计的，可以有效地实现TCP数据的完整传送，特别是当数据传输出现错误时可以有效进行错误纠正。 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;(2)TCP会话文件写指针SYN计算方法 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;基于TCP头中的Sequence Number有一种简单而有效的TCP会话重组数据文件写指针的计算方法，在这里我们称之为SYN计算。本节将对此方法进行介绍。 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;在将一个TCP包的数据内容写入到重组数据文件的时候，需要两个参数：数据长度Data Length和文件写指针Write Pointer。数据长度可以很方便地从数据包的IP头中提取，难点是如何计算TCP重组数据文件写指针。根据上文介绍的Sequence Number的作用，可利用这个值来计算写指针。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; ①记录初始Sequence Number，该值可以从携带SYN标记的TCP包中获得。 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;②用当前TCP包中的Sequence Number减去初始Sequence Number，再减去1（因为TCP SYN标记需要占用一个Sequence Number），即可以得到TCP重组数据文件的写指针Write Pointer。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; 以上就是用来计算TCP重组数据文件写指针的SYN算法。即： <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;①File_Init_Write_Pointer = Init Sequence Number + 1； <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;②File_Write_Pointer = Current Sequence Number – File_Init_Write_Pointer。 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;(3)特例问题<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;本节分析用上述SYN算法如何实现有效处理IP数据包乱序到达和TCP数据包重传问题。 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;▲处理IP数据包乱序到达问题<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;设正确的IP数据包到达顺序应该是：P1、P2、P3，对应的Sequence Number分别是：SYN1、SYN2、SYN3，有效TCP数据的大小为Len1、Len2、Len3。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; 则有：SYN2 = SYN1 + LEN1，SYN3 = SYN2 + LEN2，在数据包按序到达的情况下，我们利用SYN算法可将各个TCP数据包内容正确地写入重组数据文件的对应位置。 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;P1：写入从SYN1-File_Init_Write_Pointer位置到SYN1－File_Init_Write_Pointer + LEN1。 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;P2：写入从SYN2-File_Init_Write_Pointer，即，SYN1 + LEN1 + - File_Init_Write_Pointer到SYN1 + LEN1 - File_Init_Write_Pointer + LEN2。 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;P3：写入从SYN3-File_Init_Write_Pointer，即，SYN1 + LEN1 + LEN2 - File_Init_Write_Pointer到SYN1 + LEN1 + LEN2 - File_Init_Write_Pointer + LEN3。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;在数据包不能按序到达的情况下，设IP数据包到达的顺序为P1，P3，P2，可以发现重组数据的写入位置还是相同的，只是写入的先后不同，成了P1，P3，P2。因此，按照此种算法仍能将有效的TCP数据写入到重组数据文件的正确位置。 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;▲处理TCP数据包重传问题<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;假设TCP数据传送方先传了四个TCP包TCP1、TCP2、TCP3、TCP4，Sequence Number分别为：SYN1、SYN2、SYN3、SYN4，长度分别为LEN1、LEN2、LEN3、LEN4。但是，TCP数据接收方要求从第二个TCP包开始重新传送，同时由于网络原因重传的数据包大小发生了变化，分别为：LEN2’，LEN3’，LEN4’，并有LEN2 + LEN3 + LEN4 = LEN2’ + LEN3’+ LEN4’，三个新TCP包的Sequence Number分别为：SYN1 + LEN1，SYN1 + LEN1 + LEN2’， SYN1 + LEN1 + LEN2’ + LEN3’。 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;根据SYN计算法可得，第一次传输的四个数据包写入TCP重组文件的位置分别为： <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;TCP1：写入位置为SYN1-File_Init_Write_Pointer到SYN1－File_Init_Write_Pointer + LEN1。 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;TCP2：写入位置为SYN2-File_Init_Write_Pointer，即，SYN1 + LEN1 + - File_Init_Write_Pointer到SYN1 + LEN1 - File_Init_Write_Pointer + LEN2。 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;TCP3：写入位置为SYN3-File_Init_Write_Pointer，即，SYN1 + LEN1 + LEN2 - File_Init_Write_Pointer到SYN1 + LEN1 + LEN2 - File_Init_Write_Pointer + LEN3。 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;TCP4：写入位置为SYN4-File_Init_Write_Pointer，即，SYN1 + LEN1 + LEN2 + LEN3 - File_Init_Write_Pointer到SYN1 + LEN1 + LEN2 + LEN3 - File_Init_Write_Pointer + LEN4。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;当发生TCP包重传时，程序将从第二个TCP包开始重新写重组数据文件。此时的情况为： <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;TCP2’：写入位置为SYN1 + LEN1 - File_Init_Write_Pointer到SYN1 + LEN1 - File_Init_Write_Pointer + LEN2’。 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;TCP3’：写入位置为SYN1 + LEN1 + LEN2’ - File_Init_Write_Pointer到SYN1 + LEN1 + LEN2’ - File_Init_Write_Pointer + LEN3’。 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;TCP4’：写入位置为SYN1 + LEN1 + LEN2’ + LEN3’ - File_Init_Write_Pointer到SYN1 + LEN1 + LEN2’ + LEN3’ - File_Init_Write_Pointer + LEN4’。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;由于LEN2 + LEN3 + LEN4 = LEN2’ + LEN3’ + LEN4’，因此各数据包在TCP重组数据文件中写入的最终位置两次是相同的，即实现了正确覆盖。 <br/><br/>三、 结束语 <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;经反复测试我们发现：利用HASH表可以快速实现对多个会话的处理；利用SYN算法可以成功实现TCP会话的恢复，并可以有效地解决IP数据包的乱序到达和TCP数据包的重传问题，误差率非常小且重组效率很高。<br/> <br/> ]]></description>
		</item>
		
			<item>
			<link>http://www.idcnote.com/default.asp?id=73</link>
			<title><![CDATA[Mysql-5.x上的插入空值BUG]]></title>
			<author>wentaiyou@126.com(kevin)</author>
			<category><![CDATA[编程学习]]></category>
			<pubDate>Fri,21 Jan 2011 23:05:30 +0800</pubDate>
			<guid>http://www.idcnote.com/default.asp?id=73</guid>	
		<description><![CDATA[这种问题一般mysql 5.x上出现。我用的mysql5.1，后面查询得知新版本mysql对空值插入有&#34;bug&#34;,要在安装mysql的时候去除默认勾选的enable strict SQL mode。如果已经安装好了的，就在my.ini中查找sql-mode，默认为sql-mode=&#34;STRICT_TRANS_TABLES,NO_AUTO_Cr&#101;ate_USER,NO_ENGINE_SUBSTITUTION&#34;，将其修改为sql-mode=&#34;NO_AUTO_Cr&#101;ate_USER,NO_ENGINE_SUBSTITUTION&#34;，重启mysql后即可。<br/><br/><br/>报错提示:<br/>1366 - Incorrect integer value: &#39;&#39; for column &#39;id&#39; at row<br/><br/><br/>解决办法:<br/>找到MY.INI文件将原先下面这句<br/>sql-mode=&#34;STRICT_TRANS_TABLES,NO_AUTO_Cr&#101;ate_USER,NO_ENGINE_SUBSTITUTION&#34;<br/>换成如下:<br/>sql-mode=&#34;NO_AUTO_Cr&#101;ate_USER,NO_ENGINE_SUBSTITUTION&#34;]]></description>
		</item>
		
			<item>
			<link>http://www.idcnote.com/default.asp?id=72</link>
			<title><![CDATA[PHP-38条PHP编码优化加速技巧]]></title>
			<author>wentaiyou@126.com(kevin)</author>
			<category><![CDATA[编程学习]]></category>
			<pubDate>Mon,27 Dec 2010 15:21:53 +0800</pubDate>
			<guid>http://www.idcnote.com/default.asp?id=72</guid>	
		<description><![CDATA[1. 尽量采用大量的PHP内置函数。<br/>2. echo 比 print 快。<br/>3. 不要把方法细分得过多，仔细想想你真正打算重用的是哪些代码？<br/>4. 在执行for循环之前确定最大循环数，不要每循环一次都计算最大值。<br/>5. 注销那些不用的变量尤其是大数组，以便释放内存。<br/>6. 并非要用类实现所有的数据结构，数组也很有用。<br/>7.&nbsp;&nbsp;$row[‘id’]的效率是$row[id]的7倍。<br/>8. 在包含文件时使用完整路径，解析操作系统路径所需的时间会更少。<br/>9. 如果你想知道脚本开始执行（译注：即服务器端收到客户端请求）的时刻，使用$_SERVER[‘REQUEST_TIME’]要好于time()。<br/>10. 检查是否能用strncasecmp，strpbrk，stripos函数代替正则表达式完成相同功能。<br/>11. str_replace函数比preg_replace函数快，但strtr函数的效率是str_replace函数的四倍。<br/>12. 如果一个字符串替换函数，可接受数组或字符作为参数，并且参数长度不太长，那么可以考虑额外写一段替换代码，使得每次传递参数是一个字符，而不是只写一行代码接受数组作为查询和替换的参数。<br/>13. 使用选择分支语句（译注：即switch case）好于使用多个if，else if语句。<br/>14. 用@屏蔽错误消息的做法非常低效。<br/>15.&nbsp;&nbsp;打开apache的mod_deflate模块。<br/>16.&nbsp;&nbsp;数据库连接当使用完毕时应关掉。<br/>18.&nbsp;&nbsp;错误消息代价昂贵。<br/>19. 尽量不要在for循环中使用函数，比如for ($x=0; $x &lt; count($array); $x)每循环一次都会调用count()函数。<br/>20.&nbsp;&nbsp;在方法中递增局部变量，速度是最快的。几乎与在函数中调用局部变量的速度相当。<br/>21.&nbsp;&nbsp;递增一个全局变量要比递增一个局部变量慢2倍。<br/>22.&nbsp;&nbsp;递增一个对象属性（如：$this-&gt;prop++）要比递增一个局部变量慢3倍。<br/>23.&nbsp;&nbsp;递增一个未预定义的局部变量要比递增一个预定义的局部变量慢9至10倍。<br/>24.&nbsp;&nbsp; 仅定义一个局部变量而没在函数中调用它，同样会减慢速度（其程度相当于递增一个局部变量）。PHP大概会检查看是否存在全局变量。<br/>25. 方法调用看来与类中定义的方法的数量无关，因为我（在测试方法之前和之后都）添加了10个方法，但性能上没有变化。<br/>26. 派生类中的方法运行起来要快于在基类中定义的同样的方法。<br/>27. 调用带有一个参数的空函数，其花费的时间相当于执行7至8次的局部变量递增操作。类似的方法调用所花费的时间接近于15次的局部变量递增操作。<br/>28. 用单引号代替双引号来包含字符串，这样做会更快一些。因为PHP会在双引号包围的字符串中搜寻变量，单引号则不会。当然，只有当你不需要在字符串中包含变量时才可以这么做。<br/>29. 用echo 输出多个字符串时，用逗号代替句点来分隔字符串，速度更快。<br/>30. Apache解析一个PHP脚本的时间要比解析一个静态HTML页面慢2至10倍。尽量多用静态HTML页面，少用脚本。<br/>31. 除非脚本可以缓存，否则每次调用时都会重新编译一次。引入一套PHP缓存机制通常可以提升25%至100%的性能，以免除编译开销。<br/>32. 尽量做缓存，可使用memcached。memcached是一款高性能的内存对象缓存系统，可用来加速动态Web应用程序，减轻数据库负载。对运算码(OP code)的缓存很有用，使得脚本不必为每个请求做重新编译。<br/>33. 当操作字符串并需要检验其长度是否满足某种要求时，你想当然地会使用strlen()函数。此函数执行起来相当快，因为它不做任何计算，只返回在zval 结构（C的内置数据结构，用于存储PHP变量）中存储的已知字符串长度。但是，由于strlen()是函数，多多少少会有些慢，因为函数调用会经过诸多步 骤，如字母小写化（译注：指函数名小写化，PHP不区分函数名大小写）、哈希查找，会跟随被调用的函数一起执行。在某些情况下，你可以使用isset() 技巧加速执行你的代码。<br/>Ex.（举例如下）<br/>if (strlen($foo) &lt; 5) { echo “Foo is too short”; }<br/>vs.（与下面的技巧做比较）<br/>if (!isset($foo{5})) { echo “Foo is too short”; }<br/>调用isset()恰巧比strlen()快，因为与后者不同的是，isset()作为一种语言结构，意味着它的执行不需要函数查找和字母小写化。也就是说，实际上在检验字符串长度的顶层代码中你没有花太多开销。<br/>34. 当执行变量$i的递增或递减时，$i++会比++$i慢一些。这种差异是PHP特有的，并不适用于其他语言，所以请不要修改你的C或Java代码并指望它 们能立即变快，没用的。++$i更快是因为它只需要3条指令(opcodes)，$i++则需要4条指令。后置递增实际上会产生一个临时变量，这个临时变 量随后被递增。而前置递增直接在原值上递增。这是最优化处理的一种，正如Zend的PHP优化器所作的那样。牢记这个优化处理不失为一个好主意，因为并不 是所有的指令优化器都会做同样的优化处理，并且存在大量没有装配指令优化器的互联网服务提供商（ISPs）和服务器。<br/>35. 并不是事必面向对象(OOP)，面向对象往往开销很大，每个方法和对象调用都会消耗很多内存。<br/>36. 如果在代码中存在大量耗时的函数，你可以考虑用C扩展的方式实现它们。<br/>37. 评估检验(profile)你的代码。检验器会告诉你，代码的哪些部分消耗了多少时间。Xdebug调试器包含了检验程序，评估检验总体上可以显示出代码的瓶颈。<br/>38. mod_zip可作为Apache模块，用来即时压缩你的数据，并可让数据传输量降低80%。<br/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.idcnote.com/default.asp?id=71</link>
			<title><![CDATA[Centos Permission denied: http错误]]></title>
			<author>wentaiyou@126.com(kevin)</author>
			<category><![CDATA[GNU/Linux]]></category>
			<pubDate>Sat,18 Dec 2010 14:06:03 +0800</pubDate>
			<guid>http://www.idcnote.com/default.asp?id=71</guid>	
		<description><![CDATA[CentOS 下启动Httpd 失败，报 <br/><br/> (13)Permission denied: make_sock: could not bind to address [::]:8000<br/><br/> 因为 小于1024 的端口只能是ROOT占用，但8000已经大于这个数值。<br/><br/> Google 一下，发现原来是 SELinux&nbsp;&nbsp;安全机制的作用。<br/><br/>&nbsp;&nbsp;查看一下预定义<br/><br/>&nbsp;&nbsp;#semanage port -l<br/> <br/><br/>http_cache_port_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tcp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3128, 8080, 8118, 11211, 10001-10010<br/>http_cache_port_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;udp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3130, 11211<br/>http_port_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tcp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;80, 443, 488, 8008, 8009, 8443<br/><br/>soundd_port_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tcp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8000, 9433, 16001<br/><br/> 原来8000 已经被预定义占用了，所有不能使用8000端口。<br/><br/>&nbsp;&nbsp;# semanage port -a -t http_port_t -p tcp 81 <br/><br/> 为Http 服务增加一个端口 81 ，同时将httpd 的端口改成 81 ，启动成功。<br/><br/><br/><br/>本文来自CSDN博客，转载请标明出处：<a href="http://blog.csdn.net/maoxiang/archive/2010/07/08/5720464.aspx" target="_blank">http://blog.csdn.net/maoxiang/archive/2010/07/08/5720464.aspx</a>]]></description>
		</item>
		
			<item>
			<link>http://www.idcnote.com/default.asp?id=70</link>
			<title><![CDATA[LINUX-多网卡识别顺序的问题]]></title>
			<author>wentaiyou@126.com(kevin)</author>
			<category><![CDATA[GNU/Linux]]></category>
			<pubDate>Tue,14 Dec 2010 22:31:32 +0800</pubDate>
			<guid>http://www.idcnote.com/default.asp?id=70</guid>	
		<description><![CDATA[参考：<br/>使用linux系统时会出现这样的情况，当你安装了某个网卡的驱动程序时，或者安装了与网卡相关的程序后。<br/><br/>网卡会出现所谓的漂移现象。(注意：不是飘逸)。可能的表象为:<br/><br/>（1）:网卡顺序颠倒，比如之前你的网线连接的网口为eth0,当安装某个网卡的驱动后，可能它的名字变为eth0或者eth3,等等情况。<br/><br/>(2):网卡名字改变，这种情况倒不是eth0到eth1的改变，而是很诡异的变化，比如eth0找不到了，多了个网卡名字叫 __tmp3183921382193__<br/><br/>这个确实让人很恼火。因为有人可能会通过ifconfig | grep eth来获取信息从而完成一些开发工作，如果网卡名字变得乌七八糟了，程序肯定会出错。<br/><br/>(3):光口网卡和电口网卡顺序乱了，或者交叉。<br/><br/>总之我们的目的就是：能够指定某个网卡的名字为我们想要的物理设备。做法如下:<br/><br/>第一步，识别谁是谁。<br/><br/>要使用网卡，首现要知道哪个名字对应的哪个物理设备，做法为:从交换机拉一根网线，从上到下挨个接到网卡上面，注意每次只能接一个网卡，接上后通过ethtool命令来查看是否连着网线，比如<br/><br/>[root@AS5 ~]# ethtool eth0<br/>Settings for eth0:<br/>Supported ports: [ MII ]<br/>Supported link modes:&nbsp;&nbsp; 10baseT/Half 10baseT/Full<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100baseT/Half 100baseT/Full<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1000baseT/Full<br/>Supports auto-negotiation: Yes<br/>Advertised link modes:&nbsp;&nbsp;10baseT/Half 10baseT/Full<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100baseT/Half 100baseT/Full<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1000baseT/Full<br/>Advertised auto-negotiation: Yes<br/>Speed: 100Mb/s<br/>Duplex: Full<br/>Port: MII<br/>PHYAD: 2<br/>Transceiver: external<br/>Auto-negotiation: on<br/>Supports Wake-on: g<br/>Wake-on: d<br/>Link detected: yes<br/><br/>看到了eth0的状态为连接着网线。如果Linked detected:no,则说明没有连接网线。<br/><br/>如此区分开哪个设备的名字是什么，标注好。<br/><br/>第二步：获取每个网卡的MAC地址<br/><br/>ifconfig -a能看到所有网络设备。<br/><br/>通过 ifconfig -a | grep HWaddr 来获取每个设备的MAC地址。<br/><br/>比如:<br/><br/>[root@AS5 ~]# ifconfig&nbsp;&nbsp;-a | grep HWaddr<br/>eth0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Link encap:Ethernet&nbsp;&nbsp;HWaddr 00:30:48:7F:B5:CA <br/>eth1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Link encap:Ethernet&nbsp;&nbsp;HWaddr 00:30:48:7F:B5:CB <br/>eth2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Link encap:Ethernet&nbsp;&nbsp;HWaddr 00:04:23:A6:81:E0 <br/>eth3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Link encap:Ethernet&nbsp;&nbsp;HWaddr 00:04:23:A6:81:E1<br/><br/>拿到了每个网卡的MAC地址。<br/><br/>第三步：进行MAC和网卡名称绑定。<br/><br/>我们都知道，对于RedHat的系统，网络的配置文件在:/etc/sysconfig/network-scripts/ifcfg-ethX<br/><br/>中存着，N=0，1，2。。。<br/><br/>比如:root@AS5 ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0<br/># nVidia Corporation MCP55 Ethernet<br/>DEVICE=eth0<br/>ONBOOT=yes<br/>HWADDR=00:30:48:7f:b5:ca<br/>TYPE=Ethernet<br/>NETMASK=255.255.255.0<br/>IPADDR=192.168.42.231<br/>GATEWAY=192.168.42.1<br/>BOOTPROTO=static<br/>#NAMESERVER=202.106.0.20<br/><br/>这个文件是对网卡进行初始化的配置文件。<br/><br/>比如如果我们想指定网卡MAC地址为MAC1的设备名称为ethn,那么，修改文件<br/><br/>/etc/sysconfig/network-scripts/ifcfg-ethn<br/><br/>在里面添加MAC地址绑定和名字的配置信息<br/><br/>DEVICE=ethn<br/><br/>HWADDR=MAC1（比如00:30:48:7f:b5:ca）<br/><br/>其它配置信息不受影响。<br/><br/>当对所有网卡实现绑定后，reboot系统，应该就可以了。<br/><br/>还有一点需要注意，就是驱动对应关系的文件:<br/><br/>/etc/modprobe.conf<br/><br/>要在该文件中修改，确保某个设备使用的就是对应它的驱动，比如:<br/><br/>cat /etc/modprobe.conf<br/>alias eth0 forcedeth<br/>alias eth1 forcedeth<br/>alias scsi_hostadapter aic79xx<br/>alias scsi_hostadapter1 sata_nv<br/>alias scsi_hostadapter2 usb-storage<br/>alias eth2 e1000<br/>alias eth3 e1000<br/><br/>说明eth0和eth1用的forcedeth的驱动，eth2和eth3用的是e1000的驱动。]]></description>
		</item>
		
</channel>
</rss>
