<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>大千世界 &#187; Tech</title>
	<atom:link href="http://www.zhangdaqian.net/blog/category/tech/feed" rel="self" type="application/rss+xml" />
	<link>http://www.zhangdaqian.net</link>
	<description>Hold Infinity in the palm of your hand</description>
	<lastBuildDate>Wed, 14 Jul 2010 16:25:07 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>vlc太恶心了</title>
		<link>http://www.zhangdaqian.net/blog/vlc%e5%a4%aa%e6%81%b6%e5%bf%83%e4%ba%86.htm</link>
		<comments>http://www.zhangdaqian.net/blog/vlc%e5%a4%aa%e6%81%b6%e5%bf%83%e4%ba%86.htm#comments</comments>
		<pubDate>Tue, 25 May 2010 13:43:56 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[darwin]]></category>
		<category><![CDATA[helix]]></category>
		<category><![CDATA[sdp]]></category>
		<category><![CDATA[vlc]]></category>

		<guid isPermaLink="false">http://www.zhangdaqian.net/blog/vlc%e5%a4%aa%e6%81%b6%e5%bf%83%e4%ba%86.htm</guid>
		<description><![CDATA[情况是这样的，使用helix做rtp relay服务器，后来发现在server2003下helix工作ok，在linux下，无法工作。
我抓狂啊！
好吧！我来查，会不会是操作系统的问题？ok，我装了rad hat 4，我装了centos，还是依旧。好吧，会不会是虚拟机的问题？我上服务器上测。still，我想跳楼了。。。。。
然后我怀疑sdp的问题，我直接把server2003下可以正常工作的文件拷过了，还是不行。。。
然后折腾了两天，终于发现vlc生成的sdp中，源使用windows机器名，放linux当然跑不起来。。。。。。
疯了。。。。。。。。。。。。
Random Posts

浪潮之巅第一章 — 帝国的余辉（AT&#038;T）（三）
苏ICP备08109458号
终极目标!!奋斗~~~
次贷危机ABC
央视元宵节大火真相

]]></description>
			<content:encoded><![CDATA[<p>情况是这样的，使用helix做rtp relay服务器，后来发现在server2003下helix工作ok，在linux下，无法工作。</p>
<p>我抓狂啊！</p>
<p>好吧！我来查，会不会是操作系统的问题？ok，我装了rad hat 4，我装了centos，还是依旧。好吧，会不会是虚拟机的问题？我上服务器上测。still，我想跳楼了。。。。。</p>
<p>然后我怀疑sdp的问题，我直接把server2003下可以正常工作的文件拷过了，还是不行。。。</p>
<p>然后折腾了两天，终于发现vlc生成的sdp中，源使用windows机器名，放linux当然跑不起来。。。。。。</p>
<p>疯了。。。。。。。。。。。。</p>
<h3>Random Posts</h3>
<ul class="related_post">
<li><a href="http://www.zhangdaqian.net/blog/%e5%a4%ae%e8%a7%86%e5%a4%a7%e8%a3%a4%e8%a1%a9.htm" title="央视大裤衩">央视大裤衩</a></li>
<li><a href="http://www.zhangdaqian.net/blog/chapter-1-the-top-of-the-wave-the-afterglow-empire.htm" title="浪潮之巅第一章 — 帝国的余辉">浪潮之巅第一章 — 帝国的余辉</a></li>
<li><a href="http://www.zhangdaqian.net/blog/fedsky%e9%aa%8c%e8%af%81.htm" title="fedsky验证">fedsky验证</a></li>
<li><a href="http://www.zhangdaqian.net/blog/%e4%ba%ba%e7%94%9f%e5%b0%b1%e5%83%8f%e8%8c%b6%e5%87%a0%ef%bc%8c%e6%91%86%e6%bb%a1%e4%ba%86%e6%9d%af%e5%85%b7.htm" title="人生就像茶几，摆满了杯具">人生就像茶几，摆满了杯具</a></li>
<li><a href="http://www.zhangdaqian.net/blog/%e7%94%9f%e6%b4%bb%e4%b8%ad%e5%b8%b8%e8%a7%81%e7%9a%84%e9%80%bb%e8%be%91%e8%b0%ac%e8%af%af-zz.htm" title="生活中常见的逻辑谬误-zz">生活中常见的逻辑谬误-zz</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.zhangdaqian.net/blog/vlc%e5%a4%aa%e6%81%b6%e5%bf%83%e4%ba%86.htm/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>NAT Order of Operation</title>
		<link>http://www.zhangdaqian.net/blog/nat-order-of-operation.htm</link>
		<comments>http://www.zhangdaqian.net/blog/nat-order-of-operation.htm#comments</comments>
		<pubDate>Thu, 08 Oct 2009 10:16:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[cisco]]></category>

		<guid isPermaLink="false">http://www.zhangdaqian.net/blog/nat-order-of-operation.htm</guid>
		<description><![CDATA[Introduction
This document illustrates that the order in which transactions are processed using Network Address Translation (NAT) is based on whether a packet is going from the inside network to the outside network, or from the outside network to the inside network.
Prerequisites
Requirements
Readers of this document should have knowledge of the following topic:


Network Address Translation (NAT). For [...]]]></description>
			<content:encoded><![CDATA[<h2><a id="intro" name="intro">Introduction</a></h2>
<p>This document illustrates that the order in which transactions are processed using Network Address Translation (NAT) is based on whether a packet is going from the inside network to the outside network, or from the outside network to the inside network.</p>
<h2><a id="prereq" name="prereq">Prerequisites</a></h2>
<h3><a id="req" name="req">Requirements</a></h3>
<p>Readers of this document should have knowledge of the following topic:</p>
<ul>
<li>
<p>Network Address Translation (NAT). For more information on NAT, see <a href="http://www.cisco.com/warp/customer/556/nat-cisco.shtml">How NAT Works</a>.</p>
</li>
</ul>
<h3><a id="hw" name="hw">Components Used</a></h3>
<p>This document is not restricted to specific software and hardware versions.</p>
<p><strong>Note:</strong> The information in this document is based on the Software Version, Cisco IOS® Software Release 12.2(27)</p>
<h3><a id="conv" name="conv">Conventions</a></h3>
<p>For more information on document conventions, refer to the <a href="http://www.cisco.com/en/US/tech/tk801/tk36/technologies_tech_note09186a0080121ac5.shtml">Cisco Technical Tips Conventions</a>.</p>
<p> <span id="more-242"></span><br />
<h2><a id="topic1" name="topic1">NAT Overview</a></h2>
<p>In the table below, when NAT performs the global to local, or local to global, translation is different in each flow.</p>
<table cellpadding="3" width="60%" cellspacing="1" border="1" bgcolor="#FFFFFF">
<tbody>
<tr>
<th bgcolor="#CCCCFF">
<p>Inside-to-Outside</p>
</th>
<th bgcolor="#CCCCFF">
<p>Outside-to-Inside</p>
</th>
</tr>
<tr>
<td bgcolor="#FFFFFF">
<ul>
<li>
<p>If IPSec then check input access list</p>
</li>
<li>
<p>decryption &#8211; for CET (Cisco Encryption Technology) or IPSec</p>
</li>
<li>
<p>check input access list</p>
</li>
<li>
<p>check input rate limits</p>
</li>
<li>
<p>input accounting</p>
</li>
<li>
<p>policy routing</p>
</li>
<li>
<p>routing</p>
</li>
<li>
<p>redirect to web cache</p>
</li>
<li>
<p><strong>NAT inside to outside (local to global translation)</strong></p>
</li>
<li>
<p>crypto (check map and mark for encryption)</p>
</li>
<li>
<p>check output access list</p>
</li>
<li>
<p>inspect (Context-based Access Control (CBAC))</p>
</li>
<li>
<p>TCP intercept</p>
</li>
<li>
<p>encryption</p>
</li>
<li>
<p>Queueing</p>
</li>
</ul>
</td>
<td bgcolor="#FFFFFF">
<ul>
<li>
<p>If IPSec then check input access list</p>
</li>
<li>
<p>decryption &#8211; for CET or IPSec</p>
</li>
<li>
<p>check input access list</p>
</li>
<li>
<p>check input rate limits</p>
</li>
<li>
<p>input accounting</p>
</li>
<li>
<p><strong>NAT outside to inside (global to local translation)</strong></p>
</li>
<li>
<p>policy routing</p>
</li>
<li>
<p>routing</p>
</li>
<li>
<p>redirect to web cache</p>
</li>
<li>
<p>crypto (check map and mark for encryption)</p>
</li>
<li>
<p>check output access list</p>
</li>
<li>
<p>inspect CBAC</p>
</li>
<li>
<p>TCP intercept</p>
</li>
<li>
<p>encryption</p>
</li>
<li>
<p>Queueing</p>
</li>
</ul>
</td>
</tr>
</tbody>
</table>
<h2><a id="topic2" name="topic2">NAT Configuration and Output</a></h2>
<p>The following example demonstrates how the order of operations can effect NAT. In this case, only NAT and routing are shown.</p>
<p><img src="http://www.cisco.com/image/gif/paws/6209/5a-1.gif" height="123" width="575" usemap="" alt="5a-1.gif" border="0"/></p>
<p>In the above example, Router-A is configured to translate the inside local address 171.68.200.48 to 172.16.47.150, as shown in the configuration below.</p>
<blockquote>
<pre>
!
version 11.2
no service udp-small-servers
no service tcp-small-servers
!
hostname Router-A
!
enable password ww
!
<strong>ip nat inside source static 171.68.200.48 172.16.47.150</strong>
<em>
              <span style="COLOR: #0000ff">!--- This command creates a static NAT translation !--- between 171.68.200.48 and 172.16.47.150 </span>
            </em>
ip domain-name cisco.com
ip name-server 171.69.2.132
!
interface Ethernet0
 no ip address
 shutdown
!
interface Serial0
 ip address 172.16.47.161 255.255.255.240
 <strong>ip nat inside</strong>
<em>
              <span style="COLOR: #0000ff">!--- Configures Serial0 as the NAT inside interface</span>
            </em>
 no ip mroute-cache
 no ip route-cache
 no fair-queue
!
interface Serial1
 ip address 172.16.47.146 255.255.255.240
 <strong>ip nat outside</strong>
<em>
              <span style="COLOR: #0000ff">!--- Configures Serial1 as the NAT outside interface</span>
            </em>
 no ip mroute-cache
 no ip route-cache
!
no ip classless
<strong>ip route 0.0.0.0 0.0.0.0 172.16.47.145</strong>
<em>
              <span style="COLOR: #0000ff">!--- Configures a default route to 172.16.47.145</span>
            </em>

ip route 171.68.200.0 255.255.255.0 172.16.47.162
!
!
line con 0
 exec-timeout 0 0
line aux 0
line vty 0 4
 password ww
 login
!
end
</pre>
</blockquote>
<p>The translation table indicates that the intended translation exists.</p>
<blockquote>
<pre>
Router-A#<strong>show ip nat translation</strong>
Pro Inside global      Inside local       Outside local      Outside global
--- 172.16.47.150      171.68.200.48      ---                ---
</pre>
</blockquote>
<p>The following output is taken from Router-A with <strong><a href="http://www.cisco.com/en/US/docs/ios/12_3t/debug/command/reference/dbg_i2gt.html#wp1086651">debug ip packet detail</a></strong> and <strong><a href="http://www.cisco.com/en/US/docs/ios/12_3t/debug/command/reference/dbg_i2gt.html#wp1127362">debug ip nat</a></strong> enabled, and a ping issued from device 171.68.200.48 destined for 172.16.47.142.</p>
<p><strong>Note:</strong> Debug commands generate a significant amount of output. Use them only when traffic on the IP network is low, so other activity on the system is not adversely affected. Before issuing <strong>debug</strong> commands, please see <a href="http://www.cisco.com/en/US/tech/tk801/tk379/technologies_tech_note09186a008017874c.shtml">Important Information on Debug Commands</a>.</p>
<blockquote>
<pre>
IP: s=171.68.200.48 (Serial0), d=172.16.47.142, len 100, unroutable
    ICMP type=8, code=0
IP: s=172.16.47.161 (local), d=171.68.200.48 (Serial0), len 56, sending
    ICMP type=3, code=1
IP: s=171.68.200.48 (Serial0), d=172.16.47.142, len 100, unroutable
    ICMP type=8, code=0
IP: s=171.68.200.48 (Serial0), d=172.16.47.142, len 100, unroutable
    ICMP type=8, code=0
IP: s=172.16.47.161 (local), d=171.68.200.48 (Serial0), len 56, sending
    ICMP type=3, code=1
IP: s=171.68.200.48 (Serial0), d=172.16.47.142, len 100, unroutable
    ICMP type=8, code=0
IP: s=171.68.200.48 (Serial0), d=172.16.47.142, len 100, unroutable
    ICMP type=8, code=0
IP: s=172.16.47.161 (local), d=171.68.200.48 (Serial0), len 56, sending
    ICMP type=3, code=1
</pre>
</blockquote>
<p>Since there are no NAT debug messages in the output above, you know that the existing static translation is not being used and that the router does not have a route for the destination address (172.16.47.142) in its routing table. The result of the non-routable packet is an <a href="http://www.iana.org/assignments/icmp-parameters">ICMP Unreachable message</a>, which is sent to the inside device.</p>
<p>However, Router-A has a default route of 172.16.47.145, so why is the route considered non-routable?</p>
<p>Router-A has <strong>no ip classless</strong> configured, which means if a packet destined for a &#8220;major&#8221; network address (in this case, 172.16.0.0) for which subnets exist in the routing table, the router does not rely on the default route. In other words, issuing the <strong>no ip classless</strong> command turns off the router&#8217;s ability to look for the route with the longest bit match. To change this behavior, you have to configure <strong><a href="http://www.cisco.com/en/US/docs/ios/12_2/ipaddr/command/reference/fipras_r.html#wp1018033">ip classless</a></strong> on Router-A. The <strong><a href="http://www.cisco.com/en/US/docs/ios/12_2/ipaddr/command/reference/fipras_r.html#wp1018033">ip classless</a></strong> command is enabled by default on Cisco routers with IOS Version 11.3 and above.</p>
<blockquote>
<pre>
Router-A#<strong>configure terminal</strong>
Enter configuration commands, one per line.  End with CTRL/Z.
Router-A(config)#<strong>ip classless</strong>
Router-A(config)#<strong>end</strong>

Router-A#<strong>show ip nat translation</strong>
%SYS-5-CONFIG_I: Configured from console by console nat tr
Pro Inside global      Inside local       Outside local      Outside global
--- 172.16.47.150      171.68.200.48      ---                ---
</pre>
</blockquote>
<p>Repeating the same ping test as before, we see that the packet gets translated and the ping is successful.</p>
<blockquote>
<pre>
Ping Response on device 171.68.200.48

D:\&gt;ping 172.16.47.142
Pinging 172.16.47.142 with 32 bytes of data:

Reply from 172.16.47.142: bytes=32 time=10ms TTL=255
Reply from 172.16.47.142: bytes=32 time&lt;10ms TTL=255
Reply from 172.16.47.142: bytes=32 time&lt;10ms TTL=255
Reply from 172.16.47.142: bytes=32 time&lt;10ms TTL=255

Ping statistics for 172.16.47.142:
    Packets: Sent = 4, Received = 4, Lost = 0 (0%)
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum =  10ms, Average =  2ms

Debug messages on Router A indicating that the packets generated by device
171.68.200.48 are getting translated by NAT. 

Router-A#
<strong>*Mar 28 03:34:28: IP: tableid=0, s=171.68.200.48 (Serial0), d=172.16.47.142 (Serial1), routed via RIB</strong>
<strong>*Mar 28 03:34:28: NAT: s=171.68.200.48-&gt;172.16.47.150, d=172.16.47.142 [160]</strong>
<strong>*Mar 28 03:34:28: IP: s=172.16.47.150 (Serial0), d=172.16.47.142 (Serial1), g=172.16.47.145, len 100, forward</strong>
<strong>*Mar 28 03:34:28: ICMP type=8, code=0</strong>
<strong>*Mar 28 03:34:28: NAT*: s=172.16.47.142, d=172.16.47.150-&gt;171.68.200.48 [160]</strong>
<strong>*Mar 28 03:34:28: IP: tableid=0, s=172.16.47.142 (Serial1), d=171.68.200.48 (Serial0), routed via RIB</strong>
<strong>*Mar 28 03:34:28: IP: s=172.16.47.142 (Serial1), d=171.68.200.48 (Serial0), g=172.16.47.162, len 100, forward</strong>
<strong>*Mar 28 03:34:28: ICMP type=0, code=0</strong>
*Mar 28 03:34:28: NAT*: s=171.68.200.48-&gt;172.16.47.150, d=172.16.47.142 [161]
*Mar 28 03:34:28: NAT*: s=172.16.47.142, d=172.16.47.150-&gt;171.68.200.48 [161]
*Mar 28 03:34:28: IP: tableid=0, s=172.16.47.142 (Serial1), d=171.68.200.48
(Serial0), routed via RIB
*Mar 28 03:34:28: IP: s=172.16.47.142 (Serial1), d=171.68.200.48 (Serial0),
g=172.16.47.162, len 100, forward
*Mar 28 03:34:28: ICMP type=0, code=0
*Mar 28 03:34:28: NAT*: s=171.68.200.48-&gt;172.16.47.150, d=172.16.47.142 [162]
*Mar 28 03:34:28: NAT*: s=172.16.47.142, d=172.16.47.150-&gt;171.68.200.48 [162]
*Mar 28 03:34:28: IP: tableid=0, s=172.16.47.142 (Serial1), d=171.68.200.48
(Serial0), routed via RIB
*Mar 28 03:34:28: IP: s=172.16.47.142 (Serial1), d=171.68.200.48 (Serial0),
g=172.16.47.162, len 100, forward
*Mar 28 03:34:28: ICMP type=0, code=0
*Mar 28 03:34:28: NAT*: s=171.68.200.48-&gt;172.16.47.150, d=172.16.47.142 [163]
*Mar 28 03:34:28: NAT*: s=172.16.47.142, d=172.16.47.150-&gt;171.68.200.48 [163]
*Mar 28 03:34:28: IP: tableid=0, s=172.16.47.142 (Serial1), d=171.68.200.48
(Serial0), routed via RIB
*Mar 28 03:34:28: IP: s=172.16.47.142 (Serial1), d=171.68.200.48 (Serial0),
g=172.16.47.162, len 100, forward
*Mar 28 03:34:28: ICMP type=0, code=0
*Mar 28 03:34:28: NAT*: s=171.68.200.48-&gt;172.16.47.150, d=172.16.47.142 [164]
*Mar 28 03:34:28: NAT*: s=172.16.47.142, d=172.16.47.150-&gt;171.68.200.48 [164]
*Mar 28 03:34:28: IP: tableid=0, s=172.16.47.142 (Serial1), d=171.68.200.48
(Serial0), routed via RIB
*Mar 28 03:34:28: IP: s=172.16.47.142 (Serial1), d=171.68.200.48 (Serial0),
g=172.16.47.162, len 100, forward
*Mar 28 03:34:28: ICMP type=0, code=0

Router-A#<strong>undebug all</strong>
All possible debugging has been turned off
</pre>
</blockquote>
<p>The above example shows that when a packet is traversing inside to outside, a NAT router checks its routing table for a route to the outside address before it continues to translate the packet. Therefore, it is important that the NAT router has a valid route for the outside network. The route to the destination network must be known through an interface that is defined as <a href="http://www.cisco.com/warp/customer/556/8.html">NAT outside</a> in the router configuration.</p>
<p>It is important to note that the return packets are translated before they are routed. Therefore, the NAT router must also have a valid route for the <a href="http://www.cisco.com/warp/customer/556/8.html">Inside local address</a> in its routing table.</p>
<h3>你还想看</h3>
<ul class="related_post">
<li><a href="http://www.zhangdaqian.net/blog/%e4%ba%ba%e7%94%9f%e5%b0%b1%e5%83%8f%e8%8c%b6%e5%87%a0%ef%bc%8c%e6%91%86%e6%bb%a1%e4%ba%86%e6%9d%af%e5%85%b7.htm" title="人生就像茶几，摆满了杯具">人生就像茶几，摆满了杯具</a></li>
<li><a href="http://www.zhangdaqian.net/blog/natpat%e4%b8%ad%e5%af%b9%e4%ba%8eftp%e7%9a%84%e5%a4%84%e7%90%86%ef%bc%8c%e4%bb%a5%e5%8f%8apat%e5%90%8e%e7%9a%84%e9%9d%9e%e6%a0%87%e5%87%8621-ftp%e7%ab%af%e5%8f%a3%e8%ae%be%e7%bd%ae.htm" title="NAT/PAT中对于FTP的处理，以及PAT后的非标准21 FTP端口设置">NAT/PAT中对于FTP的处理，以及PAT后的非标准21 FTP端口设置</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.zhangdaqian.net/blog/nat-order-of-operation.htm/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NAT/PAT中对于FTP的处理，以及PAT后的非标准21 FTP端口设置</title>
		<link>http://www.zhangdaqian.net/blog/natpat%e4%b8%ad%e5%af%b9%e4%ba%8eftp%e7%9a%84%e5%a4%84%e7%90%86%ef%bc%8c%e4%bb%a5%e5%8f%8apat%e5%90%8e%e7%9a%84%e9%9d%9e%e6%a0%87%e5%87%8621-ftp%e7%ab%af%e5%8f%a3%e8%ae%be%e7%bd%ae.htm</link>
		<comments>http://www.zhangdaqian.net/blog/natpat%e4%b8%ad%e5%af%b9%e4%ba%8eftp%e7%9a%84%e5%a4%84%e7%90%86%ef%bc%8c%e4%bb%a5%e5%8f%8apat%e5%90%8e%e7%9a%84%e9%9d%9e%e6%a0%87%e5%87%8621-ftp%e7%ab%af%e5%8f%a3%e8%ae%be%e7%bd%ae.htm#comments</comments>
		<pubDate>Sat, 19 Sep 2009 14:40:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[cisco]]></category>
		<category><![CDATA[ftp]]></category>
		<category><![CDATA[nat]]></category>

		<guid isPermaLink="false">http://www.zhangdaqian.net/blog/natpat%e4%b8%ad%e5%af%b9%e4%ba%8eftp%e7%9a%84%e5%a4%84%e7%90%86%ef%bc%8c%e4%bb%a5%e5%8f%8apat%e5%90%8e%e7%9a%84%e9%9d%9e%e6%a0%87%e5%87%8621-ftp%e7%ab%af%e5%8f%a3%e8%ae%be%e7%bd%ae.htm</guid>
		<description><![CDATA[
这里先要对FTP的两种模式说一下：

引用一张Cisco上面的图：
http://www.cisco.com/image/gif/paws/82018/pix-asa-enable-ftp-2.gif

 
FTP分为两种模式： 主动Active 被动 Passive
主动模式下是使用21作为控制， 20作为数据口。
首先是客户端通过大于1023的端口发起到服务器21端口的控制连接，信息交换完成后。服务器从20端口发起连接到客户端提供的接收端口。
这是传统意义上的FTP行为。
被动模式是使用21作为控制，然后服务器自动选择一个大于1023的端口作为数据。
首先是客户端通过大于1023的端口发起到服务器21端口的控制连接，信息交换完成后。服务器告诉客户端一个大于1023的端口作为数据口，
然后客户端再以另外一个大于1023的端口发起连接到服务器提供的数据端口进行数据传输。
目前大多数服务器都支持这种模式，而且大部分客户端都默认采用被动模式和服务器进行传输。
好了，当我们在内网有两台服务器FTP SEVER1和FTP SERVER2都需要被外网访问的时侯，我们会分别为这两个服务器做映射出去。
假定FTP SERVE1(10.0.0.100)占用公网IP(x.x.x.x)的21端口，FTP SERVER2(10.0.0.200)占用公网IP(x.x.x.x)的2211端口。那么我们就会这么写：
ip nat inside source static tcp 10.0.0.100 21 x.x.x.x 21 extendable

ip nat inside source static tcp 10.0.0.200 21 x.x.x.x 2211 extendable
这样做了以后，我们会发现FTP SERVER1是正常的，而FTP SERVER2却不正常，表现为登录以后无法列出目录:
以下为FTP 客户端的LOG：


[xx:xx:03] PASV [xx:xx:03] 227 Entering Passive Mode (10,0,0,200,6,32) [xx:xx:24] Data Socket Error: Connection timed out [xx:xx:24] List Complete: 0 bytes in 21.44 (1.00 [...]]]></description>
			<content:encoded><![CDATA[<div>
<div>这里先要对FTP的两种模式说一下：</div>
</p></div>
<div>引用一张Cisco上面的图：</div>
<div><a href="http://www.cisco.com/image/gif/paws/82018/pix-asa-enable-ftp-2.gif">http://www.cisco.com/image/gif/paws/82018/pix-asa-enable-ftp-2.gif</a></div>
<div><img src="http://www.cisco.com/image/gif/paws/82018/pix-asa-enable-ftp-2.gif" style="WIDTH: 564px; HEIGHT: 457px" height="30" width="179" usemap="" alt="pix-asa-enable-ftp-2.gif" border="0"/></div>
<p> <span id="more-240"></span>
<div>FTP分为两种模式： 主动Active 被动 Passive</div>
<div>主动模式下是使用21作为控制， 20作为数据口。</div>
<div>首先是客户端通过大于1023的端口发起到服务器21端口的控制连接，信息交换完成后。服务器从20端口发起连接到客户端提供的接收端口。</div>
<div>这是传统意义上的FTP行为。</div>
<div>被动模式是使用21作为控制，然后服务器自动选择一个大于1023的端口作为数据。</div>
<div>首先是客户端通过大于1023的端口发起到服务器21端口的控制连接，信息交换完成后。服务器告诉客户端一个大于1023的端口作为数据口，</div>
<div>然后客户端再以另外一个大于1023的端口发起连接到服务器提供的数据端口进行数据传输。</div>
<div>目前大多数服务器都支持这种模式，而且大部分客户端都默认采用被动模式和服务器进行传输。</div>
<div>好了，当我们在内网有两台服务器FTP SEVER1和FTP SERVER2都需要被外网访问的时侯，我们会分别为这两个服务器做映射出去。</div>
<div>假定FTP SERVE1(10.0.0.100)占用公网IP(x.x.x.x)的21端口，FTP SERVER2(10.0.0.200)占用公网IP(x.x.x.x)的2211端口。那么我们就会这么写：</div>
<div>ip nat inside source static tcp 10.0.0.100 21 x.x.x.x 21 extendable</div>
<div>
<div>ip nat inside source static tcp 10.0.0.200 21 x.x.x.x 2211 extendable</div>
<div>这样做了以后，我们会发现FTP SERVER1是正常的，而FTP SERVER2却不正常，表现为登录以后无法列出目录:</div>
<div>以下为FTP 客户端的LOG：</div>
<div>
<hr/></div>
<div>[xx:xx:03] PASV <br/>[xx:xx:03] 227 Entering Passive Mode (10,0,0,200,6,32) <br/>[xx:xx:24] Data Socket Error: Connection timed out <br/>[xx:xx:24] List Complete: 0 bytes in 21.44 (1.00 KBps)<br />
<hr/></div>
<div>这是为什么呢？</div>
<div>答案就是在被动模式下，FTP SEVER告诉客户端的数据端口，无法被访问。为什么 FTP SERVER1又可以呢？</div>
<div>因为FTP SERVER1在对外映射的时侯采用了21端口，IOS会自动识别这个端口是FTP控制口，</div>
<div>从而去检查里面FTP数据控制数据发现服务器告诉客户端的这个用于传送数据的端口，然后自动的添加一条映射。</div>
<div>phanx# sh ip nat tr | in 10.0.0.100: <br/>tcp x.x.x.x:21 10.0.0.100:21 y.y.y.y:1585 y.y.y.y:1585 <br/>tcp x.x.x.x:21 10.0.0.100:21 &#8211; - <br/>tcp x.x.x.x:1812 10.0.0.20:1812 y.y.y.y:1594 y.y.y.y:1594</div>
<div>而FTP SERVER2映射的端口2211无法自动被识别成FTP端口，所以IOS不会自动的为它建立数据端口的映射。</div>
<div>解决的办法就是用 ip nat service 来指定这个端口。</div>
<div>access-list <strong>10</strong> permit 10.0.0.200</div>
<div>ip nat service <strong>10</strong> ftp tcp port 21</div>
<div>注意，这里的tcp port 21是指的 10.0.0.200的FTP端口21而不是 x.x.x.x的2211。如果FTP SERVER2用的FTP端口是其他的，那么就写对应的端口号。</div>
<div>这样做了以后，我们的FTP SERVER2就可以以 x.x.x.x:2211 的方式被公网访问了。</div>
<div>说道这里，问题已经解决了。但是，有人可能会提出来，既然FTP SERVER1用被动很正常，x.x.x.x:20端口并没有使用，</div>
<div>那为什么不用把FTP SERVER2主动模式来映射呢？比如这样做:</div>
<div>ip nat inside source static tcp 10.0.0.200 20 x.x.x.x 20 extendable</div>
<div>
<div>ip nat inside source static tcp 10.0.0.200 21 x.x.x.x 2211 extendable</div>
</p></div>
<div>OK. 这样做其实对于一部分情况是没有问题的。例如客户机的地址是公网地址，或者说能被FTP SERVER2所访问的地址。</div>
<div>但是如果客户机也是通过NAT/PAT上网的呢？假设客户端地址是192.168.1.111我们将看到这样的情况：</div>
<div>
<hr/></div>
<div>[00:14:10] PORT <strong><span style="COLOR: #ff0000">192,168,1,111</span></strong> ,6,179 <br/>[00:14:10] 200 PORT Command successful. <br/>[00:14:10] REST 2028256 <br/>[00:14:10] 350 Restarting at 2028256. Send STORE or RETRIEVE. <br/>[00:14:10] RETR fool.exe <br/>[00:14:10] 150 Opening BINARY mode data connection for fool.exe (924668 Bytes). <br/>[00:14:11] 425 Cannot open data connection. <br/>[00:14:11] Transfer Failed!<br />
<hr/></div>
<div>因为是主动模式，是服务器主动送数据给客户机。那客户机通过控制信息就需要告诉服务器往哪里送，</div>
<div>但是FTP客户端并不知道自己的公网地址和端口，并且客户机也没有能力去自己的NAT/PAT网关上去开放一个端口让服务器来送数据。</div>
<div>所以它是以自己的实际地址去告诉服务器的。对于服务器而言，这个地址是无法被访问到的，所以这个办法也有行不通的地方。</div>
<div>当然，如果FTP客户端支持uPNP能识别到翻译后的公网地址，NAT/PAT网关也有uPNP的能力的话，主动模式的这个问题应该就能解决。</div>
<div>BTW：主动模式的FTP又被称为 &#8220;firewall <span style="COLOR: #ff0000">UN</span>friendly&#8221;，什么原因？ 好好理解哦～</div>
<div>PIX/ASA上面的配置方法见：</div>
<div>
<h2><strong>PIX/ASA 7.x: Enable FTP/TFTP Services Configuration Example</strong></h2>
<p><a href="http://www.cisco.com/en/US/products/ps6120/products_configuration_example09186a00807ee585.shtml">http://www.cisco.com/en/US/products/ps6120/products_configuration_example09186a00807ee585.shtml</a></p>
</p></div>
</p></div>
<h3>你还想看</h3>
<ul class="related_post">
<li><a href="http://www.zhangdaqian.net/blog/%e4%ba%ba%e7%94%9f%e5%b0%b1%e5%83%8f%e8%8c%b6%e5%87%a0%ef%bc%8c%e6%91%86%e6%bb%a1%e4%ba%86%e6%9d%af%e5%85%b7.htm" title="人生就像茶几，摆满了杯具">人生就像茶几，摆满了杯具</a></li>
<li><a href="http://www.zhangdaqian.net/blog/nat-order-of-operation.htm" title="NAT Order of Operation">NAT Order of Operation</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.zhangdaqian.net/blog/natpat%e4%b8%ad%e5%af%b9%e4%ba%8eftp%e7%9a%84%e5%a4%84%e7%90%86%ef%bc%8c%e4%bb%a5%e5%8f%8apat%e5%90%8e%e7%9a%84%e9%9d%9e%e6%a0%87%e5%87%8621-ftp%e7%ab%af%e5%8f%a3%e8%ae%be%e7%bd%ae.htm/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>about ip address</title>
		<link>http://www.zhangdaqian.net/blog/about-ip-address.htm</link>
		<comments>http://www.zhangdaqian.net/blog/about-ip-address.htm#comments</comments>
		<pubDate>Thu, 27 Aug 2009 09:27:58 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[ip]]></category>
		<category><![CDATA[rfc]]></category>

		<guid isPermaLink="false">http://www.zhangdaqian.net/blog/about-ip-address.htm</guid>
		<description><![CDATA[

http://www.rfc-editor.org/rfc/rfc3330.txt


 Address Block             Present Use                       Reference
   ---------------------------------------------------------------------
   0.0.0.0/8          [...]]]></description>
			<content:encoded><![CDATA[
<pre>
<a href="http://www.rfc-editor.org/rfc/rfc3330.txt">http://www.rfc-editor.org/rfc/rfc3330.txt</a>
</pre>
<pre>
 Address Block             Present Use                       Reference
   ---------------------------------------------------------------------
   0.0.0.0/8            "This" Network                 [RFC1700, page 4]
   10.0.0.0/8           Private-Use Networks                   [RFC1918]
   14.0.0.0/8           Public-Data Networks         [RFC1700, page 181]
   24.0.0.0/8           Cable Television Networks                    --
   39.0.0.0/8           Reserved but subject
                           to allocation                       [RFC1797]
   127.0.0.0/8          Loopback                       [RFC1700, page 5]
   128.0.0.0/16         Reserved but subject
                           to allocation                             --
   169.254.0.0/16       Link Local                                   --
   172.16.0.0/12        Private-Use Networks                   [RFC1918]
   191.255.0.0/16       Reserved but subject
                           to allocation                             --
   192.0.0.0/24         Reserved but subject
                           to allocation                             --
   192.0.2.0/24         Test-Net
   192.88.99.0/24       6to4 Relay Anycast                     [RFC3068]
   192.168.0.0/16       Private-Use Networks                   [RFC1918]
   198.18.0.0/15        Network Interconnect
                           Device Benchmark Testing            [RFC2544]
   223.255.255.0/24     Reserved but subject
                           to allocation                             --
   224.0.0.0/4          Multicast                              [RFC3171]
   240.0.0.0/4          Reserved for Future Use        [RFC1700, page 4]
</pre>
<h3>Random Posts</h3>
<ul class="related_post">
<li><a href="http://www.zhangdaqian.net/blog/congratulations-universe-zhengshishangxian.htm" title="祝贺大千世界正式上线">祝贺大千世界正式上线</a></li>
<li><a href="http://www.zhangdaqian.net/blog/%e9%83%bd%e5%a4%a7%e5%b9%b4%e4%b8%89%e5%8d%81%e4%ba%86%ef%bc%8c%e4%bd%a0%e4%bb%ac%e5%93%8e.htm" title="都大年三十了，你们哎">都大年三十了，你们哎</a></li>
<li><a href="http://www.zhangdaqian.net/blog/%e5%8e%bb%e6%af%9b%e5%b9%bf%e5%91%8a.htm" title="去毛广告">去毛广告</a></li>
<li><a href="http://www.zhangdaqian.net/blog/%e7%a2%8e%e6%80%9d%e8%83%a1%e8%a8%80%e4%b9%b1%e8%af%ad.htm" title="碎思&#038;胡言乱语">碎思&#038;胡言乱语</a></li>
<li><a href="http://www.zhangdaqian.net/blog/%e7%bb%88%e6%9e%81%e7%9b%ae%e6%a0%87%e5%a5%8b%e6%96%97.htm" title="终极目标!!奋斗~~~">终极目标!!奋斗~~~</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.zhangdaqian.net/blog/about-ip-address.htm/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Understanding SVI Autostate Exclude</title>
		<link>http://www.zhangdaqian.net/blog/understanding-svi-autostate-exclude.htm</link>
		<comments>http://www.zhangdaqian.net/blog/understanding-svi-autostate-exclude.htm#comments</comments>
		<pubDate>Mon, 24 Aug 2009 15:28:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://www.zhangdaqian.net/blog/understanding-svi-autostate-exclude.htm</guid>
		<description><![CDATA[To be &#8220;up/up,&#8221; a router VLAN interface must fulfill the following general conditions:
•The VLAN exists and is &#8220;active&#8221; on the VLAN database of the switch.
•The VLAN interface exists on the router and is not administratively down.
•At least one Layer 2 (access port or trunk) port exists, has a link &#8220;up&#8221; on this VLAN and is [...]]]></description>
			<content:encoded><![CDATA[<h3 class="p_H_Head2">To be &#8220;up/up,&#8221; a router VLAN interface must fulfill the following general conditions:</h3>
<p class="pBu1_Bullet1">•<img src="http://www.cisco.com/en/US/i/templates/blank.gif" alt="" height="2" border="0" width="19"/>The VLAN exists and is &#8220;active&#8221; on the VLAN database of the switch.</p>
<p class="pBu1_Bullet1">•<img src="http://www.cisco.com/en/US/i/templates/blank.gif" alt="" height="2" border="0" width="19"/>The VLAN interface exists on the router and is not administratively down.</p>
<p class="pBu1_Bullet1">•<img src="http://www.cisco.com/en/US/i/templates/blank.gif" alt="" height="2" border="0" width="19"/>At least one Layer 2 (access port or trunk) port exists, has a link &#8220;up&#8221; on this VLAN and is in spanning-tree forwarding state on the VLAN.</p>
<h3>Random Posts</h3>
<ul class="related_post">
<li><a href="http://www.zhangdaqian.net/blog/%e3%80%90zz%e8%87%aa%e8%b7%af%e7%94%b1%e3%80%91%e5%bd%93%e6%89%80%e6%9c%89%e7%9a%84%e6%a2%a6%e6%83%b3%e5%8f%98%e6%88%90%e4%ba%86%e7%90%86%e6%83%b3%ef%bc%8c%e4%b9%9f%e5%bd%93%e6%89%80%e6%9c%89%e7%9a%84.htm" title="【ZZ自路由】当所有的梦想变成了理想，也当所有的理想变成了梦想">【ZZ自路由】当所有的梦想变成了理想，也当所有的理想变成了梦想</a></li>
<li><a href="http://www.zhangdaqian.net/blog/%e5%a4%9c%e5%a4%9c%e5%a4%9cyeah%e8%82%89%e8%82%89%e8%82%89%e8%af%b1.htm" title="夜夜夜yeah~肉肉肉诱~">夜夜夜yeah~肉肉肉诱~</a></li>
<li><a href="http://www.zhangdaqian.net/blog/%e5%8f%b2%e8%ae%b0%c2%b7%e9%99%88%e5%86%a0%e5%b8%8c%e5%88%97%e4%bc%a0.htm" title="史记·陈冠希列传">史记·陈冠希列传</a></li>
<li><a href="http://www.zhangdaqian.net/blog/closing-the-gaap-accounting-principles-generally-accepted-in-the-end.htm" title="Closing the GAAP 结束公认会计准则">Closing the GAAP 结束公认会计准则</a></li>
<li><a href="http://www.zhangdaqian.net/blog/%e6%b5%b7%e9%87%8f%e6%97%a5%e5%bf%97%e5%88%86%e6%9e%90%e9%a2%84%e5%91%8a%e7%af%87.htm" title="海量日志分析预告篇">海量日志分析预告篇</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.zhangdaqian.net/blog/understanding-svi-autostate-exclude.htm/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DNS缓存投毒细节泄露</title>
		<link>http://www.zhangdaqian.net/blog/dns%e7%bc%93%e5%ad%98%e6%8a%95%e6%af%92%e7%bb%86%e8%8a%82%e6%b3%84%e9%9c%b2.htm</link>
		<comments>http://www.zhangdaqian.net/blog/dns%e7%bc%93%e5%ad%98%e6%8a%95%e6%af%92%e7%bb%86%e8%8a%82%e6%b3%84%e9%9c%b2.htm#comments</comments>
		<pubDate>Thu, 30 Apr 2009 13:36:56 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[DNS缓存]]></category>
		<category><![CDATA[攻击]]></category>
		<category><![CDATA[转载]]></category>

		<guid isPermaLink="false">http://www.zhangdaqian.net/blog/dns%e7%bc%93%e5%ad%98%e6%8a%95%e6%af%92%e7%bb%86%e8%8a%82%e6%b3%84%e9%9c%b2.htm</guid>
		<description><![CDATA[昨天Mantasano上的一篇文章描述了Dan Kaminsky的DNS域名服务器攻击的细节。该文章发表了几分钟之后即被删掉了。 虽然Dan Kaminsky已经联合厂商发布了补丁，但是仍处于补丁推送阶段，目前仍有相当一部分域名服务器还没有打补丁。如果被恶意利用的话，对整个互联网还是很有威胁的。这也是为什么Dan 希望 &#8220;not speculate publicly&#8221;。 大概看了一下那篇hypothesis，基本上还是利用了&#8221;Cache 投毒&#8221;（cache poisoning）的方法，不过使用了一些新的技巧。 DNS查询是如何进行的？对于绝大多数桌面系统来说，DNS的查询并不是由自己的机器完成的，DNS查询会提交给另一台DNS服务器（这台服务器通常是由 ISP或者公司提供），然后这台服务器再去进行真正的查询操作。这样做的好处是DNS的查询结果可以由这台机器给缓存下来，从而提高查询效率并降低由 DNS带来的流量开销。 一台缓存DNS服务器（与权威DNS相对，这类系统提供的）下面的桌面系统可能有几百、几千、几万甚至几十万台桌面系统。 DNS缓存中毒攻击指的是更改了DNS服务器的DNS缓存中某项，这样缓存中与主机名相关的IP地址就不再指向正确的位置。例如，如果 www.example.com映射到IP地址192.168.0.1且DNS服务器的缓存中存在这个映射，则成功向这个服务器的DNS缓存投毒的攻击者就可以将www.example.com映射到10.0.0.1。在这种情况下，试图访问www.example.com的用户就可能与错误的Web服务器联络。 当攻击者试图请求查询某站点的域名时，DNS服务器首先会检查自己的DNS缓存中是否存在该域名，如果存在则将该域名所对应的IP地址返回给请求者，如果不存在则向上一级DNS或者权威DNS查询。这就会给攻击者带来一定的困难，如果是大一点的站点的话，攻击者发起DNS查询时，DNS服务器直接从缓存应答了，根本不会去请求权威域名服务器。怎么才能解决这个问题呢？云舒在他的DNS缓存中毒漏洞的一点推测中也提到过。 比如我们要攻击www.google.com.首先向目的DNS服务器查询根本不存在的二级域名，比如：aaa.google.com. DNS服务器在缓存中查找aaa.google.com,没有找到，则会向上级DNS或者权威DNS查询 。这时我们可以生成伪造的DNS Response数据包并发送这些的伪造DNS Response数据包给目的服务器。让目的DNS在上级DNS或者权威DNS服务器响应到达之前，接受到恶意的应答。 从表面上看这样只是截持了一个不存在的二级域名，只能用来钓钓鱼罢了。 其实DNS Response数据包可以不仅仅包含aaa.google.com的IP地址，还可以在DNS 数据包的Additional resource record中包含www.google.com的IP地址（当然该IP地址可以是伪造的）。当目的DNS收到该数据报时会将伪造的IP地址与 www.google.com关联起来并刷新到缓存上。这样就完成了主域名的截持。
Random Posts

加密日志测试
呆呆PS正式Beta
无知真可怕
DOTA之最高境界
网测有感

]]></description>
			<content:encoded><![CDATA[<p>昨天Mantasano上的一篇文章描述了Dan Kaminsky的DNS域名服务器攻击的细节。该文章发表了几分钟之后即被删掉了。 <br/>虽然Dan Kaminsky已经联合厂商发布了补丁，但是仍处于补丁推送阶段，目前仍有相当一部分域名服务器还没有打补丁。如果被恶意利用的话，对整个互联网还是很有威胁的。这也是为什么Dan 希望 &#8220;not speculate publicly&#8221;。 <br/>大概看了一下那篇hypothesis，基本上还是利用了&#8221;Cache 投毒&#8221;（cache poisoning）的方法，不过使用了一些新的技巧。 <br/><span id="more-2187"><br/>DNS查询是如何进行的？对于绝大多数桌面系统来说，DNS的查询并不是由自己的机器完成的，DNS查询会提交给另一台DNS服务器（这台服务器通常是由 ISP或者公司提供），然后这台服务器再去进行真正的查询操作。这样做的好处是DNS的查询结果可以由这台机器给缓存下来，从而提高查询效率并降低由 DNS带来的流量开销。 <br/>一台缓存DNS服务器（与权威DNS相对，这类系统提供的）下面的桌面系统可能有几百、几千、几万甚至几十万台桌面系统。 <br/>DNS缓存中毒攻击指的是更改了DNS服务器的DNS缓存中某项，这样缓存中与主机名相关的IP地址就不再指向正确的位置。例如，如果 www.example.com映射到IP地址192.168.0.1且DNS服务器的缓存中存在这个映射，则成功向这个服务器的DNS缓存投毒的攻击者就可以将www.example.com映射到10.0.0.1。在这种情况下，试图访问www.example.com的用户就可能与错误的Web服务器联络。 <br/>当攻击者试图请求查询某站点的域名时，DNS服务器首先会检查自己的DNS缓存中是否存在该域名，如果存在则将该域名所对应的IP地址返回给请求者，如果不存在则向上一级DNS或者权威DNS查询。这就会给攻击者带来一定的困难，如果是大一点的站点的话，攻击者发起DNS查询时，DNS服务器直接从缓存应答了，根本不会去请求权威域名服务器。怎么才能解决这个问题呢？云舒在他的<a href="http://www.icylife.net/yunshu/show.php?id=586" target="_blank">DNS缓存中毒漏洞的一点推测</a>中也提到过。 <br/>比如我们要攻击www.google.com.首先向目的DNS服务器查询根本不存在的二级域名，比如：aaa.google.com. DNS服务器在缓存中查找aaa.google.com,没有找到，则会向上级DNS或者权威DNS查询 。这时我们可以生成伪造的DNS Response数据包并发送这些的伪造DNS Response数据包给目的服务器。让目的DNS在上级DNS或者权威DNS服务器响应到达之前，接受到恶意的应答。 <br/>从表面上看这样只是截持了一个不存在的二级域名，只能用来钓钓鱼罢了。 <br/>其实DNS Response数据包可以不仅仅包含aaa.google.com的IP地址，还可以在DNS 数据包的Additional resource record中包含www.google.com的IP地址（当然该IP地址可以是伪造的）。当目的DNS收到该数据报时会将伪造的IP地址与 www.google.com关联起来并刷新到缓存上。这样就完成了主域名的截持。</span></p>
<h3>Random Posts</h3>
<ul class="related_post">
<li><a href="http://www.zhangdaqian.net/blog/%e7%bb%8f%e6%b5%8e%e5%8d%b1%e6%9c%ba%e4%b8%ad%e7%9a%84500%e5%bc%balogo.htm" title="经济危机中的500强Logo">经济危机中的500强Logo</a></li>
<li><a href="http://www.zhangdaqian.net/blog/lycoris-radiata-herb.htm" title="曼珠沙华">曼珠沙华</a></li>
<li><a href="http://www.zhangdaqian.net/blog/%e6%97%a0%e7%9f%a5%e7%9c%9f%e5%8f%af%e6%80%95.htm" title="无知真可怕">无知真可怕</a></li>
<li><a href="http://www.zhangdaqian.net/blog/%e7%94%9f%e6%b4%bb%e4%b8%ad%e5%b8%b8%e8%a7%81%e7%9a%84%e9%80%bb%e8%be%91%e8%b0%ac%e8%af%af-zz.htm" title="生活中常见的逻辑谬误-zz">生活中常见的逻辑谬误-zz</a></li>
<li><a href="http://www.zhangdaqian.net/blog/zz-10-on-26-students-nationwide-long-distance-race-every-day.htm" title="zz 10月26日起全国学生每天都要长跑">zz 10月26日起全国学生每天都要长跑</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.zhangdaqian.net/blog/dns%e7%bc%93%e5%ad%98%e6%8a%95%e6%af%92%e7%bb%86%e8%8a%82%e6%b3%84%e9%9c%b2.htm/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>通过emule做DDOS是否可行？</title>
		<link>http://www.zhangdaqian.net/blog/%e9%80%9a%e8%bf%87emule%e5%81%9addos%e6%98%af%e5%90%a6%e5%8f%af%e8%a1%8c%ef%bc%9f.htm</link>
		<comments>http://www.zhangdaqian.net/blog/%e9%80%9a%e8%bf%87emule%e5%81%9addos%e6%98%af%e5%90%a6%e5%8f%af%e8%a1%8c%ef%bc%9f.htm#comments</comments>
		<pubDate>Thu, 30 Apr 2009 13:25:38 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[DDOS]]></category>
		<category><![CDATA[emule]]></category>
		<category><![CDATA[网络]]></category>

		<guid isPermaLink="false">http://www.zhangdaqian.net/blog/%e9%80%9a%e8%bf%87emule%e5%81%9addos%e6%98%af%e5%90%a6%e5%8f%af%e8%a1%8c%ef%bc%9f.htm</guid>
		<description><![CDATA[by 云舒
今天抽空看了下emule协议几个可能会出问题的地方，初步感觉是可能真的有问题。下了代码回来看了，不过代码太大，目前还没找到地方，没法对想法进行印证。我简单的说下，看哪位代码牛人能够在项目中找到对应的代码。
首先是在客户端连接到服务器之后，搜索文件时，服务器返回结果的报文。报文中返回的结果是一个集合，每个集合表示一条记录。但是每条记录中，并不包含拥有该文件的客户端的IP地址，而是返回的拥有该文件的客户端的ClientID和端口。这里我猜测ClientID的计算是可逆的，搜索发起者可以根据这个 ClientID计算出IP地址，然后连接，请求下载文件。具体报文结构如下： 



名称
大小（字节）
默认值
注释


协议类型
1
0xE3
 

大小
4

不包含报文和大小域的报文大小


类型
1
0&#215;16
操作码 OP SEARCHRESULT 的值


结果数
4
N/A
此报文中包含的结果数目


结果列表
可变
N/A
一个结果的列表



搜索结果列表项格式：



名称
大小（字节）
默认值
注释


文件HASH
16
N/A
用于识别文件的 Hash 值


客户端 ID
4
N/A
eMule服务器分配给客户端的ID


客户端端口
2
N/A
客户端的监听的TCP端口


标志数
4
N/A
其后的属性标志个数


标志列表
可变
N/A
标志列表



其次的第二个地方是下载文件的地方，客户端要求下载一个文件时，服务器会返回一个源查找结果报文。该报文也是只包含源的ClientID和端口，客户端应该是按照ClientID计算出IP地址，再去连接下载文件的。具体报文如下：



名称
大小（字节）
默认值
注释


协议类型
1
0xE3
 

大小
4
N/A
不包含报文头和大小域的报文大小


类型
1
0&#215;42
操作码 OP FOUNDSOURCES 的值


文件HASH
16
N/A
相关文件的 Hash 值


源数量
1
N/A
拥有该文件的机器的数量


源列表
可变
N/A
源列表内容，每一条是一个可用源



每一条源的报文格式如下：



名称
大小（字节）
默认值
注释


客户端 ID
4
N/A
共享该文件的客户端的 ID


客户端端口
2
N/A
共享该文件的客户端端口



可以看到，搜索某个文件时，服务器返回的搜索列表中按照ClientID来区分不同的其它客户端。在开始下载一个文件时，服务器返回的可用源列表中，每个源也是以一个ClientID来表示的。也就是说，没一个ClientID就可以确定一个源，区分开彼此。而emule可以根据这个ClientID找到对应的客户端，去连接指定端口，请求文件。那么，现在的问题是这个ClientID是哪里来的？
原来这个ClientID在正常情况下，是我们连接到emule服务器时，服务器分配给我们的。但是注意到，在连接之后，我们可以像服务器提供我们所拥有的文件列表，报文格式如下：



名称
大小（字节）
默认值
注释


协议类型
1
0xE3
 

大小
4

不包含报文和大小域的报文大小


类型
1
0&#215;15
操作码 OP SEARCHRESULT 的值


文件数
4
N/A
共享列表中的文件数，这个数不超过 200


文件列表
可变
N/A
可选的文件列表,单个项的描述见下



单个文件条目描述我就不细写了，比较有用的字段是文件Hash码，ClientID，以及端口。这样看来，我们在连接到服务器之后，告诉它baidu的IP地址，TCP80端口，有赤壁下载，或者有XXX片下载，别人下载的时候，emule客户端会不会从服务器返回的可用源列表中，找到这条记录，并且去连接？
关键问题到了ClientID的计算，协议中这样描述的：假设 IP 地址为 X.Y.Z.W,则客户端 ID 按公式 X+28*Y+216*Z+24*W (Big Endian[6])计算。如果想法是正确的，那么我们可以先计算出百度的IP地址的ClientID，端口设置为80，然后通知服务器，这个 ClientID有高树的片子可以看……
你还想看

Windows XP的无线桥接

]]></description>
			<content:encoded><![CDATA[<p>by 云舒</p>
<p>今天抽空看了下emule协议几个可能会出问题的地方，初步感觉是可能真的有问题。下了代码回来看了，不过代码太大，目前还没找到地方，没法对想法进行印证。我简单的说下，看哪位代码牛人能够在项目中找到对应的代码。</p>
<p>首先是在客户端连接到服务器之后，搜索文件时，服务器返回结果的报文。报文中返回的结果是一个集合，每个集合表示一条记录。但是每条记录中，并不包含拥有该文件的客户端的IP地址，而是返回的拥有该文件的客户端的ClientID和端口。这里我猜测ClientID的计算是可逆的，搜索发起者可以根据这个 ClientID计算出IP地址，然后连接，请求下载文件。具体报文结构如下： <br/><span id="more-2186"/></p>
<table cellpadding="1" width="80%" cellspacing="1" border="1">
<tbody>
<tr>
<td>名称</td>
<td>大小（字节）</td>
<td>默认值</td>
<td>注释</td>
</tr>
<tr>
<td>协议类型</td>
<td>1</td>
<td>0xE3</td>
<td/> </tr>
<tr>
<td>大小</td>
<td>4</td>
<td/>
<td>不包含报文和大小域的报文大小</td>
</tr>
<tr>
<td>类型</td>
<td>1</td>
<td>0&#215;16</td>
<td>操作码 OP SEARCHRESULT 的值</td>
</tr>
<tr>
<td>结果数</td>
<td>4</td>
<td>N/A</td>
<td>此报文中包含的结果数目</td>
</tr>
<tr>
<td>结果列表</td>
<td>可变</td>
<td>N/A</td>
<td>一个结果的列表</td>
</tr>
</tbody>
</table>
<p>搜索结果列表项格式：</p>
<table cellpadding="1" width="80%" cellspacing="1" border="1">
<tbody>
<tr>
<td>名称</td>
<td>大小（字节）</td>
<td>默认值</td>
<td>注释</td>
</tr>
<tr>
<td>文件HASH</td>
<td>16</td>
<td>N/A</td>
<td>用于识别文件的 Hash 值</td>
</tr>
<tr>
<td>客户端 ID</td>
<td>4</td>
<td>N/A</td>
<td>eMule服务器分配给客户端的ID</td>
</tr>
<tr>
<td>客户端端口</td>
<td>2</td>
<td>N/A</td>
<td>客户端的监听的TCP端口</td>
</tr>
<tr>
<td>标志数</td>
<td>4</td>
<td>N/A</td>
<td>其后的属性标志个数</td>
</tr>
<tr>
<td>标志列表</td>
<td>可变</td>
<td>N/A</td>
<td>标志列表</td>
</tr>
</tbody>
</table>
<p>其次的第二个地方是下载文件的地方，客户端要求下载一个文件时，服务器会返回一个源查找结果报文。该报文也是只包含源的ClientID和端口，客户端应该是按照ClientID计算出IP地址，再去连接下载文件的。具体报文如下：</p>
<table cellpadding="1" width="80%" cellspacing="1" border="1">
<tbody>
<tr>
<td>名称</td>
<td>大小（字节）</td>
<td>默认值</td>
<td>注释</td>
</tr>
<tr>
<td>协议类型</td>
<td>1</td>
<td>0xE3</td>
<td/> </tr>
<tr>
<td>大小</td>
<td>4</td>
<td>N/A</td>
<td>不包含报文头和大小域的报文大小</td>
</tr>
<tr>
<td>类型</td>
<td>1</td>
<td>0&#215;42</td>
<td>操作码 OP FOUNDSOURCES 的值</td>
</tr>
<tr>
<td>文件HASH</td>
<td>16</td>
<td>N/A</td>
<td>相关文件的 Hash 值</td>
</tr>
<tr>
<td>源数量</td>
<td>1</td>
<td>N/A</td>
<td>拥有该文件的机器的数量</td>
</tr>
<tr>
<td>源列表</td>
<td>可变</td>
<td>N/A</td>
<td>源列表内容，每一条是一个可用源</td>
</tr>
</tbody>
</table>
<p>每一条源的报文格式如下：</p>
<table cellpadding="1" width="80%" cellspacing="1" border="1">
<tbody>
<tr>
<td>名称</td>
<td>大小（字节）</td>
<td>默认值</td>
<td>注释</td>
</tr>
<tr>
<td>客户端 ID</td>
<td>4</td>
<td>N/A</td>
<td>共享该文件的客户端的 ID</td>
</tr>
<tr>
<td>客户端端口</td>
<td>2</td>
<td>N/A</td>
<td>共享该文件的客户端端口</td>
</tr>
</tbody>
</table>
<p>可以看到，搜索某个文件时，服务器返回的搜索列表中按照ClientID来区分不同的其它客户端。在开始下载一个文件时，服务器返回的可用源列表中，每个源也是以一个ClientID来表示的。也就是说，没一个ClientID就可以确定一个源，区分开彼此。而emule可以根据这个ClientID找到对应的客户端，去连接指定端口，请求文件。那么，现在的问题是这个ClientID是哪里来的？</p>
<p>原来这个ClientID在正常情况下，是我们连接到emule服务器时，服务器分配给我们的。但是注意到，在连接之后，我们可以像服务器提供我们所拥有的文件列表，报文格式如下：</p>
<table cellpadding="1" width="80%" cellspacing="1" border="1">
<tbody>
<tr>
<td>名称</td>
<td>大小（字节）</td>
<td>默认值</td>
<td>注释</td>
</tr>
<tr>
<td>协议类型</td>
<td>1</td>
<td>0xE3</td>
<td/> </tr>
<tr>
<td>大小</td>
<td>4</td>
<td/>
<td>不包含报文和大小域的报文大小</td>
</tr>
<tr>
<td>类型</td>
<td>1</td>
<td>0&#215;15</td>
<td>操作码 OP SEARCHRESULT 的值</td>
</tr>
<tr>
<td>文件数</td>
<td>4</td>
<td>N/A</td>
<td>共享列表中的文件数，这个数不超过 200</td>
</tr>
<tr>
<td>文件列表</td>
<td>可变</td>
<td>N/A</td>
<td>可选的文件列表,单个项的描述见下</td>
</tr>
</tbody>
</table>
<p>单个文件条目描述我就不细写了，比较有用的字段是文件Hash码，ClientID，以及端口。这样看来，我们在连接到服务器之后，告诉它baidu的IP地址，TCP80端口，有赤壁下载，或者有XXX片下载，别人下载的时候，emule客户端会不会从服务器返回的可用源列表中，找到这条记录，并且去连接？</p>
<p>关键问题到了ClientID的计算，协议中这样描述的：假设 IP 地址为 X.Y.Z.W,则客户端 ID 按公式 X+28*Y+216*Z+24*W (Big Endian[6])计算。如果想法是正确的，那么我们可以先计算出百度的IP地址的ClientID，端口设置为80，然后通知服务器，这个 ClientID有高树的片子可以看……</p>
<h3>你还想看</h3>
<ul class="related_post">
<li><a href="http://www.zhangdaqian.net/blog/windows-xp%e7%9a%84%e6%97%a0%e7%ba%bf%e6%a1%a5%e6%8e%a5.htm" title="Windows XP的无线桥接">Windows XP的无线桥接</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.zhangdaqian.net/blog/%e9%80%9a%e8%bf%87emule%e5%81%9addos%e6%98%af%e5%90%a6%e5%8f%af%e8%a1%8c%ef%bc%9f.htm/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting Started With JGAP</title>
		<link>http://www.zhangdaqian.net/blog/getting-started-with-jgap.htm</link>
		<comments>http://www.zhangdaqian.net/blog/getting-started-with-jgap.htm#comments</comments>
		<pubDate>Tue, 21 Apr 2009 12:31:27 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[JAVA]]></category>
		<category><![CDATA[JGAP]]></category>
		<category><![CDATA[遗传算法]]></category>

		<guid isPermaLink="false">http://www.zhangdaqian.net/blog/getting-started-with-jgap.htm</guid>
		<description><![CDATA[Preface: Please note that this documentation could be correlated to a former JGAP version. Therefor we recommend having a look at the examples provided with JGAP and then read this document in order to get an idea.
To use JGAP in an application, there are five basic things that you must do:


Plan your Chromosome.


Implement a &#8220;fitness [...]]]></description>
			<content:encoded><![CDATA[<p class="text"><a id="top" name="top"><strong>Preface: Please note that this documentation could be correlated to a former JGAP version. Therefor we recommend having a look at the examples provided with JGAP and then read this document in order to get an idea.</strong></a></p>
<p class="text"><a id="top" name="top">To use JGAP in an application, there are five basic things that you must do:</a></p>
<ol>
<li>
<p class="text"><a href="http://jgap.sourceforge.net/doc/tutorial.html#step1">Plan your Chromosome.</a></p>
</li>
<li>
<p class="text"><a href="http://jgap.sourceforge.net/doc/tutorial.html#step2">Implement a &#8220;fitness function&#8221;.</a></p>
</li>
<li>
<p class="text"><a href="http://jgap.sourceforge.net/doc/tutorial.html#step3">Setup a Configuration object.</a></p>
</li>
<li>
<p class="text"><a href="http://jgap.sourceforge.net/doc/tutorial.html#step4">Create a population of potential solutions.</a></p>
</li>
<li>
<p class="text"><a href="http://jgap.sourceforge.net/doc/tutorial.html#step5">Evolve the population!</a></p>
</li>
</ol>
<p class="text">Through the course of this tutorial, we&#8217;ll build a simple example program that makes use of JGAP. The goal of our program will be to produce a user-specified amount of change in the fewest possible American coins (quarters, dimes, nickels, and pennies).</p>
<p> <span id="more-214"></span><br />
<h3 class="subheader"><a id="step1" name="step1">Step 1: Plan your Chromosome</a></h3>
<p class="text"><a id="step1" name="step1">At the heart of the genetic algorithm is the Chromosome. The Chromosome represents a potential solution and is divided into multiple genes. Genes in JGAP represent distinct aspects of the solution as a whole, just as human genes represent distinct aspects of individual people, such as their sex or eye color. During the JGAP evolution process, chromosomes are exposed to multiple genetic operators that represent mating, mutation, etc. and then are chosen for the next generation during a natural selection phase based upon their &#8220;fitness,&#8221; which is a measure of how optimal that solution is relative to other potential solutions. The entire goal of the genetic algorithm is to mimic the natural process of evolution in order to produce superior solutions.</a></p>
<p class="text"><a id="step1" name="step1">Step 1, therefore, is to decide on the makeup of your chromosomes, which includes how many genes you want and what those genes will represent. In our sample program, we want to create a pile of change that contains the fewest possible American coins that total up to the amount specified by the user. Since a chromosome represents a potential solution, in our sample it will represent a pile of change. We&#8217;ll setup our genes to represent the different denominations of coins so that we&#8217;ll have a total of four genes per chromosome (one each for quarters, dimes, nickels, and pennies).</a></p>
<p style="TEXT-ALIGN: center"><a id="step1" name="step1"><img src="http://jgap.sourceforge.net/doc/chromosome.png" alt="(Diagram of a Chromosome with four genes: quarters, dimes, nickels, and pennies.)" height="150" class="diagram" width="300"/></a></p>
<p class="text"><a id="step1" name="step1">We&#8217;ll actually write the code to setup our Chromosome objects in</a> <a href="http://jgap.sourceforge.net/doc/tutorial.html#step3">step 3</a>.</p>
<h3 class="subheader"><a id="step2" name="step2">Step 2: Implementing a Fitness Function</a></h3>
<p class="text">JGAP is designed to do almost all of the evolutionary work for you in a relatively generic fashion. However, it has no knowledge of the specific problem you&#8217;re actually trying to solve, and hence has no intrinsic way of deciding if one potential solution is any better than another potential solution for your specific problem. That&#8217;s where the fitness function comes in: it&#8217;s a single method that you must implement that accepts a potential problem solution and returns an integer value that indicates how good (or &#8220;fit&#8221;) that solution is relative to other possible solutions. The higher the number, the better the solution. The lower the number (1 being the lowest legal fitness value), the poorer the solution. JGAP will use these fitness measurements to evolve the population of solutions toward a more optimal set of solutions.</p>
<p class="text">Let&#8217;s start with a fully-working example of a fitness function, the details of which will be explained below. Since the goal of our small program is to produce an amount of change in American coins equal to a target amount in the fewest possible number of coins, it seems reasonable that the measure of fitness for a particular solution would be a combination of the relative closeness of the amount of change it represented to the target amount of change, and the total number of coins represented by the solution (fewer being better).</p>
<pre class="Listing">
<tt>
            <strong>
              <span style="COLOR: #000080">package</span>
            </strong> <span style="COLOR: #000000">examples;</span>

<strong>
              <span style="COLOR: #000080">import</span>
            </strong> <span style="COLOR: #000000">org.jgap.Chromosome;</span>
<strong>
              <span style="COLOR: #000080">import</span>
            </strong> <span style="COLOR: #000000">org.jgap.FitnessFunction;</span>

<em>
              <span style="COLOR: #808080">/**</span>
            </em>
<em>
              <span style="COLOR: #808080">* This class provides an implementation of the classic "Make change" problem</span>
            </em>
<em>
              <span style="COLOR: #808080">* using a genetic algorithm. The goal of the problem is to provide a</span>
            </em>
<em>
              <span style="COLOR: #808080">* specified amount of change (from a cash purchase) in the fewest coins</span>
            </em>
<em>
              <span style="COLOR: #808080">* possible. This example implementation uses American currency (quarters,</span>
            </em>
<em>
              <span style="COLOR: #808080">* dimes, nickels, and pennies).</span>
            </em>
<em>
              <span style="COLOR: #808080">*</span>
            </em>
<em>
              <span style="COLOR: #808080">* This example may be seen as somewhat significant because it demonstrates</span>
            </em>
<em>
              <span style="COLOR: #808080">* the use of a genetic algorithm in a less-than-optimal problem space.</span>
            </em>
<em>
              <span style="COLOR: #808080">* The genetic algorithm does best when there is a smooth slope of fitness</span>
            </em>
<em>
              <span style="COLOR: #808080">* over the problem space towards the optimum solution. This problem exhibits</span>
            </em>
<em>
              <span style="COLOR: #808080">* a more choppy space with more local optima. However, as can be seen from</span>
            </em>
<em>
              <span style="COLOR: #808080">* running this example, the genetic algorithm still will get the correct</span>
            </em>
<em>
              <span style="COLOR: #808080">* answer virtually everytime.</span>
            </em>
<em>
              <span style="COLOR: #808080">*/</span>
            </em>
<strong>
              <span style="COLOR: #000080">public</span>
            </strong> <strong>
              <span style="COLOR: #000080">class</span>
            </strong> <span style="COLOR: #000000">MinimizingMakeChangeFitnessFunction</span> <strong>
              <span style="COLOR: #000080">extends</span>
            </strong> <span style="COLOR: #000000">FitnessFunction</span>
<span style="COLOR: #000000">{</span>
    <strong>
              <span style="COLOR: #000080">private</span>
            </strong> <strong>
              <span style="COLOR: #000080">final</span>
            </strong> <strong>
              <span style="COLOR: #000080">int</span>
            </strong> <span style="COLOR: #000000">m_targetAmount;</span>

    <em>
              <span style="COLOR: #808080">/**</span>
            </em>
<em>
              <span style="COLOR: #808080">* Constructs this MinimizingMakeChangeFitnessFunction with the desired</span>
            </em>
<em>
              <span style="COLOR: #808080">* amount of change to make.</span>
            </em>
<em>
              <span style="COLOR: #808080">*</span>
            </em>
<em>
              <span style="COLOR: #808080">* @param a_targetAmount The desired amount of change, in cents. This</span>
            </em>
<em>
              <span style="COLOR: #808080">* value must be between 1 and 99 cents.</span>
            </em>
<em>
              <span style="COLOR: #808080">*/</span>
            </em>
    <strong>
              <span style="COLOR: #000080">public</span>
            </strong> <span style="COLOR: #000000">MinimizingMakeChangeFitnessFunction(</span> <strong>
              <span style="COLOR: #000080">int</span>
            </strong> <span style="COLOR: #000000">a_targetAmount</span> <span style="COLOR: #000000">)</span>
    <span style="COLOR: #000000">{</span>
        <strong>
              <span style="COLOR: #000080">if</span>
            </strong>
            <span style="COLOR: #000000">(</span> <span style="COLOR: #000000">a_targetAmount</span> <span style="COLOR: #000000">&lt;</span> <span style="COLOR: #0000ff">1</span> <span style="COLOR: #000000">||</span> <span style="COLOR: #000000">a_targetAmount</span> <span style="COLOR: #000000">&gt;</span> <span style="COLOR: #0000ff">99</span> <span style="COLOR: #000000">)</span>
        <span style="COLOR: #000000">{</span>
            <strong>
              <span style="COLOR: #000080">throw</span>
            </strong> <strong>
              <span style="COLOR: #000080">new</span>
            </strong> <span style="COLOR: #000000">IllegalArgumentException(</span>
                <strong>
              <span style="COLOR: #009900">"Change amount must be between 1 and 99 cents."</span>
            </strong> <span style="COLOR: #000000">);</span>
        <span style="COLOR: #000000">}</span>

        <span style="COLOR: #000000">m_targetAmount</span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000">a_targetAmount;</span>
    <span style="COLOR: #000000">}</span>

    <em>
              <span style="COLOR: #808080">/**</span>
            </em>
<em>
              <span style="COLOR: #808080">* Determine the fitness of the given Chromosome instance. The higher the</span>
            </em>
<em>
              <span style="COLOR: #808080">* return value, the more fit the instance. This method should always</span>
            </em>
<em>
              <span style="COLOR: #808080">* return the same fitness value for two equivalent Chromosome instances.</span>
            </em>
<em>
              <span style="COLOR: #808080">*</span>
            </em>
<em>
              <span style="COLOR: #808080">* @param a_subject: The Chromosome instance to evaluate.</span>
            </em>
<em>
              <span style="COLOR: #808080">*</span>
            </em>
<em>
              <span style="COLOR: #808080">* @return A positive integer reflecting the fitness rating of the given</span>
            </em>
<em>
              <span style="COLOR: #808080">* Chromosome.</span>
            </em>
<em>
              <span style="COLOR: #808080">*/</span>
            </em>
    <strong>
              <span style="COLOR: #000080">public</span>
            </strong> <strong>
              <span style="COLOR: #000080">double</span>
            </strong> <span style="COLOR: #000000">evaluate(</span> I<span style="COLOR: #000000">Chromosome</span> <span style="COLOR: #000000">a_subject</span> <span style="COLOR: #000000">)</span>
    <span style="COLOR: #000000">{</span>
        <em>
              <span style="COLOR: #808080">// The fitness value measures both how close the value is to the</span>
            </em>
        <em>
              <span style="COLOR: #808080">// target amount supplied by the user and the total number of coins</span>
            </em>
        <em>
              <span style="COLOR: #808080">// represented by the solution. We do this in two steps: first,</span>
            </em>
        <em>
              <span style="COLOR: #808080">// we consider only the represented amount of change vs. the target</span>
            </em>
        <em>
              <span style="COLOR: #808080">// amount of change and calculate higher fitness values for amounts</span>
            </em>
        <em>
              <span style="COLOR: #808080">// closer to the target, and lower fitness values for amounts further</span>
            </em>
        <em>
              <span style="COLOR: #808080">// away from the target. If the amount equals the target, then we go</span>
            </em>
        <em>
              <span style="COLOR: #808080">// to step 2, which adjusts the fitness to a higher value for</span>
            </em>
        <em>
              <span style="COLOR: #808080">// solutions representing fewer total coins, and lower fitness</span>
            </em>
        <em>
              <span style="COLOR: #808080">// values for solutions representing a larger total number of coins.</span>
            </em>
        <em>
              <span style="COLOR: #808080">// ------------------------------------------------------------------</span>
            </em>
        <strong>
              <span style="COLOR: #000080">int</span>
            </strong> <span style="COLOR: #000000">changeAmount</span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000">amountOfChange(</span> <span style="COLOR: #000000">a_subject</span> <span style="COLOR: #000000">);</span>
        <strong>
              <span style="COLOR: #000080">int</span>
            </strong> <span style="COLOR: #000000">totalCoins</span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000">getTotalNumberOfCoins(</span> <span style="COLOR: #000000">a_subject</span> <span style="COLOR: #000000">);</span>
        <strong>
              <span style="COLOR: #000080">int</span>
            </strong> <span style="COLOR: #000000">changeDifference</span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000">Math.abs(</span> <span style="COLOR: #000000">m_targetAmount</span> <span style="COLOR: #000000">-</span> <span style="COLOR: #000000">changeAmount</span> <span style="COLOR: #000000">);</span>

        <em>
              <span style="COLOR: #808080">// Step 1: Determine the distance of the amount represented by the</span>
            </em>
        <em>
              <span style="COLOR: #808080">// solution from the target amount. Since we know the maximum amount</span>
            </em>
        <em>
              <span style="COLOR: #808080">// of change is 99 cents, we'll subtract from that the difference</span>
            </em>
        <em>
              <span style="COLOR: #808080">// between the solution amount and the target amount. That will give</span>
            </em>
        <em>
              <span style="COLOR: #808080">// the desired effect of returning higher values for amounts close</span>
            </em>
        <em>
              <span style="COLOR: #808080">// to the target amount and lower values for amounts further away</span>
            </em>
        <em>
              <span style="COLOR: #808080">// from the target amount.</span>
            </em>
        <em>
              <span style="COLOR: #808080">// ------------------------------------------------------------------</span>
            </em>
        <strong>
              <span style="COLOR: #000080">double</span>
            </strong> <span style="COLOR: #000000">fitness</span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000">(</span> <span style="COLOR: #0000ff">99</span> <span style="COLOR: #000000">-</span> <span style="COLOR: #000000">changeDifference</span> <span style="COLOR: #000000">);</span>

        <em>
              <span style="COLOR: #808080">// Step 2: If the solution amount equals the target amount, then</span>
            </em>
        <em>
              <span style="COLOR: #808080">// we add additional fitness points for solutions representing fewer</span>
            </em>
        <em>
              <span style="COLOR: #808080">// total coins.</span>
            </em>
        <em>
              <span style="COLOR: #808080">// -----------------------------------------------------------------</span>
            </em>
        <strong>
              <span style="COLOR: #000080">if</span>
            </strong>
            <span style="COLOR: #000000">(</span> <span style="COLOR: #000000">changeAmount</span> <span style="COLOR: #000000">==</span> <span style="COLOR: #000000">m_targetAmount</span> <span style="COLOR: #000000">)</span>
        <span style="COLOR: #000000">{</span>
            <span style="COLOR: #000000">fitness</span> <span style="COLOR: #000000">+=</span> <span style="COLOR: #0000ff">100</span> <span style="COLOR: #000000">-</span> <span style="COLOR: #000000">(</span> <span style="COLOR: #0000ff">10</span> <span style="COLOR: #000000">*</span> <span style="COLOR: #000000">totalCoins</span> <span style="COLOR: #000000">);</span>
        <span style="COLOR: #000000">}</span>

        <strong>
              <span style="COLOR: #000080">return</span>
            </strong> <span style="COLOR: #000000">fitness;</span>
    <span style="COLOR: #000000">}</span>

    <em>
              <span style="COLOR: #808080">/**</span>
            </em>
<em>
              <span style="COLOR: #808080">* Calculates the total amount of change (in cents) represented by</span>
            </em>
<em>
              <span style="COLOR: #808080">* the given chromosome and returns that amount.</span>
            </em>
<em>
              <span style="COLOR: #808080">*</span>
            </em>
<em>
              <span style="COLOR: #808080">* @param a_potentialSolution The potential solution to evaluate.</span>
            </em>
<em>
              <span style="COLOR: #808080">* @return The total amount of change (in cents) represented by the</span>
            </em>
<em>
              <span style="COLOR: #808080">* given solution.</span>
            </em>
<em>
              <span style="COLOR: #808080">*/</span>
            </em>
    <strong>
              <span style="COLOR: #000080">public</span>
            </strong> <strong>
              <span style="COLOR: #000080">static</span>
            </strong> <strong>
              <span style="COLOR: #000080">int</span>
            </strong> <span style="COLOR: #000000">amountOfChange(</span> I<span style="COLOR: #000000">Chromosome</span> <span style="COLOR: #000000">a_potentialSolution</span> <span style="COLOR: #000000">)</span>
    <span style="COLOR: #000000">{</span>
        <strong>
              <span style="COLOR: #000080">int</span>
            </strong> <span style="COLOR: #000000">numQuarters</span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000">getNumberOfCoinsAtGene(</span> <span style="COLOR: #000000">a_potentialSolution,</span> <span style="COLOR: #0000ff">0</span> <span style="COLOR: #000000">);</span>
        <strong>
              <span style="COLOR: #000080">int</span>
            </strong> <span style="COLOR: #000000">numDimes</span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000">getNumberOfCoinsAtGene(</span> <span style="COLOR: #000000">a_potentialSolution,</span> <span style="COLOR: #0000ff">1</span> <span style="COLOR: #000000">);</span>
        <strong>
              <span style="COLOR: #000080">int</span>
            </strong> <span style="COLOR: #000000">numNickels</span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000">getNumberOfCoinsAtGene(</span> <span style="COLOR: #000000">a_potentialSolution,</span> <span style="COLOR: #0000ff">2</span> <span style="COLOR: #000000">);</span>
        <strong>
              <span style="COLOR: #000080">int</span>
            </strong> <span style="COLOR: #000000">numPennies</span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000">getNumberOfCoinsAtGene(</span> <span style="COLOR: #000000">a_potentialSolution,</span> <span style="COLOR: #0000ff">3</span> <span style="COLOR: #000000">);</span>

        <strong>
              <span style="COLOR: #000080">return</span>
            </strong> <span style="COLOR: #000000">(</span> <span style="COLOR: #000000">numQuarters</span> <span style="COLOR: #000000">*</span> <span style="COLOR: #0000ff">25</span> <span style="COLOR: #000000">)</span> <span style="COLOR: #000000">+</span> <span style="COLOR: #000000">(</span> <span style="COLOR: #000000">numDimes</span> <span style="COLOR: #000000">*</span> <span style="COLOR: #0000ff">10</span> <span style="COLOR: #000000">)</span> <span style="COLOR: #000000">+</span> <span style="COLOR: #000000">(</span> <span style="COLOR: #000000">numNickels</span> <span style="COLOR: #000000">*</span> <span style="COLOR: #0000ff">5</span> <span style="COLOR: #000000">)</span> <span style="COLOR: #000000">+</span>
               <span style="COLOR: #000000">numPennies;</span>
    <span style="COLOR: #000000">}</span>

    <em>
              <span style="COLOR: #808080">/**</span>
            </em>
<em>
              <span style="COLOR: #808080">* Retrieves the number of coins represented by the given potential</span>
            </em>
<em>
              <span style="COLOR: #808080">* solution at the given gene position.</span>
            </em>
<em>
              <span style="COLOR: #808080">*</span>
            </em>
<em>
              <span style="COLOR: #808080">* @param a_potentialSolution The potential solution to evaluate.</span>
            </em>
<em>
              <span style="COLOR: #808080">* @param a_position The gene position to evaluate.</span>
            </em>
<em>
              <span style="COLOR: #808080">* @return the number of coins represented by the potential solution</span>
            </em>
<em>
              <span style="COLOR: #808080">* at the given gene position.</span>
            </em>
<em>
              <span style="COLOR: #808080">*/</span>
            </em>
    <strong>
              <span style="COLOR: #000080">public</span>
            </strong> <strong>
              <span style="COLOR: #000080">static</span>
            </strong> <strong>
              <span style="COLOR: #000080">int</span>
            </strong> <span style="COLOR: #000000">getNumberOfCoinsAtGene(</span> I<span style="COLOR: #000000">Chromosome</span> <span style="COLOR: #000000">a_potentialSolution,</span>
                                              <strong>
              <span style="COLOR: #000080">int</span>
            </strong> <span style="COLOR: #000000">a_position</span> <span style="COLOR: #000000">)</span>
    <span style="COLOR: #000000">{</span>
        <span style="COLOR: #000000">Integer</span> <span style="COLOR: #000000">numCoins</span> <span style="COLOR: #000000">=</span>
          <span style="COLOR: #000000">(Integer)</span> <span style="COLOR: #000000">a_potentialSolution.getGene(a_position).getAllele();</span>

        <strong>
              <span style="COLOR: #000080">return</span>
            </strong> <span style="COLOR: #000000">numCoins.intValue();</span>
    <span style="COLOR: #000000">}</span>

    <em>
              <span style="COLOR: #808080">/**</span>
            </em>
<em>
              <span style="COLOR: #808080">* Returns the total number of coins represented by all of the genes in</span>
            </em>
<em>
              <span style="COLOR: #808080">* the given chromosome.</span>
            </em>
<em>
              <span style="COLOR: #808080">*</span>
            </em>
<em>
              <span style="COLOR: #808080">* @param a_potentialsolution The potential solution to evaluate.</span>
            </em>
<em>
              <span style="COLOR: #808080">* @return The total number of coins represented by the given Chromosome.</span>
            </em>
<em>
              <span style="COLOR: #808080">*/</span>
            </em>
    <strong>
              <span style="COLOR: #000080">public</span>
            </strong> <strong>
              <span style="COLOR: #000080">static</span>
            </strong> <strong>
              <span style="COLOR: #000080">int</span>
            </strong> <span style="COLOR: #000000">getTotalNumberOfCoins(</span> I<span style="COLOR: #000000">Chromosome</span> <span style="COLOR: #000000">a_potentialsolution</span> <span style="COLOR: #000000">)</span>
    <span style="COLOR: #000000">{</span>
        <strong>
              <span style="COLOR: #000080">int</span>
            </strong> <span style="COLOR: #000000">totalCoins</span> <span style="COLOR: #000000">=</span> <span style="COLOR: #0000ff">0</span>
            <span style="COLOR: #000000">;</span>

        <strong>
              <span style="COLOR: #000080">int</span>
            </strong> <span style="COLOR: #000000">numberOfGenes</span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000">a_potentialsolution.size();</span>
        <strong>
              <span style="COLOR: #000080">for</span>
            </strong>
            <span style="COLOR: #000000">(</span> <strong>
              <span style="COLOR: #000080">int</span>
            </strong> <span style="COLOR: #000000">i</span> <span style="COLOR: #000000">=</span> <span style="COLOR: #0000ff">0</span>
            <span style="COLOR: #000000">;</span> <span style="COLOR: #000000">i</span> <span style="COLOR: #000000">&lt;</span> <span style="COLOR: #000000">numberOfGenes;</span> <span style="COLOR: #000000">i++</span> <span style="COLOR: #000000">)</span>
        <span style="COLOR: #000000">{</span>
            <span style="COLOR: #000000">totalCoins</span> <span style="COLOR: #000000">+=</span> <span style="COLOR: #000000">getNumberOfCoinsAtGene(</span> <span style="COLOR: #000000">a_potentialsolution,</span> <span style="COLOR: #000000">i</span> <span style="COLOR: #000000">);</span>
        <span style="COLOR: #000000">}</span>

        <strong>
              <span style="COLOR: #000080">return</span>
            </strong> <span style="COLOR: #000000">totalCoins;</span>
    <span style="COLOR: #000000">}</span>
<span style="COLOR: #000000">}</span>
          </tt>
</pre>
<p class="text">Let&#8217;s tackle our example fitness function bit by bit. To start, we define our own class and extend the org.jgap.FitnessFunction class. All fitness functions must extend the FitnessFunction class. We then define a constructor and an evaluate() method. The evaluate() method is a standard method that all fitness functions must implement. That is the method that will be called by the genetic engine when it needs to know the fitness value of a chromosome.</p>
<p class="text">Our constructor isn&#8217;t very exciting: it merely accepts a target change amount that the user desires, verifies that the amount meets our constraint of being between 1 and 99 cents, and then stores the amount in an instance variable for later use.</p>
<p class="text">The interesting part of the whole class is the evaluate() method, which is where the work is done. The evaluate method is always passed in a Chromosome, which represents a potential solution. A Chromosome is made up of genes, each of which represents a respective part of the solution. In our example, the Chromosome represents an amount of change, while the genes represent the specific kinds of coins: quarters for the first gene, dimes for the second gene, nickels for the third gene, and pennies for the fourth gene. The value of a gene is called an allele. In our example, the allele would be the number of a given type of coin (for example, 2 pennies).</p>
<p class="text">The first thing the evaluate() method does is invoke a couple of helper methods which conveniently return the total amount of change that is represented by the potential solution and the total number of coins represented by the solution. We&#8217;ll take a closer look at how these work later. It then subtracts the amount of change represented by the solution from the target amount, and takes the absolute value of the difference to measure how close the solution amount is to the target amount. We then set about calculating our fitness value.</p>
<p class="text">As the comments indicate, we&#8217;re going to calculate fitness in two stages. The first stage calculates an initial fitness value based on how far away the solution amount is from the target amount. Then, if the solution amount happens to equal the target amount, we go to stage two, which adjusts the fitness value based upon the total number of coins represented by the solution. In the end, we want to return high fitness values for solutions that match the target amount with very few coins, and return lower fitness values for solutions that are far away from the target amount or represent a large number of coins.</p>
<p class="text">Moving beyond the evaluate() method, we encounter those helper methods we mentioned earlier. The amountOfChange() method calculates the total amount of change (in cents) represented by a Chromosome that is passed to it. Internally, it defers to the getNumberOfCoinsAtGene() method to actually extract the number of each type of coin. It then calculates the total amount of change and returns it.</p>
<p class="text">The next convenience method, getNumberOfCoinsAtGene(), is responsible for determining the number of coins represented by a specific gene in the given Chromosome. As mentioned earlier, the value of each gene in the Chromosome is called an allele. This method gets the allele for the gene at the provided position in the Chromosome and then returns it as an int primitive.</p>
<p class="text">Finally, there&#8217;s a getTotalNumberOfCoins() method that determines the total number of coins represented by a given Chromosome. It simply tallies up the number of coins represented by each gene&#8211;using the getNumberOfCoinsAtGene() method&#8211;and then returns the tally.</p>
<p class="text">And that&#8217;s the end of the fitness function. If you&#8217;re feeling a little bit overwhelmed, don&#8217;t worry about it and take some comfort in the fact that it&#8217;s all down hill from here! The fitness function is the hardest part of using JGAP and, after writing a few, you&#8217;ll get the hang of it.</p>
<h3 class="subheader"><a id="step3" name="step3">Step 3: Setup a Configuration Object</a></h3>
<p class="text"><a id="step3" name="step3">JGAP is designed to be very flexible and pluggable. If you want, you can create your own genetic operators, random number generators, natural selectors, and so on. To support all of this, JGAP uses a Configuration object that must be setup with all of the settings you want prior to using the genetic engine. Fortunately, we realize that most people will want to use the stock components, and so we include a DefaultConfiguration class that comes already setup with the most common settings. You just need to provide three extra pieces of information: what fitness function you want to use, how you want your Chromosomes to be setup, and how many Chromosomes you want in your population. Let&#8217;s look at some sample code that you might want to include in the same class as the above snippets.</a></p>
<pre class="Listing">
<tt>
            <a id="step2" name="step2">
              <strong>
                <span style="COLOR: #000080">public</span>
              </strong> <strong>
                <span style="COLOR: #000080">static</span>
              </strong> </a>
          </tt>
          <tt>
            <a id="step2" name="step2">void main<span style="COLOR: #000000">(</span>String[] args<span style="COLOR: #000000">) throws Exception {</span>
</a>  </tt>
          <a id="step3" name="step3">
            <tt>
              <em>
                <span style="COLOR: #808080">// Start with a DefaultConfiguration, which comes setup with the</span>
              </em>
  <span style="COLOR: #808080">
                <em>// most common settings.</em>
              </span>
  <span style="COLOR: #808080">
                <em>// -------------------------------------------------------------</em>
              </span>
  <span style="COLOR: #000000">Configuration</span> <span style="COLOR: #000000">conf</span> <span style="COLOR: #000000">=</span> <strong>
                <span style="COLOR: #000080">new</span>
              </strong> <span style="COLOR: #000000">DefaultConfiguration();</span>

  <span style="COLOR: #808080">
                <em>// Set the fitness function we want to use, which is our</em>
              </span>
  <span style="COLOR: #808080">
                <em>// MinimizingMakeChangeFitnessFunction that we created earlier.</em>
              </span>
  <span style="COLOR: #808080">
                <em>// We construct it with the target amount of change provided</em>
              </span>
  <span style="COLOR: #808080">
                <em>// by the user.</em>
              </span>
  <span style="COLOR: #808080">
                <em>// ------------------------------------------------------------</em>
              </span>
  int targetAmount = Integer.parseInt(args[0])<span style="COLOR: #000000">; FitnessFunction</span> <span style="COLOR: #000000">myFunc</span> <span style="COLOR: #000000">=</span>
    <strong>
                <span style="COLOR: #000080">new</span>
              </strong> <span style="COLOR: #000000">MinimizingMakeChangeFitnessFunction(</span> <span style="COLOR: #000000">targetAmount</span> <span style="COLOR: #000000">);</span>

  <span style="COLOR: #000000">conf.setFitnessFunction(</span> <span style="COLOR: #000000">myFunc</span> <span style="COLOR: #000000">);</span>

  <span style="COLOR: #808080">
                <em>// Now we need to tell the Configuration object how we want our</em>
              </span>
  <span style="COLOR: #808080">
                <em>// Chromosomes to be setup. We do that by actually creating a</em>
              </span>
  <span style="COLOR: #808080">
                <em>// sample Chromosome and then setting it on the Configuration</em>
              </span>
  <span style="COLOR: #808080">
                <em>// object. As mentioned earlier, we want our Chromosomes to</em>
              </span>
  <span style="COLOR: #808080">
                <em>// each have four genes, one for each of the coin types. We</em>
              </span>
  <span style="COLOR: #808080">
                <em>// want the values of those genes to be integers, which represent</em>
              </span>
  <span style="COLOR: #808080">
                <em>// how many coins of that type we have. We therefore use the</em>
              </span>
  <span style="COLOR: #808080">
                <em>// IntegerGene class to represent each of the genes. That class</em>
              </span>
  <span style="COLOR: #808080">
                <em>// also lets us specify a lower and upper bound, which we set</em>
              </span>
  <span style="COLOR: #808080">
                <em>// to sensible values for each coin type.</em>
              </span>
  <span style="COLOR: #808080">
                <em>// --------------------------------------------------------------</em>
              </span>
  <span style="COLOR: #000000">Gene[]</span> <span style="COLOR: #000000">sampleGenes</span> <span style="COLOR: #000000">=</span> <strong>
                <span style="COLOR: #000080">new</span>
              </strong> <span style="COLOR: #000000">Gene[</span> <span style="COLOR: #0000ff">4</span> <span style="COLOR: #000000">];</span>

  <span style="COLOR: #000000">sampleGenes[</span>
              <span style="COLOR: #0000ff">0</span>
              <span style="COLOR: #000000">]</span> <span style="COLOR: #000000">=</span> <strong>
                <span style="COLOR: #000080">new</span>
              </strong> <span style="COLOR: #000000">IntegerGene(conf,</span> <span style="COLOR: #0000ff">0</span>
              <span style="COLOR: #000000">,</span> <span style="COLOR: #0000ff">3</span> <span style="COLOR: #000000">);</span>  <em>
                <span style="COLOR: #808080">// Quarters</span>
              </em>
  <span style="COLOR: #000000">sampleGenes[</span>
              <span style="COLOR: #0000ff">1</span>
              <span style="COLOR: #000000">]</span> <span style="COLOR: #000000">=</span> <strong>
                <span style="COLOR: #000080">new</span>
              </strong> <span style="COLOR: #000000">IntegerGene(conf,</span> <span style="COLOR: #0000ff">0</span>
              <span style="COLOR: #000000">,</span> <span style="COLOR: #0000ff">2</span> <span style="COLOR: #000000">);</span>  <em>
                <span style="COLOR: #808080">// Dimes</span>
              </em>
  <span style="COLOR: #000000">sampleGenes[</span>
              <span style="COLOR: #0000ff">2</span>
              <span style="COLOR: #000000">]</span> <span style="COLOR: #000000">=</span> <strong>
                <span style="COLOR: #000080">new</span>
              </strong> <span style="COLOR: #000000">IntegerGene(conf,</span> <span style="COLOR: #0000ff">0</span>
              <span style="COLOR: #000000">,</span> <span style="COLOR: #0000ff">1</span> <span style="COLOR: #000000">);</span>  <em>
                <span style="COLOR: #808080">// Nickels</span>
              </em>
  <span style="COLOR: #000000">sampleGenes[</span>
              <span style="COLOR: #0000ff">3</span>
              <span style="COLOR: #000000">]</span> <span style="COLOR: #000000">=</span> <strong>
                <span style="COLOR: #000080">new</span>
              </strong> <span style="COLOR: #000000">IntegerGene(conf,</span> <span style="COLOR: #0000ff">0</span>
              <span style="COLOR: #000000">,</span> <span style="COLOR: #0000ff">4</span> <span style="COLOR: #000000">);</span>  <em>
                <span style="COLOR: #808080">// Pennies</span>
              </em>

  <span style="COLOR: #000000">Chromosome</span> <span style="COLOR: #000000">sampleChromosome</span> <span style="COLOR: #000000">=</span> <strong>
                <span style="COLOR: #000080">new</span>
              </strong> <span style="COLOR: #000000">Chromosome(conf,</span> <span style="COLOR: #000000">sampleGenes</span> <span style="COLOR: #000000">);</span>

  <span style="COLOR: #000000">conf.setSampleChromosome(</span> <span style="COLOR: #000000">sampleChromosome</span> <span style="COLOR: #000000">);</span>

  <span style="COLOR: #808080">
                <em>// Finally, we need to tell the Configuration object how many</em>
              </span>
  <span style="COLOR: #808080">
                <em>// Chromosomes we want in our population. The more Chromosomes,</em>
              </span>
  <span style="COLOR: #808080">
                <em>// the larger the number of potential solutions (which is good</em>
              </span>
  <span style="COLOR: #808080">
                <em>// for finding the answer), but the longer it will take to evolve</em>
              </span>
  <span style="COLOR: #808080">
                <em>// the population each round. We'll set the population size to</em>
              </span>
  <span style="COLOR: #808080">
                <em>// 500 here.</em>
              </span>
  <span style="COLOR: #808080">
                <em>// --------------------------------------------------------------</em>
              </span>
  <span style="COLOR: #000000">conf.setPopulationSize(</span> <span style="COLOR: #0000ff">500</span> <span style="COLOR: #000000">); // TODO: Add the code following below in this example here}</span>
            </tt>
          </a>
</pre>
<p class="text"><a id="step3" name="step3">Hopefully most of the above code is pretty self-explanatory, with maybe the exception of setting up the sample Chromosome. Let&#8217;s look at that bit in a little more detail.</a></p>
<p class="text"><a id="step3" name="step3">As mentioned earlier, a Chromosome is made up of genes. JGAP lets you choose what Gene class to use to represent each gene in the Chromosome (for more information on creating custom Gene classes, please see the</a> <a href="http://jgap.sourceforge.net/doc/genes.html">Creating Custom Genes</a> document). That provides the most flexibility and convenience. If we wanted to, we could have actually written a separate Gene class for each coin type in our example, such as a QuarterGene, DimeGene, NickelGene, and PennyGene. In fact, we look at what a QuarterGene might look like in the <em>Creating Custom Genes</em> document that we just mentioned.</p>
<p class="text">As it happens, we decided that the IntegerGene (which comes with JGAP) would suffice. You&#8217;ll notice, however, that we did take advantage of the ability to specify different Gene implementations for each gene in the Chromosome by creating separate IntegerGenes with different lower and upper bounds for each coin type. We set the upper bounds to be the largest number of coins of that respective type that would appear in an optimal solution. Limiting the solution space this way helps JGAP arrive at better solutions with fewer evolutions.</p>
<p class="text">So to get back to the code, we first create an array of Genes with a length of 4, since we want to represent 4 genes (one for each coin type). We then set each Gene in the array to an IntegerGene that is constructed with appropriate lower and upper bounds for that coin type. Finally, we construct a new Chromosome and pass it the array of Genes, and then set that sample Chromosome on the Configuration object.</p>
<p class="text">The final part of this step is setting the population size, which is the number of Chromosomes we want in the population. A larger population size means more potential solutions to choose from and more genetic diversity, but it also means more work to evolve that population. Ultimately, you&#8217;ll need to settle on a value that balances your need for a nice selection of potential solutions against how much time you&#8217;re willing to spend waiting for your population to evolve. The population size is chosen higher than the number of possible solutions here (as 3*2*1*4 = 24). But as Genetic Algorithms is a stochastic system, the more tries the GA is allowed to make, the higher the chances finding a good solution. Besides, the population size should not be correlated too specifically to a narrowed search space, but be usable in a more generic way. Meaning: if the 24 possible combinations mentioned above was raised, then the population wouldn&#8217;t need to be adapted. And if the 24 is kept, the population size of 500 will not have a negative impact, because fewer evolutions are needed finding a good solutions than with smaller population size.</p>
<h3 class="subheader"><a id="step4" name="step4">Step 4: Create a Population</a></h3>
<p class="text"><a id="step4" name="step4">Recall that each potential solution is represented by a Chromosome. A population of Chromosomes is called a Genotype, and that is the class we need to construct to create our population. If you want, you can construct each Chromosome individually and then pass them all into a new Genotype (much like we constructed each Gene and passed them into the sample Chromosome in step 3), but JGAP provides a much quicker and easier way of creating a random population. In fact, it only takes one line of code</a> <a id="step5" name="step5">(append all following code lines to the above code in method main)</a>:</p>
<pre class="Listing">
<tt>
            <span style="COLOR: #000000">Genotype</span> <span style="COLOR: #000000">population</span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000">Genotype.randomInitialGenotype(</span> <span style="COLOR: #000000">conf</span> <span style="COLOR: #000000">);</span>
          </tt>
</pre>
<p>The randomInitialGenotype() method takes in a Configuration object (which we setup in step 3) and returns a Genotype with the correct number of Chromosomes, each of which has its genes set to random values. In other words, it generates a random population. For most applications, this is all that&#8217;s necessary to create your initial population of potential solutions.</p>
<h3 class="subheader"><a id="step5" name="step5">Step 5: Evolve the Population!</a></h3>
<p class="text">Now that we&#8217;ve gotten everything setup and ready to go, it&#8217;s time to start evolving the population until it contains some potential solutions that we&#8217;re satisfied with. Evolving the population one cycle is another one-liner:</p>
<pre class="Listing">
<tt>
            <span style="COLOR: #000000">population.evolve();</span>
          </tt>
</pre>
<p class="text">Typically, after each evolution cycle, you&#8217;ll want to check if the population contains any satisfactory solutions. The easiest way to do this is to invoke the getFittestChromosome() method on the population:</p>
<pre class="Listing">
<tt>
            <span style="COLOR: #000000">IChromosome</span> <span style="COLOR: #000000">bestSolutionSoFar</span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000">population.getFittestChromosome();</span>
          </tt>
</pre>
<p class="text">If the best solution so far is good enough for you, then you&#8217;re done. If not, then you can evolve the population again. Alternatively, you may just choose to evolve the population a set number of times and then see what the best solution is that was produced at the end (or a combination thereof). For our example problem, we&#8217;ll take this latter approach.</p>
<pre class="Listing">
<tt>
            <span style="COLOR: #000000">IChromosome</span> <span style="COLOR: #000000">bestSolutionSoFar;</span>

<strong>
              <span style="COLOR: #000080">for</span>
            </strong>
            <span style="COLOR: #000000">(</span> <strong>
              <span style="COLOR: #000080">int</span>
            </strong> <span style="COLOR: #000000">i</span> <span style="COLOR: #000000">=</span> <span style="COLOR: #0000ff">0</span>
            <span style="COLOR: #000000">;</span> <span style="COLOR: #000000">i</span> <span style="COLOR: #000000">&lt;</span> <span style="COLOR: #000000">MAX_ALLOWED_EVOLUTIONS;</span> <span style="COLOR: #000000">i++</span> <span style="COLOR: #000000">)</span>
<span style="COLOR: #000000">{</span>
    <span style="COLOR: #000000">population.evolve();</span>
<span style="COLOR: #000000">}</span>

<span style="COLOR: #000000">System.out.println(</span> <strong>
              <span style="COLOR: #009900">"The best solution contained the following: "</span>
            </strong> <span style="COLOR: #000000">);</span>

<span style="COLOR: #000000">System.out.println(</span>
    <span style="COLOR: #000000">MinimizingMakeChangeFitnessFunction.getNumberOfCoinsAtGene(</span>
        <span style="COLOR: #000000">bestSolutionSoFar,</span> <span style="COLOR: #0000ff">0</span> <span style="COLOR: #000000">)</span> <span style="COLOR: #000000">+</span> <strong>
              <span style="COLOR: #009900">" quarters."</span>
            </strong> <span style="COLOR: #000000">);</span>

<span style="COLOR: #000000">System.out.println(</span>
    <span style="COLOR: #000000">MinimizingMakeChangeFitnessFunction.getNumberOfCoinsAtGene(</span>
        <span style="COLOR: #000000">bestSolutionSoFar,</span> <span style="COLOR: #0000ff">1</span> <span style="COLOR: #000000">)</span> <span style="COLOR: #000000">+</span> <strong>
              <span style="COLOR: #009900">" dimes."</span>
            </strong> <span style="COLOR: #000000">);</span>

<span style="COLOR: #000000">System.out.println(</span>
    <span style="COLOR: #000000">MinimizingMakeChangeFitnessFunction.getNumberOfCoinsAtGene(</span>
        <span style="COLOR: #000000">bestSolutionSoFar,</span> <span style="COLOR: #0000ff">2</span> <span style="COLOR: #000000">)</span> <span style="COLOR: #000000">+</span> <strong>
              <span style="COLOR: #009900">" nickels."</span>
            </strong> <span style="COLOR: #000000">);</span>

<span style="COLOR: #000000">System.out.println(</span>
    <span style="COLOR: #000000">MinimizingMakeChangeFitnessFunction.getNumberOfCoinsAtGene(</span>
        <span style="COLOR: #000000">bestSolutionSoFar,</span> <span style="COLOR: #0000ff">3</span> <span style="COLOR: #000000">)</span> <span style="COLOR: #000000">+</span> <strong>
              <span style="COLOR: #009900">" pennies."</span>
            </strong> <span style="COLOR: #000000">);</span>

<span style="COLOR: #000000">System.out.println(</span> <strong>
              <span style="COLOR: #009900">"For a total of "</span>
            </strong> <span style="COLOR: #000000">+</span>
    <span style="COLOR: #000000">MinimizingMakeChangeFitnessFunction.amountOfChange(</span>
        <span style="COLOR: #000000">bestSolutionSoFar</span> <span style="COLOR: #000000">)</span> <span style="COLOR: #000000">+</span> <strong>
              <span style="COLOR: #009900">" cents in "</span>
            </strong> <span style="COLOR: #000000">+</span>
    <span style="COLOR: #000000">MinimizingMakeChangeFitnessFunction.getTotalNumberOfCoins(</span>
        <span style="COLOR: #000000">bestSolutionSoFar</span> <span style="COLOR: #000000">)</span> <span style="COLOR: #000000">+</span> <strong>
              <span style="COLOR: #009900">" coins."</span>
            </strong> <span style="COLOR: #000000">);</span>
          </tt>
</pre>
<p class="text">Now we&#8217;ve got ourselves a full-fledged genetic application! To view all of the code for this example, see the MinimizingMakeChange.java and MinimizingMakeChangeFitnessFunction.java files in the examples/src directory of the JGAP distribution.</p>
<h3 class="subheader"><a id="step1" name="step1">Further resources</a></h3>
<ul>
<li>
<p class="subheader">See the examples under package <em>examples</em>. They are located in subdirectory <em>examples/src</em> of the JGAP source distribution.</p>
</li>
<li>
<p class="subheader">See the external <a href="http://jcraane.blogspot.com/2009/02/introduction-to-genetic-algorithms-with.html" target="_blank">blog entry from Jamie Craane</a> or <a href="http://jgap.sourceforge.net/doc/references/Introduction to Genetic Algorithms with JGAP.pdf" target="_blank">download a local copy of the article as PDF</a>.</p>
</li>
</ul>
<h3>Random Posts</h3>
<ul class="related_post">
<li><a href="http://www.zhangdaqian.net/blog/will-work-for-food.htm" title="Will work for food">Will work for food</a></li>
<li><a href="http://www.zhangdaqian.net/blog/%e5%a4%a7%e4%b8%8d%e6%8a%98%e8%85%be%e5%8f%8a%e6%b8%af%e6%be%b3%e5%8f%b0%e8%81%94%e5%90%88%e7%8e%8b%e5%9b%bd.htm" title="大不折腾及港澳台联合王国">大不折腾及港澳台联合王国</a></li>
<li><a href="http://www.zhangdaqian.net/blog/%e7%94%9f%e6%b4%bb%e4%b8%ad%e5%b8%b8%e8%a7%81%e7%9a%84%e9%80%bb%e8%be%91%e8%b0%ac%e8%af%af-zz.htm" title="生活中常见的逻辑谬误-zz">生活中常见的逻辑谬误-zz</a></li>
<li><a href="http://www.zhangdaqian.net/blog/%e6%b5%b7%e5%a4%96%e8%91%97%e5%90%8d-web-%e8%ae%be%e8%ae%a1%e5%b8%88%e4%bb%ac%e7%9a%84%e5%b7%a5%e4%bd%9c%e5%8f%b0.htm" title="海外著名 Web 设计师们的工作台">海外著名 Web 设计师们的工作台</a></li>
<li><a href="http://www.zhangdaqian.net/blog/fedsky%e9%aa%8c%e8%af%81.htm" title="fedsky验证">fedsky验证</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.zhangdaqian.net/blog/getting-started-with-jgap.htm/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows XP的无线桥接</title>
		<link>http://www.zhangdaqian.net/blog/windows-xp%e7%9a%84%e6%97%a0%e7%ba%bf%e6%a1%a5%e6%8e%a5.htm</link>
		<comments>http://www.zhangdaqian.net/blog/windows-xp%e7%9a%84%e6%97%a0%e7%ba%bf%e6%a1%a5%e6%8e%a5.htm#comments</comments>
		<pubDate>Mon, 30 Mar 2009 09:40:21 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[widows]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[网络]]></category>

		<guid isPermaLink="false">http://www.zhangdaqian.net/blog/windows-xp%e7%9a%84%e6%97%a0%e7%ba%bf%e6%a1%a5%e6%8e%a5.htm</guid>
		<description><![CDATA[目前大部分的笔记本都是有两块网卡，一块是普通网卡，一块是无线网卡。一般有网口的地方会用普通网卡，通过网线连接上网，以获得较好的性能，没有网口的地方，会用无线上网。通常情况下，即使在同一个局域网里面，如果手工配置IP地址，必须为这两个不同的链接配置不同的IP地址，因为windows不允许为两个不同的适配器配置相同的IP地址。在特殊情况下，例如，使用电驴并在路由器上做了端口映射，于是需要在两种情况下都使用相同的IP地址，又不想每次都重新手工配置，这个时候可以用Windows自带的桥接模式来解决这个问题。

在网络连接的文件夹中，选中&#8221;本地连接&#8221;和&#8221;无线网络连接&#8221;，击右键，选择&#8221;桥接&#8221;。这个时候将创建一个新的连接，叫&#8221;网络桥&#8221;（MAC Birdge Miniport)。这时候就可以手工为&#8221;网路桥&#8221;配置IP地址了。这样配置后，发现当接上网线时，上网是没有任何问题的，但是一旦拔开网线，改用无线上网，就上不去了，但是无线网卡显示的是连接上的状态。百思不得其解。Google了一下，发现了这两个连接：
Windows XP Home Networking: Building Network Bridges
Bridge May Not Work With a Non-Promiscuous Mode Network Adapter
其中，提到了一个东西：&#8221;Promiscuous Mode&#8221;。原来，网卡工作在普通状态时，只接收属于自己的MAC地址的以太网包。只有当工作在&#8221;Promiscuous Mode&#8221;时，才不加限制地接收所有的以太网包。大部分的普通网卡都可以工作在&#8221;Promiscuous Mode&#8221;，可能为了安全起见，大部分的无线网卡都不能工作在&#8221;Promiscuous Mode&#8221;下。当Windows创建桥接模式时，实际上在系统里面创建了一个虚拟的新的网卡，这个新的网卡有自己的MAC地址，桥里面的所有网卡都以这个新的MAC地址发送以太网包，回送的以太网包自然也是发给这个新的MAC地址，由于普通网卡支持&#8221;Promiscuous Mode&#8221;，所以可以接收到不属于自己的新的MAC地址以太网包，所以通讯正常，无线网卡会抛弃掉所有不属于自己MAC地址的包，所以在桥接模式下收不到任何发回来的以太网包，自然就不能正常工作了。Windows XP提供了一个解决办法，叫ForceCompatibilityMode（强制兼容模式），在命令行（cmd）下，打入netsh bridge show a，可以看到已经桥接的各个网卡的编号和是否启用强制兼容模式，如果无线网卡显示&#8221;已停用&#8221;或者&#8221;未知&#8221;，应记住无线网卡的编号，并在命令行下打入：netsh bridge set a X e，其中X是无线网卡的编号，以启用强制兼容模式。
这个兼容模式的原理是这样的，一旦某个网卡启用了这个模式，当从这个网口向外发送以太网包时，将改写以太网包，把源地址换成网卡自己的MAC地址，并记住这个转换，回复的以太网包的目标地址也是网卡的MAC地址，这样网卡就不会丢弃这个包，当这个收到这个回复包后，再根据原来的记忆，把目标地址换回原来的地址，和IP层的NAT的原理类似。
通过这样设置以后，当拔掉网线，启用无线网络连接后，依然可以上网，并且IP地址不变，整个过程自动完成。
你还想看

通过emule做DDOS是否可行？

]]></description>
			<content:encoded><![CDATA[<p>目前大部分的笔记本都是有两块网卡，一块是普通网卡，一块是无线网卡。一般有网口的地方会用普通网卡，通过网线连接上网，以获得较好的性能，没有网口的地方，会用无线上网。通常情况下，即使在同一个局域网里面，如果手工配置IP地址，必须为这两个不同的链接配置不同的IP地址，因为windows不允许为两个不同的适配器配置相同的IP地址。在特殊情况下，例如，使用电驴并在路由器上做了端口映射，于是需要在两种情况下都使用相同的IP地址，又不想每次都重新手工配置，这个时候可以用Windows自带的桥接模式来解决这个问题。<br />
<span id="more-196"></span><br />
在网络连接的文件夹中，选中&#8221;本地连接&#8221;和&#8221;无线网络连接&#8221;，击右键，选择&#8221;桥接&#8221;。这个时候将创建一个新的连接，叫&#8221;网络桥&#8221;（MAC Birdge Miniport)。这时候就可以手工为&#8221;网路桥&#8221;配置IP地址了。这样配置后，发现当接上网线时，上网是没有任何问题的，但是一旦拔开网线，改用无线上网，就上不去了，但是无线网卡显示的是连接上的状态。百思不得其解。Google了一下，发现了这两个连接：</p>
<p><a href="http://www.microsoft.com/windowsxp/using/networking/expert/crawford_02april22.mspx"><span style="COLOR: #336699">Windows XP Home Networking: Building Network Bridges</span></a><br />
<a href="http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q302348&amp;ID=KB;EN-US;Q302348&amp;"><span style="COLOR: #336699">Bridge May Not Work With a Non-Promiscuous Mode Network Adapter</span></a></p>
<p>其中，提到了一个东西：&#8221;Promiscuous Mode&#8221;。原来，网卡工作在普通状态时，只接收属于自己的MAC地址的以太网包。只有当工作在&#8221;Promiscuous Mode&#8221;时，才不加限制地接收所有的以太网包。大部分的普通网卡都可以工作在&#8221;Promiscuous Mode&#8221;，可能为了安全起见，大部分的无线网卡都不能工作在&#8221;Promiscuous Mode&#8221;下。当Windows创建桥接模式时，实际上在系统里面创建了一个虚拟的新的网卡，这个新的网卡有自己的MAC地址，桥里面的所有网卡都以这个新的MAC地址发送以太网包，回送的以太网包自然也是发给这个新的MAC地址，由于普通网卡支持&#8221;Promiscuous Mode&#8221;，所以可以接收到不属于自己的新的MAC地址以太网包，所以通讯正常，无线网卡会抛弃掉所有不属于自己MAC地址的包，所以在桥接模式下收不到任何发回来的以太网包，自然就不能正常工作了。Windows XP提供了一个解决办法，叫ForceCompatibilityMode（强制兼容模式），在命令行（cmd）下，打入netsh bridge show a，可以看到已经桥接的各个网卡的编号和是否启用强制兼容模式，如果无线网卡显示&#8221;已停用&#8221;或者&#8221;未知&#8221;，应记住无线网卡的编号，并在命令行下打入：netsh bridge set a X e，其中X是无线网卡的编号，以启用强制兼容模式。</p>
<p>这个兼容模式的原理是这样的，一旦某个网卡启用了这个模式，当从这个网口向外发送以太网包时，将改写以太网包，把源地址换成网卡自己的MAC地址，并记住这个转换，回复的以太网包的目标地址也是网卡的MAC地址，这样网卡就不会丢弃这个包，当这个收到这个回复包后，再根据原来的记忆，把目标地址换回原来的地址，和IP层的NAT的原理类似。</p>
<p>通过这样设置以后，当拔掉网线，启用无线网络连接后，依然可以上网，并且IP地址不变，整个过程自动完成。<br />
<h3>你还想看</h3>
<ul class="related_post">
<li><a href="http://www.zhangdaqian.net/blog/%e9%80%9a%e8%bf%87emule%e5%81%9addos%e6%98%af%e5%90%a6%e5%8f%af%e8%a1%8c%ef%bc%9f.htm" title="通过emule做DDOS是否可行？">通过emule做DDOS是否可行？</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.zhangdaqian.net/blog/windows-xp%e7%9a%84%e6%97%a0%e7%ba%bf%e6%a1%a5%e6%8e%a5.htm/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
