[Twisted-Python] How to write binary data from a protocol?

Carl Waldbieser waldbie at attglobal.net
Fri Apr 30 22:34:15 EDT 2004


I am attempting to write a server that communicates by a protocol very similar 
to the twisted.protocols.basic.LineReceiver protocol.  The server accepts a 
line of data, followed by a raw data section, and then responds to the client 
with raw data pre-pended with an integer that tells the size of the binary 
data.  I am not sure how to write the integer as binary data in twisted, 
though.  I tried calling self.transport.write(), but I received an error 
indicating that only string data is accepted.  This implementation is meant 
as a drop-in replacement for an existing server, so I don't really want to 
change the protocol.

Below is a sample program that I have been trying to get to work.  It receives 
a line (actually, an integer followed by a newline).  It then enters raw data 
mode where it aquires raw data until it reaches the length specified by the 
integer.  Then it attempts to send a test message consisting of a string 
("xyzzy") pre-pended by the length of the string.  The error output follows 
the sample.

Is there a better way to accomplish what I am trying to do?

Any Help Is Appreciated,
Carl Waldbieser

---- Begin Sample --------------------------------------------------------- 

from twisted.internet import reactor, protocol
from twisted.protocols.basic import LineReceiver

class MyProtocol(LineReceiver):
    delimiter = "\n"
    def __init__(self):
        self.setLineMode()
    def lineReceived(self, line):
        self.length = int(line)
        self.data = ""
        print "Received : %d\n" % self.length
        self.setRawMode()
    def rawDataReceived(self, data):
        self.data += data
        if len(self.data) >= self.length:
            data = self.data[0:self.length]
            remaining = self.data[self.length:]
            print "Received data: %s\n" % data
            self.transport.write(5)
            self.transport.write("xyzzy")
            self.transport.loseConnection()
    
class MyFactory(protocol.ServerFactory):
    protocol = MyProtocol
    
mf = MyFactory()
reactor.listenTCP(2525, mf)
reactor.run()



--- Begin Error -----------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.3/site-packages/twisted/internet/default.py", line 
523, in doSelect
    _logrun(selectable, _drdw, selectable, method, dict)
  File "/usr/lib/python2.3/site-packages/twisted/python/log.py", line 65, in 
callWithLogger
    callWithContext({"system": lp}, func, *args, **kw)
  File "/usr/lib/python2.3/site-packages/twisted/python/log.py", line 52, in 
callWithContext
    return context.call({ILogContext: newCtx}, func, *args, **kw)
  File "/usr/lib/python2.3/site-packages/twisted/python/context.py", line 32, 
in callWithContext
    return func(*args,**kw)
--- <exception caught here> ---
  File "/usr/lib/python2.3/site-packages/twisted/internet/default.py", line 
532, in _doReadOrWrite
    why = getattr(selectable, method)()
  File "/usr/lib/python2.3/site-packages/twisted/internet/tcp.py", line 250, 
in doRead
    return self.protocol.dataReceived(data)
  File "/usr/lib/python2.3/site-packages/twisted/protocols/basic.py", line 
229, in dataReceived
    return self.rawDataReceived(data)
  File "twgfserver.py", line 20, in rawDataReceived
    self.transport.write(6)
  File "/usr/lib/python2.3/site-packages/twisted/internet/abstract.py", line 
140, in write
    assert isinstance(data, str), "Data must be a string."
exceptions.AssertionError: Data must be a string.





More information about the Twisted-Python mailing list