私はQtに比較的慣れていませんが、少し調べてみました。UDPブロードキャストを処理する基本クラスがあり、クラスのコンストラクターで次のように接続ステートメントを実行します。
NetworkConnection::NetworkConnection(QObject *parent)
: QObject(parent) // Based on QObject
, m_server_search( new QUdpSocket ) // Our UDP Broadcast socket
, m_waiting_for_server( false )
, m_found_server( false )
{
qDebug() << "NetworkConnection::constructor";
connect( m_server_search, SIGNAL(readyRead()), this, SLOT(serverResponse()), Qt::UniqueConnection );
if ( m_server_search->bind( QHostAddress::AnyIPv4, (quint16)PORT_MULTICAST, QUdpSocket::ShareAddress ) )
{
if ( m_server_search->joinMulticastGroup( QHostAddress( MULTICAST_GROUP ) ) )
{
connect( this, SIGNAL(broadcast(NetworkMessage)), this, SLOT(broadcast_message(NetworkMessage)), Qt::UniqueConnection );
this->m_ping_timer = this->startTimer(2000);
qDebug() << "Ping timer id=" << this->m_ping_timer;
} else qDebug() << "Couldn't start multicast listener";
} else qDebug() << "Couldn't bind multicast to port" << PORT_MULTICAST;
}
ブロードキャスト用のシグナル/スロット インターフェイスをセットアップしました。
signals:
void serverFound();
void serverNotFound();
void broadcast(NetworkMessage);
private slots:
void serverResponse();
void broadcast_message( NetworkMessage msg );
次broadcast_message
のようになります。
void NetworkConnection::broadcast_message( NetworkMessage msg )
{
QByteArray raw = msg.toString();
qDebug() << "NetworkConnection::broadcast_message>" << raw;
if ( m_server_search->writeDatagram( raw.data(), raw.size(), QHostAddress(MULTICAST_GROUP), (quint16)PORT_MULTICAST ) < 1 ) qDebug() << "Failed broadcast last message";
}
私のタイマーはうまく機能します。コードは次のとおりです。
void NetworkConnection::timerEvent(QTimerEvent *event)
{
qDebug() << "NetworkConnection::timerEvent with id" << event->timerId() << "(ping timer=" << this->m_ping_timer << ")";
if ( event->timerId() == this->m_ping_timer )
{
qDebug() << "NetworkConnection::pingForServer";
if ( m_waiting_for_server && !m_found_server )
{
qDebug() << "Server not found!";
emit this->serverNotFound();
return;
}
if ( !m_found_server )
{
qDebug() << "Sending a ping to the server";
NetworkMessage msg( m_software_guid, get_microseconds(), QString("whoisaserver") );
emit this->broadcast( msg );
m_waiting_for_server = true;
m_found_server = false;
}
}
}
「サーバーにパイントを送信しています」というテキストは1回しか表示されませんが、broadcast_messageはqDebug()
複数回出力します。
私は明示的に複数のスレッドを使用していません。ご覧のとおり、Qt::UniqueConnection を使用していますが、明らかに影響はありませんか?
では、なぜスロットが複数回呼び出されるのでしょうか? 私はそれを少しデバッグして、emit を使用せずに this->broadcast( ... ) を呼び出してみましたが、それでも複数回呼び出されます。
編集:スロットにカウンターを追加したところ、broadcast_message
340回呼び出されました。それに何か意味はありますか?