OceanSocket::OceanSocket(QObject *parent) : QObject(parent) { // setup the heartbeat timer heartbeat = new QTimer(this); connect(heartbeat, SIGNAL(timeout()), this, SLOT(heartbeatTimer())); // setup our ocean sockets groupAddress = QHostAddress(MULTICAST_ADDRESS); QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces(); for (int i = 0; i < ifaces.count(); i++) { QNetworkInterface iface = ifaces.at(i); if (iface.flags().testFlag(QNetworkInterface::IsUp) && !iface.flags().testFlag(QNetworkInterface::IsLoopBack) && iface.flags().testFlag(QNetworkInterface::CanMulticast)) { for (int j = 0; j < iface.addressEntries().count(); j++) { if (iface.addressEntries().at(j).ip().protocol() != QAbstractSocket::IPv4Protocol) continue; qDebug() << "Ocean bind to iface: " << iface.name() << endl << "IP: " << iface.addressEntries().at(j).ip().toString() << endl; QUdpSocket* socket = new QUdpSocket(this); socket->bind(QHostAddress::AnyIPv4, 8047, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint); socket->joinMulticastGroup(groupAddress, iface); connect(socket, SIGNAL(readyRead()), this, SLOT(processIncomingWaves())); boundAddresses.append(iface.addressEntries().at(j).ip()); multicastSockets.append(socket); } } } sendSocket = new QUdpSocket(this); sendSocket->bind(); }
bool CQMedia::loadURL(const QString& url) { QString tmp = url; tmp.remove(0,6); QString ip = tmp.split(QChar(':'))[0]; int port = tmp.split(QChar(':'))[1].toInt(); QUdpSocket udp; udp.bind(port,QUdpSocket::ShareAddress); udp.joinMulticastGroup(QHostAddress(ip)); QEventLoop q; QTimer::singleShot(1000,&q,SLOT(quit())); connect(&udp,SIGNAL(readyRead()),&q,SLOT(quit())); q.exec(); if(udp.pendingDatagramSize() == -1) { //qDebug("has no avalid datapkg..."); QTimer::singleShot(3500,this,SLOT(_emitTimeout())); return false; } qDebug("has avalid datapkg..."); udp.leaveMulticastGroup(QHostAddress(ip)); udp.close(); this->url = url; // SdpsrcParser sdpSrc(url); // if(!sdpSrc.isValid()) // { // qDebug()<<"SdpsrcParser invalid!!"; // return false; // } // sdpSrc.printf(); GstElement *udpsrc = gst_bin_get_by_name(GST_BIN(pipeline),"udpsrc"); GstCaps *caps = gst_caps_new_simple("application/x-rtp",NULL); //QString uri = "udp://"+sdpSrc.broadcastIP+":"+QString::number(sdpSrc.v_port); // QString uri = "udp://"+sdpSrc.broadcastIP+":"+QString::number(sdpSrc.v_port); // QString uri = "udp://239.255.42.42:1234"; QString uri = url; g_object_set(G_OBJECT(udpsrc),"uri",uri.toUtf8().data(),"caps",caps,NULL); gst_object_unref(udpsrc); return true; }
void Discover::announceRecords () { // Reset timer timer->start(announcePeriodMsec); if (not running) return; // Servers don't announce periodically or send departure messages if (mServerMode) return; // Start building a list of records to send in each scope QList<Record> recordsToSend; /////////////////////////////////////////////////////////////////////// // Global scope first /////////////////////////////////////////////////////////////////////// for (Record record : ownedRecords) if (record["Scope"] == "Global") { recordsToSend.push_back(record); } if (not recordsToSend.empty() or defaultScope=="Global") { // This is a discovery request which should be responded to QByteArray datagram("DSDR"); if (departure) datagram = "DSDD"; datagram += makeDatagram(recordsToSend, false); // Send to each Global server for (QPair<QHostAddress,quint16> globalServer : globalServers) { globalSocket->writeDatagram(datagram, globalServer.first, globalServer.second); } } /////////////////////////////////////////////////////////////////////// // Local scope next /////////////////////////////////////////////////////////////////////// for (Record record : ownedRecords) if (record["Scope"] == "Local") { recordsToSend.push_back(record); } if (not recordsToSend.empty() or defaultScope=="Global" or defaultScope=="Local") { QByteArray datagram("DSDA"); if (announceNeedsResponse) datagram = "DSDR"; if (departure) datagram = "DSDD"; datagram += makeDatagram(recordsToSend, true); // For each interface for (auto iface : QNetworkInterface::allInterfaces()) { // For each IPv4 address on this interface for (auto entry : iface.addressEntries()) { if (entry.ip().protocol() != QAbstractSocket::IPv4Protocol) continue; // Add it to addressEntryCache if necessary for local scope testing if (not addressEntryCache.contains(entry)) addressEntryCache.push_back(entry); // Multicast if (iface.flags().testFlag(QNetworkInterface::CanMulticast) and !entry.ip().isNull() and !entry.ip().isLoopback()) { // Create the socket if it doesn't exit yet if (not multiSocket.contains(entry.ip().toString())) { logDebug(QString("New multicast socket: %1 %2").arg(entry.ip().toString(), entry.netmask().toString())); // Add it, create and bind the socket QUdpSocket* socket = new QUdpSocket(this); connect(socket, SIGNAL(readyRead()), this, SLOT(readDatagrams())); socket->setSocketOption(QAbstractSocket::MulticastTtlOption, 1); if (not socket->bind(QHostAddress::AnyIPv4, port, QAbstractSocket::ShareAddress | QAbstractSocket::ReuseAddressHint)) { logWarning(QString("Error binding to iface %1: %2").arg(entry.ip().toString(), socket->errorString())); } socket->setMulticastInterface(iface); socket->joinMulticastGroup(groupAddress, iface); multiSocket.insert(entry.ip().toString(), socket); } // Send datagram multiSocket[entry.ip().toString()]->writeDatagram(datagram, groupAddress, port); } } } } /////////////////////////////////////////////////////////////////////// // Loopback scope last /////////////////////////////////////////////////////////////////////// for (Record record : ownedRecords) if (record["Scope"] == "Loopback") { recordsToSend.push_back(record); } if (not recordsToSend.empty() or true) // Any scope is above or equivalent to loopback { QByteArray datagram("DSDA"); if (announceNeedsResponse) datagram = "DSDR"; if (departure) datagram = "DSDD"; datagram += makeDatagram(recordsToSend, true); // Loopback //loopbackSocket->writeDatagram(datagram, QHostAddress::LocalHost, port); } // Reset announceNeedsResponse = false; departure = false; }