这个让我疯狂了一段时间。由于我从未做过任何与网络相关的代码,因此我无法总结此实验的结果。
我收到了有关使用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%的时间,这都失败了。当我尝试打印消息时,我得到的响应总是与我所查询的内容相呼应。无论我离开多久,正确的反应永远不会到来。另一方面,当条件“恰到好处”时,发现是完美无缺的,并且总是立即返回结果。
预期结果:我希望看到服务器响应,其中包含更多信息,例如位置。
注意事项:
我在Mac上遇到了类似的问题但在iOS上却没有相同的代码。你设法解决了吗?怎么样?
好吧,我必须获得响应的唯一方法是绑定到不同于1900的端口,但我不知道是否是正确的方法。我通过使用wireshark找到了这个,例如Google Chrome在发送M-SEARCH和1900作为目标时使用“随机”端口作为源端口。
通过将绑定端口设置为1900,我只能将数据报发送到“239.255.255.250”,例如其他软件M-SEARCH或设备NOTIFY消息。
这应该使你的代码工作:
auto ok = m_sock->bind(QHostAddress::AnyIPv4, 56123, QUdpSocket::ShareAddress);