2

I have the following tcpserver simple example. I'm looking to share the factor counter var with a udp server so on each connect it will inc the value for both tcp and udp. So if i connect first with tcp it will be 2 then if I connect to the port on udp.. it will be 3

#!/usr/bin/env python

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

class TCP(Protocol):

    def connectionMade(self):
        self.factory.counter += 1
        self.transport.write(str(self.factory.counter)+'\r\n')
        self.transport.loseConnection()

class QOTDFactory(Factory):

    def __init__(self, protocol='tcp'):
        if protocol == 'tcp':
            self.protocol = TCP
        else:
            self.protocol = UDP

        self.counter = 1

reactor.listenTCP(8007, QOTDFactory('tcp'))
#reactor.listenUDP(8007, QOTDFactory('udp'))

reactor.run()

My main issue is starting up a UDP class that will work along side.. that is my sticking point. I think how i reference the counter is ok and will work

Mike
  • 7,769
  • 13
  • 57
  • 81

3 Answers3

4

The argument to reactor.listenUDP should be a DatagramProtocol instance, as shown in the UDP example: http://twistedmatrix.com/documents/current/core/howto/udp.html. You can't use your QOTDFactory with UDP, so it doesn't need the TCP vs UDP selection logic. Instead, just make a DatagramProtocol subclass with your desired protocol logic and let it share a reference to the factory used by your TCP server.

#!/usr/bin/env python

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

class StreamCounter(Protocol):
    def connectionMade(self):
        self.factory.counter += 1
        self.transport.write(str(self.factory.counter)+'\r\n')
        self.transport.loseConnection()


class DatagramCounter(DatagramProtocol):
    def __init__(self, factory):
        self.factory = factory

    def datagramReceived(self, data, address):
        self.factory.counter += 1
        self.transport.write(str(self.factory.counter), address)


class QOTDFactory(Factory):
    counter = 0
    protocol = StreamCounter


factory = QOTDFactory()
reactor.listenTCP(8007, factory)
reactor.listenUDP(8007, DatagramCounter(factory))

reactor.run()

I renamed TCP and UDP to StreamCounter and DatagramCounter, since they're not limited to use with TCP and UDP respectively (and those weren't terrible descriptive names ;). For example, you'll be able to use StreamCounter over SSL using reactor.listenSSL as well.

Jean-Paul Calderone
  • 47,755
  • 6
  • 94
  • 122
  • How is the DatagramCounter sharing a reference to the factor used by the TCP server? – kratsg Oct 19 '15 at 21:07
  • Excellent question! My answer was actually wrong. I forgot to add the part that hooks the DatagramCounter up to the factory. Edited answer with the fix. – Jean-Paul Calderone Jan 13 '16 at 18:31
1

Does this work for your needs?

#!/usr/bin/env python

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

class Counter():
  def __init__(self):
    self.count = 0

class TCP(Protocol):

    def connectionMade(self):
        self.factory.counter.count += 1
        self.transport.write(str(self.factory.counter)+'\r\n')
        self.transport.loseConnection()

class QOTDFactory(Factory):

    def __init__(self, protocol, counter):
        if protocol == 'tcp':
            self.protocol = TCP
        else:
            self.protocol = UDP

        self.counter = counter

counter = Counter()
reactor.listenTCP(8007, QOTDFactory('tcp', counter))
reactor.listenUDP(8007, QOTDFactory('udp', counter))

reactor.run()
Bryan Austin
  • 487
  • 3
  • 13
0

You could use a static class variable to implement this counter:

class QOTDFactory(Factory):
    counter = 1

    def __init__(self, protocol='tcp'):
        if protocol == 'tcp':
            self.protocol = TCP
        else:
            self.protocol = UDP

        QOTDFactory.counter += 1
Community
  • 1
  • 1
gecco
  • 17,969
  • 11
  • 51
  • 68
  • Sorry maybe the question was worded wrong.. but i think my self.counter is ok in how i reference it in the tcp class.. my issue is starting up another UDP class based off that factory – Mike Dec 30 '11 at 17:00
  • Ok. But honestly I still don't understand. Could you be a bit more precise in formulating the question?! What _exactly_ is the issue you are stuck on? – gecco Dec 30 '11 at 21:20