8#include "daq/slc/system/UDPSocket.h"
10#include <daq/slc/base/IOException.h>
18#include <sys/socket.h>
19#include <netinet/in.h>
26unsigned int UDPSocket::findSubnet(
unsigned int addr)
28 struct ifaddrs* ifa_list;
30 char addrstr[256], netmaskstr[256];
31 if (getifaddrs(&ifa_list) != 0)
return 0;
32 for (ifa = ifa_list; ifa != NULL; ifa = ifa->ifa_next) {
33 memset(addrstr, 0,
sizeof(addrstr));
34 memset(netmaskstr, 0,
sizeof(netmaskstr));
35 if (ifa->ifa_addr->sa_family == AF_INET &&
36 addr == ((
struct sockaddr_in*)ifa->ifa_addr)->sin_addr.s_addr) {
37 addr |= ~(((
struct sockaddr_in*)ifa->ifa_netmask)->sin_addr.s_addr);
40 freeifaddrs(ifa_list);
46 m_addr.sin_family = AF_INET;
47 m_addr.sin_addr.s_addr = INADDR_ANY;
50UDPSocket::UDPSocket(
unsigned int port)
52 m_addr.sin_port = htons(port);
53 m_addr.sin_family = AF_INET;
54 m_addr.sin_addr.s_addr = INADDR_ANY;
55 if ((m_fd = ::socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
60UDPSocket::UDPSocket(
unsigned int port,
61 const std::string& hostname,
64 m_addr.sin_port = htons(port);
65 m_addr.sin_family = AF_INET;
66 if (hostname.size() > 0) {
67 struct hostent* host = NULL;
68 host = gethostbyname(hostname.c_str());
70 unsigned long addr = inet_addr(hostname.c_str());
71 if ((
signed long) addr < 0) {
72 throw (std::exception());
75 host = gethostbyaddr((
char*)&addr,
sizeof(addr), AF_INET);
78 m_addr.sin_addr.s_addr = (*(
unsigned long*) host->h_addr_list[0]);
80 if ((m_fd = ::socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
84 unsigned int addr = m_addr.sin_addr.s_addr;
85 if ((addr = findSubnet(addr)) > 0) {
86 m_addr.sin_addr.s_addr = addr;
89 setsockopt(m_fd, SOL_SOCKET, SO_BROADCAST,
90 (
char*)&yes,
sizeof(yes));
94UDPSocket::UDPSocket(
unsigned int port,
98 m_addr.sin_port = htons(port);
99 m_addr.sin_family = AF_INET;
100 m_addr.sin_addr.s_addr = addr;
101 if ((m_fd = ::socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
105 addr = m_addr.sin_addr.s_addr;
106 if ((addr = findSubnet(addr)) > 0) {
107 m_addr.sin_addr.s_addr = addr;
110 setsockopt(m_fd, SOL_SOCKET, SO_BROADCAST,
111 (
char*)&yes,
sizeof(yes));
115int UDPSocket::bind(
unsigned int port,
116 const std::string& hostname,
bool broadcast)
118 if (m_fd <= 0 && (m_fd = ::socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
121 m_addr.sin_port = htons(port);
122 if (hostname.size() > 0) {
123 struct hostent* host = NULL;
124 host = gethostbyname(hostname.c_str());
126 unsigned long addr = inet_addr(hostname.c_str());
127 if ((
signed long) addr < 0) {
128 throw (std::exception());
131 host = gethostbyaddr((
char*)&addr,
sizeof(addr), AF_INET);
134 m_addr.sin_addr.s_addr = (*(
unsigned long*) host->h_addr_list[0]);
136 unsigned int addr = m_addr.sin_addr.s_addr;
137 if ((addr = findSubnet(addr)) > 0) {
138 m_addr.sin_addr.s_addr = addr;
147 if (::bind(m_fd, (
struct sockaddr*)&m_addr,
sizeof(m_addr)) < 0) {
149 throw (
IOException(
"Failed to bind socket port=%d",
150 ntohs(m_addr.sin_port)));
155size_t UDPSocket::write(
const void* buf,
size_t count)
160 int ret = sendto(m_fd, ((
unsigned char*)buf + c),
162 (
struct sockaddr*)&m_addr,
sizeof(m_addr));
165 case EINTR:
continue;
180size_t UDPSocket::read(
void* buf,
size_t count)
183 socklen_t addrlen =
sizeof(m_remote_addr);
186 int ret = recvfrom(m_fd, ((
unsigned char*)buf + c), (count - c), 0,
187 (
struct sockaddr*)&m_remote_addr, &addrlen);
190 case EINTR:
continue;
191 case EAGAIN:
continue;
202const std::string UDPSocket::getHostName()
const
204 return inet_ntoa(m_addr.sin_addr);
207unsigned int UDPSocket::getAddress()
const
209 return m_addr.sin_addr.s_addr;
212unsigned int UDPSocket::getPort()
const
214 return ntohs(m_addr.sin_port);
217const std::string UDPSocket::getRemoteHostName()
const
219 return inet_ntoa(m_remote_addr.sin_addr);
222unsigned int UDPSocket::getRemoteAddress()
const
224 return m_remote_addr.sin_addr.s_addr;
227unsigned int UDPSocket::getRemotePort()
const
229 return ntohs(m_remote_addr.sin_port);
Abstract base class for different kinds of events.