Home > Software engineering >  How do I efficiently select ports in multi process C linux servers?
How do I efficiently select ports in multi process C linux servers?

Time:07-01

I am using Amazon Gamelift to manage a c game server in an Amazon Linux 2 environment. This service will launch multiple instances of the same game server on the same machine at nearly the same time. These processes then report back when they are ready and what port they are bound to. What is the best way to attempt to bind to ports in the same range. For instance, I may choose to use between 1900 and 2100, but I may need 100 processes started up. How do I avoid a ton of collisions as these processes try to all bind to different ports at nearly the same time?

CodePudding user response:

So I kind of hate that the only answer now is seemingly trying random ports within the unblocked range and retrying on collision, but that is all I seem to have to go on, so I implemented it. Here is the code if its helpful to anyone:

bool MultiplayerServer::tryToBindPort(int port, int triesLeft)
{
    ServerPort = port;
    cout << "Trying Port " << port << "\n";
    triesLeft--;

    Server.Bind(port, [this, port, triesLeft](int errorCode, string errorMessage) 
    {
        cout << errorCode << " : " << errorMessage << "\n";
        cout << "Unable to bind to port: "   port << "\n";
        if(triesLeft <= 0)
        {
            cout << "Ran out of tries to find a good port. Ending \n";
            MyGameLiftServer.TerminateGameSession();
            return;
        }

        tryToBindPort(getRandomPortInRange(), triesLeft);
    });
}

int MultiplayerServer::getRandomPortInRange()
{
    std::random_device rd;
    std::mt19937 mt(rd());
    uniform_int_distribution<int> intDistro(MinPort, MaxPort);
    return intDistro(mt);
}

It seems to work good so far. I plan on opening about 500 ports and then have a max of around 150 server processes started. The chances of a long string of collisions happening then should be fairly small.

  • Related