14 #include "libmythbase/mythconfig.h"
17 # include <winsock2.h>
18 # include <ws2tcpip.h>
19 # define GET_SOCKET_ERROR WSAGetLastError()
21 # include <sys/socket.h>
22 # include <netinet/in.h>
23 # include <arpa/inet.h>
24 # define GET_SOCKET_ERROR errno
31 #include <QStringList>
39 #define LOC QString("MMulticastSocketDevice(%1:%2): ") \
40 .arg(m_address.toString()).arg(socket())
43 const QString& sAddress, quint16 nPort, u_char ttl) :
44 MSocketDevice(MSocketDevice::Datagram),
45 m_address(sAddress), m_port(nPort)
55 setSocket(createNewSocket(), MSocketDevice::Datagram);
57 m_imr.imr_multiaddr.s_addr = inet_addr(sAddress.toLatin1().constData());
58 m_imr.imr_interface.s_addr = htonl(INADDR_ANY);
60 if (setsockopt(socket(), IPPROTO_IP, IP_ADD_MEMBERSHIP,
63 LOG(VB_GENERAL, LOG_ERR,
LOC +
"setsockopt - IP_ADD_MEMBERSHIP " +
ENO);
66 if (setsockopt(socket(), IPPROTO_IP, IP_MULTICAST_TTL,
67 (
const char *)&ttl,
sizeof(ttl)) < 0)
69 LOG(VB_GENERAL, LOG_ERR,
LOC +
"setsockopt - IP_MULTICAST_TTL " +
ENO);
72 setAddressReusable(
true);
75 LOG(VB_GENERAL, LOG_ERR,
LOC +
"bind failed");
81 (setsockopt(socket(), IPPROTO_IP, IP_DROP_MEMBERSHIP,
86 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"setsockopt - IP_DROP_MEMBERSHIP " +
92 const char *data, quint64 len,
93 const QHostAddress & host, quint16 port)
95 #ifdef IP_MULTICAST_IF
96 if (host.toString() ==
"239.255.255.250")
101 if (
address.protocol() != QAbstractSocket::IPv4Protocol)
104 QString addr =
address.toString();
105 if (addr ==
"127.0.0.1")
108 uint32_t interface_addr =
address.toIPv4Address();
109 if (setsockopt(socket(), IPPROTO_IP, IP_MULTICAST_IF,
110 (
const char *)&interface_addr,
111 sizeof(interface_addr)) < 0)
113 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
114 "setsockopt - IP_MULTICAST_IF " +
ENO);
116 retx = MSocketDevice::writeBlock(data, len, host,
port);
118 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"writeBlock on %1 %2")
119 .arg((*it).toString()).arg((retx==(
int)len)?
"ok":
"err"));
121 std::this_thread::sleep_for(std::chrono::milliseconds(
MythRandom(5, 9)));
127 return MSocketDevice::writeBlock(data, len, host,
port);