[Twisted-Python] Noob Question

Peter Sabaini peter at sabaini.at
Sun Mar 15 13:27:19 EDT 2009


On Sunday 15 March 2009 14:55:25 Shelby Ramsey wrote:
> Peter,
>
> Thanks for the assistance.  I think you and David have me on the right
> path.  Just to clarify the protocol looks like this:
>
> Content-Length: 984
> Content-Type: text/event-xml
>
> <event>
>   <headers>
>    $bunchofinfo ...
>   </headers>
> </event>
>
> Where the body (and the content length) start and stop with the <event> ...
> </event>.
>
> Here is what I've done so far:
>
> from twisted.internet import reactor, protocol
> from twisted.protocols import basic
> from re import compile, findall
>
> bl_p = compile('Content-Length:\s(\d+)')
>
> class My_Client(basic.LineReceiver):
>     def __init__(self):
>         self.body_length = None
>
>     def connectionMade(self):
>         self.transport.write("login \r\n\r\n")
>         self.transport.write("sendevents\r\n\r\n")
>
>     def lineReceived(self, line):
>         print line
>         bl_m = bl_p.findall(line)
>         if bl_m:
>             print 'Match:'
>             self.body_length = int(bl_m[0]) - len(line) # this doesn't
> really work because it doesn't factor in the len of the next line

Hm, I thought you said the Content-Length was only the length of the body? Ie. 
without headers?

>             self.setRawMode()
>
>     def rawDataReceived(self, data):
>        datalen = len(data)
>        if self.body_length > datalen:
>            self.body_length -= datalen
>            print data
>        else:
>            part = data[:self.body_length]
>            extra = data[self.body_length:]
>            print 'Left Over\n:'
>            print extra
>            self.setLineMode(extra=extra)
>
>     def connectionLost(self, reason):
>         print "%s" % (reason)
>
> class My_Factory(protocol.ClientFactory):
>     protocol = My_Client
>
>     def clientConnectionFailed(self, connector, reason):
>         print "Connection failed - goodbye!"
>         reactor.stop()
>
>     def clientConnectionLost(self, connector, reason):
>         print "Connection lost - goodbye!"
>         reactor.stop()
>
> def main():
>     f = FS_Factory()

Should be My_Factory() above, right?

>     reactor.connectTCP("$IP", $PORT, f)

I assume $IP / $PORT get replaced with actual values?

>     reactor.run()
>
> # this only runs if the module was *not* imported
> if __name__ == '__main__':
>     main()
>
> To me ... this looks somewhat correct ... but it doesn't seem to actually
> ever use the line received method (note the print statement ...).  For
> instance upon logging in it should respond with a +OK Logged In ... but it
> never prints that.

One thing that might be an issue here is the line delimiter. Twisted by 
default has "\r\n" as a line delimiter, so if you fed it only "\n" newlines, 
basic.LineReceiver would never detect an end of line. 

The delimiter is an attribute of the class, ie. 

class My_Client(basic.LineReceiver):
    delimiter = '\n'

switches to newline-delim. lines.


Two tools I find indispensable for this kind of work:

* the Python debugger "pdb" which lets you browse around interactively at 
interesting points in the running code ; see eg. here for a short intro: 
http://www.ferg.org/papers/debugging_in_python.html

* some kind of packet sniffer, eg. tcpdump or wireshark so you can actually 
see whats going on at the wire.

bye,
peter.



> And then when it receives an "<event>..." it actually dies with this error:
>
> [Failure instance: Traceback (failure with no frames): <class
> 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.
> ]
> Connection lost - goodbye!
>
> So I'm a bit lost as to what the impact of adding the rawDataReceived
> method has done.
>
> Thanks!
>
> SDR

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: This is a digitally signed message part.
Url : http://twistedmatrix.com/pipermail/twisted-python/attachments/20090315/76c2d9be/attachment.pgp 


More information about the Twisted-Python mailing list