1 #include "daq/slc/system/UDPSocket.h"
3 #include <daq/slc/base/IOException.h>
11 #include <sys/socket.h>
12 #include <netinet/in.h>
14 #include <arpa/inet.h>
19 unsigned int UDPSocket::findSubnet(
unsigned int addr)
21 struct ifaddrs* ifa_list;
23 char addrstr[256], netmaskstr[256];
24 if (getifaddrs(&ifa_list) != 0)
return 0;
25 for (ifa = ifa_list; ifa != NULL; ifa = ifa->ifa_next) {
26 memset(addrstr, 0,
sizeof(addrstr));
27 memset(netmaskstr, 0,
sizeof(netmaskstr));
28 if (ifa->ifa_addr->sa_family == AF_INET &&
29 addr == ((
struct sockaddr_in*)ifa->ifa_addr)->sin_addr.s_addr) {
30 addr |= ~(((
struct sockaddr_in*)ifa->ifa_netmask)->sin_addr.s_addr);
33 freeifaddrs(ifa_list);
37 UDPSocket::UDPSocket()
39 m_addr.sin_family = AF_INET;
40 m_addr.sin_addr.s_addr = INADDR_ANY;
43 UDPSocket::UDPSocket(
unsigned int port)
45 m_addr.sin_port = htons(port);
46 m_addr.sin_family = AF_INET;
47 m_addr.sin_addr.s_addr = INADDR_ANY;
48 if ((m_fd = ::socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
53 UDPSocket::UDPSocket(
unsigned int port,
54 const std::string& hostname,
57 m_addr.sin_port = htons(port);
58 m_addr.sin_family = AF_INET;
59 if (hostname.size() > 0) {
60 struct hostent* host = NULL;
61 host = gethostbyname(hostname.c_str());
63 unsigned long addr = inet_addr(hostname.c_str());
64 if ((
signed long) addr < 0) {
65 throw (std::exception());
68 host = gethostbyaddr((
char*)&addr,
sizeof(addr), AF_INET);
71 m_addr.sin_addr.s_addr = (*(
unsigned long*) host->h_addr_list[0]);
73 if ((m_fd = ::socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
77 unsigned int addr = m_addr.sin_addr.s_addr;
78 if ((addr = findSubnet(addr)) > 0) {
79 m_addr.sin_addr.s_addr = addr;
82 setsockopt(m_fd, SOL_SOCKET, SO_BROADCAST,
83 (
char*)&yes,
sizeof(yes));
87 UDPSocket::UDPSocket(
unsigned int port,
91 m_addr.sin_port = htons(port);
92 m_addr.sin_family = AF_INET;
93 m_addr.sin_addr.s_addr = addr;
94 if ((m_fd = ::socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
98 addr = m_addr.sin_addr.s_addr;
99 if ((addr = findSubnet(addr)) > 0) {
100 m_addr.sin_addr.s_addr = addr;
103 setsockopt(m_fd, SOL_SOCKET, SO_BROADCAST,
104 (
char*)&yes,
sizeof(yes));
108 int UDPSocket::bind(
unsigned int port,
109 const std::string& hostname,
bool broadcast)
111 if (m_fd <= 0 && (m_fd = ::socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
114 m_addr.sin_port = htons(port);
115 if (hostname.size() > 0) {
116 struct hostent* host = NULL;
117 host = gethostbyname(hostname.c_str());
119 unsigned long addr = inet_addr(hostname.c_str());
120 if ((
signed long) addr < 0) {
121 throw (std::exception());
124 host = gethostbyaddr((
char*)&addr,
sizeof(addr), AF_INET);
127 m_addr.sin_addr.s_addr = (*(
unsigned long*) host->h_addr_list[0]);
129 unsigned int addr = m_addr.sin_addr.s_addr;
130 if ((addr = findSubnet(addr)) > 0) {
131 m_addr.sin_addr.s_addr = addr;
138 int UDPSocket::bind()
140 if (::bind(m_fd, (
struct sockaddr*)&m_addr,
sizeof(m_addr)) < 0) {
142 throw (
IOException(
"Failed to bind socket port=%d",
143 ntohs(m_addr.sin_port)));
148 size_t UDPSocket::write(
const void* buf,
size_t count)
154 ret = sendto(m_fd, ((
unsigned char*)buf + c),
156 (
struct sockaddr*)&m_addr,
sizeof(m_addr));
159 case EINTR:
continue;
174 size_t UDPSocket::read(
void* buf,
size_t count)
178 socklen_t addrlen =
sizeof(m_remote_addr);
181 ret = recvfrom(m_fd, ((
unsigned char*)buf + c), (count - c), 0,
182 (
struct sockaddr*)&m_remote_addr, &addrlen);
185 case EINTR:
continue;
186 case EAGAIN:
continue;
197 const std::string UDPSocket::getHostName()
const
199 return inet_ntoa(m_addr.sin_addr);
202 unsigned int UDPSocket::getAddress()
const
204 return m_addr.sin_addr.s_addr;
207 unsigned int UDPSocket::getPort()
const
209 return ntohs(m_addr.sin_port);
212 const std::string UDPSocket::getRemoteHostName()
const
214 return inet_ntoa(m_remote_addr.sin_addr);
217 unsigned int UDPSocket::getRemoteAddress()
const
219 return m_remote_addr.sin_addr.s_addr;
222 unsigned int UDPSocket::getRemotePort()
const
224 return ntohs(m_remote_addr.sin_port);