<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">
Hi Richard,<div><br class="webkit-block-placeholder"></div><div>I tried your code and it works fine for me.  The script always exits right away after scanning all ports.  I tried various hosts and various port ranges.</div><div><br class="webkit-block-placeholder"></div><div>I'm running Python 2.4.4, Twisted 2.5.0, on OS X.</div><div><br class="webkit-block-placeholder"></div><div>btw: I would warn against port scanning public sites such as google; you don't want to trip an IDS and cop the wrath of a network admin.</div><div><br class="webkit-block-placeholder"></div><div>Hope this helps.</div><div><br class="webkit-block-placeholder"></div><div>Cya at PyConUK.</div><div><br class="webkit-block-placeholder"></div><div>Cheers,</div><div>Chris</div><div><br><div><div>On 25 Aug 2007, at 12:53, Richard Wall wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">I'm giving a talk "An introduction to Twisted" at PyconUK and am trying to come up with some simple examples.</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">One of these, is the attached PortCheck module, that is supposed to attempt connection to a range of ports and report whether they're open, closed, filtered (timeout).</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">It works okay when run against localhost, or another machine on my local network, but I've noticed that when I run it against an internet host, the reactor takes ages to shutdown after scanning all the ports. I wondered if there was anything obviously wrong with the code.</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Run it as follows from bash: python portcheck.py <a href="http://www.google.co.uk">www.google.co.uk</a> {1..1000}</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Thanks in advance for any suggestions.</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">-RichardW.</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka">"""</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka">A module to demonstrate some of the simplest twisted client code possible</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka">@author: Richard Wall &lt;richard (at) the-moon.net&gt;</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka">"""</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka">import sys</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Osaka; min-height: 16px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka">from twisted.internet import reactor</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka">from twisted.internet.defer import DeferredList</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka">from twisted.internet.task import Cooperator</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka">from twisted.internet.protocol import ClientCreator, Protocol</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka">from twisted.internet.error import ConnectionRefusedError, TimeoutError</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Osaka; min-height: 16px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka">STATUS_OPEN = "open"</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka">STATUS_CLOSED = "closed"</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka">STATUS_TIMEOUT = "timeout"</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Osaka; min-height: 16px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka">MAX_SIMULTANEOUS_CONNECTIONS = 100</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Osaka; min-height: 16px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka">def getPortStatus(host, port, timeout=1):</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>"""</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>Return a deferred that is called back with one of: open, closed, timeout</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>@param host: The hostname or IP with which to attempt a connection</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>@param port: The port to connect</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>@param timeout: Number of seconds to wait for connection before giving up</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>@return: A deferred which will call back with one of<span class="Apple-converted-space"> </span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">             </span>STATUS_{OPEN,CLOSED,TIMEOUT}</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>"""</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Osaka; min-height: 16px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>cli = ClientCreator(reactor, Protocol)</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Osaka; min-height: 16px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>d = cli.connectTCP(host, port, timeout=timeout)</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Osaka; min-height: 16px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>def cb(proto):</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">        </span>proto.transport.loseConnection()</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">        </span>return STATUS_OPEN</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Osaka; min-height: 16px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>def eb(err):</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">        </span>expectedErrors = {</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">            </span>ConnectionRefusedError: STATUS_CLOSED,</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">            </span>TimeoutError: STATUS_TIMEOUT</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">        </span>}</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Osaka; min-height: 16px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">        </span>e = err.trap(*expectedErrors.keys())</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">        </span>if e:</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">            </span>return expectedErrors[e]</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Osaka; min-height: 16px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>d.addCallbacks(cb, eb)</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Osaka; min-height: 16px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>return d</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Osaka; min-height: 16px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka">def main(argv):<span class="Apple-converted-space"> </span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>"""</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>Command line access to the getPortStatus function. Pass me a hostname and</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>one or more ports and I will report their status.</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>"""<span class="Apple-converted-space"> </span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>host = argv[1]</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>ports = map(int, argv[2:])</font></div><p style="margin: 0.0px 0.0px 0.0px 0.0px; min-height: 14.0px"><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span></font><br class="khtml-block-placeholder"></p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>def cb(status, host, port):</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">         </span>sys.stdout.write("%s:%d %s\n"%(host,port,status))</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Osaka; min-height: 16px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>def eb(err):</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">        </span>sys.stderr.write("%s\n" % err.value)</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Osaka; min-height: 16px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>def portStatusGenerator(host, ports):</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">        </span>for p in ports:</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">            </span>d = getPortStatus(host, p)</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">            </span>d.addCallbacks(cb, eb, (host, p))</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">            </span>yield d</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Osaka; min-height: 16px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span># Limit parallelism otherwise we run out of file descriptors</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span># See <a href="http://jcalderone.livejournal.com/24285.html">http://jcalderone.livejournal.com/24285.html</a></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>work = portStatusGenerator(host, ports)</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>coop = Cooperator()</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>d = DeferredList(</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">            </span>[coop.coiterate(work) for i in xrange(MAX_SIMULTANEOUS_CONNECTIONS)])</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Osaka; min-height: 16px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>d.addCallback(lambda ign: reactor.stop())</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>reactor.run()</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Osaka; min-height: 16px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka">if __name__ == "__main__":</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Osaka" size="3" style="font: 11.0px Osaka"><span class="Apple-converted-space">    </span>sys.exit(main(sys.argv))</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Osaka; min-height: 16px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">_______________________________________________</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Twisted-Python mailing list</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><a href="mailto:Twisted-Python@twistedmatrix.com">Twisted-Python@twistedmatrix.com</a></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><a href="http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python">http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python</a></div> </blockquote></div><br></div></body></html>