Commit a0fbe9284b1538f9149b43581adcda3847f6f0a0
add client which can receive the server broadcast message, no handling yet though.
| |   |
| 1 | 1 | SET( |
| 2 | 2 | CLASSES |
| 3 | 3 | NetworkClient |
| NetworkClient_ServerDiscoverer |
| 4 | 5 | ) |
| 5 | 6 | |
| 6 | 7 | SET(SOURCES) |
| |   |
| 1 | 1 | #include "NetworkClient.h" |
| #include "NetworkClient_ServerDiscoverer.h" |
| 2 | 3 | |
| 3 | 4 | #include <QApplication> |
| 4 | 5 | #include <QDebug> |
| … | … | |
| 8 | 8 | NetworkClient::NetworkClient() |
| 9 | 9 | : QObject(0) |
| 10 | 10 | { |
| new ServerDiscoverer(this); |
| 11 | 12 | } |
| 12 | 13 | |
| 13 | 14 | QString NetworkClient::pluginName() const |
| |   |
| 14 | 14 | QString pluginAuthor() const; |
| 15 | 15 | QString uniqueId() const; |
| 16 | 16 | private: |
| class Implementation; |
| class ServerDiscoverer; |
| 18 | 18 | }; |
| |   |
| #include "NetworkClient_ServerDiscoverer.h" |
|
| #include "../NetworkCommon/NetworkCommon.h" |
|
| #include <QUdpSocket> |
|
| NetworkClient::ServerDiscoverer::ServerDiscoverer(QObject* parent) |
| : QObject(parent) |
| , m_socket(new QUdpSocket(this)) |
| { |
| m_socket->bind(); |
| connect(m_socket, SIGNAL(readyRead()), SLOT(handleResponses())); |
| sendBroadcast(); |
| } |
|
| void NetworkClient::ServerDiscoverer::sendBroadcast() |
| { |
| m_socket->writeDatagram(NetworkCommon::discoveryMessage(), QHostAddress::Broadcast, NetworkCommon::portNumber()); |
| } |
|
| void NetworkClient::ServerDiscoverer::handleResponses() |
| { |
| while(m_socket->hasPendingDatagrams()) |
| { |
| // don't worry about overflow, UDP packets have reasonable maximum size |
| QByteArray payload; |
| payload.resize(m_socket->pendingDatagramSize()); |
| QHostAddress source; |
| quint16 sourcePort; |
| m_socket->readDatagram(payload.data(), payload.size(), &source, &sourcePort); |
| if(sourcePort != NetworkCommon::portNumber()) |
| { |
| qDebug() << "Got a stray UDP packet from" << QString("%1:%2").arg(source.toString()).arg(sourcePort); |
| continue; |
| } |
| else |
| { |
| qDebug() << "Got a response:" << payload; |
| } |
| } |
| } |
| |   |
| #pragma once |
|
| #include "NetworkClient.h" |
|
| class QUdpSocket; |
|
| #include <QPair> // before QHostAddress for Qt 4.5 |
|
| #include <QHostAddress> |
|
| class NetworkClient::ServerDiscoverer : public QObject |
| { |
| Q_OBJECT; |
| public: |
| ServerDiscoverer(QObject* parent); |
| signals: |
| void foundServer(const QString& name, const QByteArray& uuid, const QHostAddress& address, quint16 tcpPort); |
| private slots: |
| void sendBroadcast(); |
| void handleResponses(); |
| private: |
| QUdpSocket* m_socket; |
| }; |
| |   |
| SET( |
| CLASSES |
| NetworkCommon |
| ) |
|
| SET(SOURCES) |
| SET(HEADERS) |
| FOREACH(class ${CLASSES}) |
| LIST(APPEND SOURCES ${class}.cpp) |
| LIST(APPEND HEADERS ${class}.h) |
| ENDFOREACH() |
|
| INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) |
| QT4_WRAP_CPP(MOC_SOURCES ${HEADERS}) |
| ADD_LIBRARY( |
| NetworkCommon |
| ${SOURCES} |
| ${MOC_SOURCES} |
| ) |
| |   |
| #include "NetworkCommon.h" |
|
| #include <QDebug> |
| #include <QtPlugin> |
|
| NetworkCommon::NetworkCommon() |
| : QObject(0) |
| { |
| } |
|
| QString NetworkCommon::pluginName() const |
| { |
| return tr("Common Network Client/Server Plugin"); |
| } |
|
| QString NetworkCommon::pluginAuthor() const |
| { |
| return QString::fromLatin1("Fred Emmott"); |
| } |
|
| QString NetworkCommon::uniqueId() const |
| { |
| return "org.jerboaplayer.NetworkCommon"; |
| } |
|
| quint16 NetworkCommon::portNumber() |
| { |
| return 61719; // pseudo-random from private range |
| } |
|
| QByteArray NetworkCommon::discoveryMessage() |
| { |
| return "Jerboa Network Discovery/1.0\n"; |
| } |
|
| Q_EXPORT_PLUGIN2(Jerboa_NetworkCommon, NetworkCommon); |
| |   |
| #pragma once |
|
| #include "Plugin.h" |
|
| #include <QObject> |
|
| class NetworkCommon: public QObject, public Jerboa::Plugin |
| { |
| Q_OBJECT; |
| Q_INTERFACES(Jerboa::Plugin); |
| public: |
| NetworkCommon(); |
| QString pluginName() const; |
| QString pluginAuthor() const; |
| QString uniqueId() const; |
|
| static quint16 portNumber(); |
| static QByteArray discoveryMessage(); |
| }; |
| |   |
| 1 | 1 | #include "NetworkServer_Implementation.h" |
| 2 | 2 | |
| #include "../NetworkCommon/NetworkCommon.h" |
|
| 3 | 5 | #include "Uuid.h" |
| 4 | 6 | |
| 5 | 7 | #include <QDebug> |
| … | … | |
| 10 | 10 | #include <QTcpServer> |
| 11 | 11 | #include <QUdpSocket> |
| 12 | 12 | |
| const quint16 PORT_NUMBER = 61719; // pseudo-random from private range |
| const QByteArray DISCOVERY_MESSAGE = "Jerboa Network Discovery/1.0\n"; |
|
| 16 | 13 | NetworkServer::Implementation::Implementation(Jerboa::CollectionInterface* collection, Jerboa::PlayerInterface* player, Jerboa::PlaylistInterface* playlist) |
| 17 | 14 | : QObject(0) |
| 18 | 15 | , m_collection(collection) |
| … | … | |
| 18 | 18 | , m_discoverySocket(new QUdpSocket(this)) |
| 19 | 19 | , m_server(new QTcpServer(this)) |
| 20 | 20 | { |
| const bool startedDiscovery = m_discoverySocket->bind(QHostAddress::Any, PORT_NUMBER); |
| const bool startedDiscovery = m_discoverySocket->bind(QHostAddress::Any, NetworkCommon::portNumber()); |
| 22 | 22 | if(!startedDiscovery) |
| 23 | 23 | { |
| 24 | 24 | qDebug() << "Failed to start network discovery:" << m_discoverySocket->errorString(); |
| … | … | |
| 108 | 108 | QHostAddress source; |
| 109 | 109 | quint16 sourcePort; |
| 110 | 110 | m_discoverySocket->readDatagram(payload.data(), payload.size(), &source, &sourcePort); |
| if(payload == DISCOVERY_MESSAGE) |
| if(payload == NetworkCommon::discoveryMessage()) |
| 112 | 112 | { |
| 113 | 113 | qDebug() << "Received a discovery message from" << QString("%1:%2").arg(source.toString()).arg(sourcePort); |
| 114 | 114 | // send a response |