Skip to content

Commit

Permalink
libdeng2|Fixed: Allow multiple Beacons to coexist on one machine
Browse files Browse the repository at this point in the history
Each server will listen on its own UDP port. The default range of UDP
ports that local servers use is 13209..13224 (16 ports).
  • Loading branch information
skyjake committed Feb 12, 2013
1 parent 774461d commit 6fd78c8
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 7 deletions.
6 changes: 6 additions & 0 deletions doomsday/libdeng2/include/de/net/beacon.h
Expand Up @@ -43,6 +43,12 @@ class DENG2_PUBLIC Beacon : public QObject

virtual ~Beacon();

/**
* Port the beacon uses for listening.
* @return Port.
*/
duint16 port() const;

/**
* Starts the beacon with a message to give out.
*
Expand Down
34 changes: 27 additions & 7 deletions doomsday/libdeng2/src/net/beacon.cpp
Expand Up @@ -27,6 +27,12 @@

namespace de {

/**
* Maximum number of Beacon UDP ports in simultaneous use at one machine, i.e.,
* maximum number of servers on one machine.
*/
static duint16 const MAX_LISTEN_RANGE = 16;

static char const *discoveryMessage = "Doomsday Beacon 1.0";

struct Beacon::Instance
Expand Down Expand Up @@ -59,6 +65,11 @@ Beacon::~Beacon()
delete d;
}

duint16 Beacon::port() const
{
return d->port;
}

void Beacon::start(duint16 serviceListenPort)
{
DENG2_ASSERT(!d->socket);
Expand All @@ -68,11 +79,17 @@ void Beacon::start(duint16 serviceListenPort)
d->socket = new QUdpSocket;
connect(d->socket, SIGNAL(readyRead()), this, SLOT(readIncoming()));

if(!d->socket->bind(d->port, QUdpSocket::ShareAddress))
for(duint16 attempt = 0; attempt < MAX_LISTEN_RANGE; ++attempt)
{
/// @throws PortError Could not open the UDP port.
throw PortError("Beacon::start", "Could not bind to UDP port " + String::number(d->port));
if(d->socket->bind(d->port + attempt, QUdpSocket::DontShareAddress))
{
d->port = d->port + attempt;
return;
}
}

/// @throws PortError Could not open the UDP port.
throw PortError("Beacon::start", "Could not bind to UDP port " + String::number(d->port));
}

void Beacon::setMessage(IByteArray const &advertisedMessage)
Expand Down Expand Up @@ -222,10 +239,13 @@ void Beacon::continueDiscovery()

LOG_TRACE("Broadcasting %i bytes") << block.size();

// Send a new broadcast.
d->socket->writeDatagram(block,
QHostAddress::Broadcast,
d->port);
// Send a new broadcast to the whole listening range of the beacons.
for(duint16 range = 0; range < MAX_LISTEN_RANGE; ++range)
{
d->socket->writeDatagram(block,
QHostAddress::Broadcast,
d->port + range);
}
}

} // namespace de

0 comments on commit 6fd78c8

Please sign in to comment.