Это сводит меня с ума какое-то время. Поскольку я никогда не занимался программным обеспечением, связанным с сетью, я не могу подвести итоги этого эксперимента.
Мне предоставлена информация о сервере, который транслирует соответствующую информацию с использованием SSDP. Мне дали IP и порт в соответствии со стандартом. Мне также дали запрос и цель поиска, которые мне нужно использовать на стороне получателя. Я использую свою последнюю итерацию для этого примера, в котором я решил использовать одноэлементный класс, который управляет обнаружением. Настоящая строка ST, которую я использую, - это та, которую я также предоставил, не обращайте внимания на приведенную ниже...
DiscoveryManager.h
class DiscoveryManager : public QObject
{
private:
DiscoveryManager( QObject *parent=0 );
public:
~DiscoveryManager();
// Public Accessor for the singleton instance of the class
static DiscoveryManager* Instance();
void Discover();
public:
void readPending();
private:
// Singleton instance of the class
static DiscoveryManager* _instance;
QUdpSocket* socket;
};
DiscoveryManager.cpp
// Definition of singleton instance
DiscoveryManager* DiscoveryManager::_instance;
// Network Parameters
quint16 port = 1900;
QHostAddress groupAddress = QHostAddress("239.255.255.250");
DiscoveryManager::DiscoveryManager(QObject *parent)
: QObject(parent)
, socket( nullptr )
{
socket = new QUdpSocket(this);
auto ok = m_sock->bind(QHostAddress::AnyIPv4, port, QUdpSocket::ShareAddress);
if (!ok)
{
printf("Bind Error\n");
return;
}
ok = socket->joinMulticastGroup(groupAddress);
if (!ok) {
printf("Join Multicast Group Failed\n");
return;
}
connect(socket, SIGNAL(readyRead()), this, SLOT(readPending()));
}
DiscoveryManager* DiscoveryManager::Instance()
{
if(_instance == nullptr)
{
_instance = new DiscoveryManager();
}
return _instance;
}
void
DiscoveryManager::startDiscovery()
{
QByteArray message("M-SEARCH * HTTP/1.1\r\n" \
"HOST: 239.255.255.250:1900\r\n" \
"MAN: \"ssdp:discover\"\r\n" \
"MX: 5\r\n" \
"ST: ***:******-****-***:*******:***********:*\r\n" \
"\r\n");
auto writeOk = socket->writeDatagram(message.data(), groupAddress, port);
if (writeOk == -1) {
printf("Writing Datagram failed\n");
return;
}
}
void
DiscoveryManager::readPending()
{
while (socket->hasPendingDatagrams()) {
QByteArray reply;
reply.resize(socket->pendingDatagramSize());
socket->readDatagram(reply.data(), reply.size());
// ... Parse Text Here ...
}
}
Результаты: в 90 % случаев это не удается. Когда я пытаюсь распечатать сообщения, я получаю ответ, который всегда является эхом того, что я запросил. Независимо от того, как долго я оставляю его, правильный ответ никогда не приходит. С другой стороны, когда условия «в самый раз», обнаружение безупречно и всегда немедленно возвращает результат.
Ожидаемые результаты. Я ожидаю ответа сервера с дополнительной информацией, например о местоположении.
Соображения:
- Поскольку мне трудно понять, почему происходит сбой кода, связанного с сетью, я не могу по результатам сделать вывод, является ли мой код получателя неправильным или сервер был настроен неправильно. Что может быть индикатором для меня, чтобы использовать? Могут ли на это повлиять такие вещи, как установленные в пространстве VPN? Имеет ли значение, работает ли сервер на моей локальной машине?
- Я прошел через множество итераций, когда пытался использовать разные флаги подключения, уничтожал и сбрасывал объект или сокет, прежде чем пытаться снова, и даже выполнял цикл, который запрашивал более 5000 раз, чтобы понять поведение.
- Если этот код не похож на один, я попытался воспроизвести точно такой же код и порядок, указанный в документации Qt.