Files
pip/libs/main/io_utils/pibroadcast.h
2026-03-12 14:46:57 +03:00

187 lines
8.2 KiB
C++

//! \~\file pibroadcast.h
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english Multi-interface UDP broadcast, multicast and loopback helper
//! \~russian Вспомогательный класс для UDP broadcast, multicast и loopback на нескольких интерфейсах
/*
PIP - Platform Independent Primitives
Broadcast for all interfaces, including loopback
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIBROADCAST_H
#define PIBROADCAST_H
#include "piethernet.h"
#include "piethutilbase.h"
#include "pip_io_utils_export.h"
//! \~\ingroup IO-Utils
//! \~\brief
//! \~english Multi-channel sender and receiver over multicast, broadcast and loopback endpoints.
//! \~russian Многоканальный отправитель и приемник через multicast-, broadcast- и loopback-конечные точки.
class PIP_IO_UTILS_EXPORT PIBroadcast
: public PIThread
, public PIEthUtilBase {
PIOBJECT_SUBCLASS(PIBroadcast, PIThread);
public:
//! \~english Transport channels that may be enabled independently.
//! \~russian Транспортные каналы, которые можно включать независимо.
enum Channel {
Multicast = 0x01 /** \~english Use multicast addresses \~russian Использовать multicast-адреса */,
Broadcast = 0x02 /** \~english Use broadcast addresses \~russian Использовать broadcast-адреса */,
Loopback = 0x04 /** \~english Use loopback addresses \~russian Использовать loopback-адреса */,
All = 0xFFFF /** \~english Use all channels \~russian Использовать все каналы */
};
//! \~english Bitmask of enabled \a Channel values.
//! \~russian Битовая маска включенных значений \a Channel.
typedef PIFlags<Channel> Channels;
//! \~english Constructs broadcaster, optionally in send-only mode.
//! \~russian Создает broadcaster, при необходимости в режиме только отправки.
//! \~\details
//! \~english
//! When "send_only" is false, receive sockets are initialized too.
//! \~russian
//! Если "send_only" равно false, также инициализируются приемные сокеты.
PIBroadcast(bool send_only = false);
//! \~english Destroys broadcaster and owned transport endpoints.
//! \~russian Уничтожает broadcaster и принадлежащие ему транспортные конечные точки.
~PIBroadcast();
//! \~english Sets enabled channels and schedules reinitialization.
//! \~russian Устанавливает включенные каналы и планирует переинициализацию.
void setChannels(Channels ch);
//! \~english Returns enabled channels.
//! \~russian Возвращает включенные каналы.
Channels channels() const { return _channels; }
//! \~english Returns whether this instance is send-only.
//! \~russian Возвращает, работает ли экземпляр только на отправку.
bool isSendOnly() const { return _send_only; }
//! \~english Sets multicast group IP and schedules reinitialization.
//! \~russian Устанавливает IP multicast-группы и планирует переинициализацию.
void setMulticastGroup(const PIString & mg);
//! \~english Returns multicast group IP.
//! \~russian Возвращает IP multicast-группы.
PIString multicastGroup() const { return mcast_address.ipString(); }
//! \~english Sets multicast port and schedules reinitialization.
//! \~russian Устанавливает multicast-порт и планирует переинициализацию.
void setMulticastPort(ushort port);
//! \~english Returns multicast port.
//! \~russian Возвращает multicast-порт.
ushort multicastPort() const { return mcast_address.port(); }
//! \~english Sets full multicast address and schedules reinitialization.
//! \~russian Устанавливает полный multicast-адрес и планирует переинициализацию.
void setMulticastAddress(const PINetworkAddress & addr);
//! \~english Returns multicast endpoint address.
//! \~russian Возвращает адрес multicast-конечной точки.
PINetworkAddress multicastAddress() const { return mcast_address; }
//! \~english Sets broadcast port and schedules reinitialization.
//! \~russian Устанавливает broadcast-порт и планирует переинициализацию.
void setBroadcastPort(ushort port);
//! \~english Returns broadcast port.
//! \~russian Возвращает broadcast-порт.
ushort broadcastPort() { return bcast_port; }
//! \~english Sets first loopback port and schedules reinitialization.
//! \~russian Устанавливает первый loopback-порт и планирует переинициализацию.
void setLoopbackPort(ushort port);
//! \~english Returns first loopback port.
//! \~russian Возвращает первый loopback-порт.
ushort loopbackPort() { return lo_port; }
//! \~english Sets number of loopback ports and schedules reinitialization.
//! \~russian Устанавливает число loopback-портов и планирует переинициализацию.
void setLoopbackPortsCount(int count);
//! \~english Returns number of loopback ports.
//! \~russian Возвращает число loopback-портов.
int loopbackPortsCount() const { return lo_pcnt; }
//! \~english Starts receiving on all initialized channels.
//! \~russian Запускает прием на всех инициализированных каналах.
void startRead();
//! \~english Stops receiving on all initialized channels.
//! \~russian Останавливает прием на всех инициализированных каналах.
void stopRead();
//! \~english Rebuilds transport endpoints for current \a PIEthernet::allAddresses().
//! \~russian Пересоздает транспортные конечные точки для текущего списка \a PIEthernet::allAddresses().
void reinit();
//! \~english Sends one packet through all enabled channels.
//! \~russian Отправляет один пакет через все включенные каналы.
void send(const PIByteArray & data);
//! \events
//! \{
//! \fn void receiveEvent(PIByteArray data)
//! \~english Emitted when a packet is received on any active channel.
//! \~russian Генерируется при получении пакета на любом активном канале.
EVENT1(receiveEvent, PIByteArray, data);
//! \}
protected:
//! \~english Called when a packet is received.
//! \~russian Вызывается при получении пакета.
virtual void received(PIByteArray data) {}
//! \~english Called after local interface address list changes.
//! \~russian Вызывается после изменения списка адресов локальных интерфейсов.
virtual void addressesChanged() {}
private:
EVENT_HANDLER2(void, mcastRead, const uchar *, data, ssize_t, size);
void destroyAll();
void initAll(PIVector<PINetworkAddress> al);
void run() override;
Channels _channels;
PINetworkAddress mcast_address;
PIMutex mcast_mutex;
PIVector<PIEthernet *> eth_mcast;
PIEthernet * eth_lo;
PIVector<PINetworkAddress> prev_al;
ushort lo_port, bcast_port;
int lo_pcnt;
bool _started, _send_only, _reinit;
};
#endif // PIBROADCAST_H