Search code examples
pythoniossocketstwisted

Run Socket Script on Multiple Ports


What I want to do is run the following script on every port, 1025+. What I am doing is making a Blackjack iPhone app that interacts with this script for online gaming. The thing is, I would want to put this on each port manually by changing the port to listen each time for all the ports. How can I do it so that there is a new table on every port. Each table has an ID the app will check for to see the amount of players and who is at the table.

The socket sets the ID for the Table class, but I need to be on multiple ports to be able to keep that table going and saving every player moves and such.

Bottom line, how can I make this script run on every port, how can I change the listening port by itself, and how can I have python make all Tables by itself on each port?

class Table:
    def __init__(self, id):
        self.players = []
        self.positions = {'1': '', '2': '', '3': '', '4': ''}

    def sit(self, player_id, position):
        self.positions[position] = player_id

# --------------------------------------------- #
# --------------------------------------------- #


class Socket(Protocol):
    def connectionMade(self):
        #self.transport.write("""connected""")
        self.factory.clients.append(self)
        print "Clients are ", self.factory.clients

    def connectionLost(self, reason):
        self.factory.clients.remove(self)

    def dataReceived(self, data):
        #print "data is ", data
        a = data.split(':')
        if len(a) > 1:
            command = a[0]
            content = a[1]



            msg = ""

        print msg

        for c in self.factory.clients:
            c.message(msg)

    def message(self, message):
        self.transport.write(message)


factory = Factory()
factory.protocol = Socket
factory.clients = []

reactor.listenTCP(1025, factory)
print "Blackjack server started"
reactor.run()

Solution

  • Answering your question

    You ask:

    • How can I make this script run on every port?
    • How can I change the listening port by itself?
    • How can I have python make all Tables by itself on each port?

    I think the answer here is to simply use a loop to bind the factory to as many ports as you want. However, since you're storing a list of clients in your factory as well, you'll need to create a new factory for reach port, as well. So something like:

    factories = [ ]
    for i in range(0, NUM_TABLES):
        factory = Factory()
        factory.protocol = Socket()
        factory.clicents = []
        factories.append(factory)
        reactor.listenTCP(1025 + i, factory)
        reactor.run()
    

    You're using classes, so each factory keeps its own list of clients, each one has its own Socket instance to manage the connection. You don't show how Table instances are instantiated, but as long as each Socket or Factory instance instantiates and maintains a reference to the Table, this should allow you to have multiple connections, each with its own state.

    By keeping a list of all factories, you can iterate over them to make a list of running games, etc.

    Considering a different architecture

    While the above might work, it's not how client-server systems are typically architected. In particular, your system here requires your client to know what port to use. That may work ad hoc when you're all in your living room together, but it's tedious and won't scale in general.

    What you want is something, like a webserver, that listens on one port to establish the connection, and then tells the client: "hey, your table id is 25, use that whenever you want to talk". In addition, this means making a list of tables available to the client, so they can pick one. And, you can get fancier from there: a special expiring cookie given to client so that it doesn't accidentally hack/disturb a game that it's no longer part of, etc.