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

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.

Am Samstag, 1. Mai 2004 04:34 schrieb Carl Waldbieser:
I tried calling self.transport.write(), but I received an error indicating that only string data is accepted.
Have a look at the struct module. To pack an integer (actually an unsigned long) as a 4 byte string, you would do: self.transport.write(struct.pack("!L",5)) On the receiving side, you would read 4 bytes, and unpack them using: struct.unpack("!L",data)[0] But all the rest is best explained using the docs of the struct module... Heiko.

Am Samstag, 1. Mai 2004 04:34 schrieb Carl Waldbieser:
I tried calling self.transport.write(), but I received an error indicating that only string data is accepted.
Have a look at the struct module. To pack an integer (actually an unsigned long) as a 4 byte string, you would do: self.transport.write(struct.pack("!L",5)) On the receiving side, you would read 4 bytes, and unpack them using: struct.unpack("!L",data)[0] But all the rest is best explained using the docs of the struct module... Heiko.
participants (2)
-
Carl Waldbieser
-
Heiko Wundram