5
votes

I use Python 2.7.x (2.7.8) and am trying to write a program using twisted python to function like this:

  • Program waits for a messaged received through TCP 7001 or UDP 7000.
  • Messages received through UDP 7000 are bridged over to TCP 7001 going out.

I couldn't figure out how to bridge UDP to TCP, so I looked up an example on this site, like this one, Twisted UDP to TCP Bridge but the problem is that the example is lying because it doesn't work. I added a "print datagram" on datagramReceived to see if UDP responds to receiving anything at all and it does not. This is totally frustrating.

Here's my current test code altered a little bit from that example:

from twisted.internet.protocol import Protocol, Factory, DatagramProtocol
from twisted.internet import reactor

class TCPServer(Protocol):
    def connectionMade(self):
        self.port = reactor.listenUDP(7000, UDPServer(self))

    def connectionLost(self, reason):
        self.port.stopListening()

    def dataReceived(self, data):
        print "Server said:", data


class UDPServer(DatagramProtocol):
    def __init__(self, stream):
        self.stream = stream

    def datagramReceived(self, datagram, address):
        print datagram
        self.stream.transport.write(datagram)


def main():
    f = Factory()
    f.protocol = TCPServer
    reactor.listenTCP(7001, f)
    reactor.run()

if __name__ == '__main__':
    main()

As you can see I changed the ports to comply with my test environment and added a print datagram to see if anything calls datagramReceived. I have no problems sending TCP things to this program, TCPServer works just fine because dataReceived can be called.

1
Is the idea here that incoming messages on UDP/7000 are routed to connected clients on the listening server bound to TCP/700?James Mills
Does it matter when the ports are different? Yes, that's what I'm trying to do. I was under the impression the example link "Bridging UDP to TCP" did that.Noname Noname
I'm the developer of circuits and here is what could work: gist.github.com/prologic/ae987fe4f6fbbd9ca415 -- I haven't tested this yet :)James Mills

1 Answers

3
votes

I ran the code from your question (with one slight modification: I enabled logging). I used telnet to connect to the TCP server on port 7001. I used a Python REPL to create a UDP socket and send some datagrams to port 7000.

Here is my REPL transcript:

>>> import socket
>>> s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>>> s.sendto('hello', ('127.0.0.1', 7000))
5
>>> s.sendto('world', ('127.0.0.1', 7000))
5
>>> 

Here is my server log (formatted to fit on your screen):

... Log opened.
... Factory starting on 7001
... Starting factory <twisted.internet.protocol.Factory instance at 0x2b9b128>
... UDPServer  starting on 7000
... Starting protocol <__main__.UDPServer instance at 0x2e8f8c0>
... hello
... world

And here's my telnet session transcript:

$ telnet localhost 7001
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
helloworld

My interpretation of these results is that the program actually works as specified. I wonder what you did differently when you tried it that produced different, non-working results.