[Twisted-Python] Noob Question
Peter Sabaini
peter at sabaini.at
Sun Mar 15 11:27:19 MDT 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: signature.asc
Type: application/pgp-signature
Size: 197 bytes
Desc: This is a digitally signed message part.
URL: </pipermail/twisted-python/attachments/20090315/76c2d9be/attachment.sig>
More information about the Twisted-Python
mailing list