datagram_broadcast.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <netcomm/socket/datagram_broadcast.h>
00026
00027 #include <sys/socket.h>
00028 #include <netinet/in.h>
00029 #include <arpa/inet.h>
00030 #include <cstdlib>
00031 #include <cstring>
00032 #include <cerrno>
00033
00034 namespace fawkes {
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 BroadcastDatagramSocket::BroadcastDatagramSocket(const char *broadcast_addr_s,
00052 unsigned short port,
00053 float timeout)
00054 : Socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP, timeout)
00055 {
00056 broadcast_addr = (struct ::sockaddr_in *)malloc(sizeof(struct ::sockaddr_in));
00057
00058 struct in_addr a;
00059 if ( inet_aton(broadcast_addr_s, &a) == -1 ) {
00060 throw SocketException("Invalid address given");
00061 }
00062 broadcast_addr->sin_family = AF_INET;
00063 broadcast_addr->sin_addr.s_addr = a.s_addr;
00064 broadcast_addr->sin_port = htons(port);
00065
00066 #if 0
00067
00068 set_loop(false);
00069 #endif
00070 }
00071
00072
00073
00074 BroadcastDatagramSocket::~BroadcastDatagramSocket()
00075 {
00076 free(broadcast_addr);
00077 }
00078
00079
00080
00081
00082
00083 BroadcastDatagramSocket::BroadcastDatagramSocket(BroadcastDatagramSocket &datagram_socket)
00084 : Socket(datagram_socket)
00085 {
00086 broadcast_addr = (struct ::sockaddr_in *)malloc(sizeof(struct ::sockaddr_in));
00087 memcpy(broadcast_addr, datagram_socket.broadcast_addr, sizeof(struct ::sockaddr_in));
00088 }
00089
00090
00091
00092
00093
00094 void
00095 BroadcastDatagramSocket::bind()
00096 {
00097 int broadcast = 1;
00098 if ( setsockopt(sock_fd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) == -1) {
00099 throw SocketException("Could not set SO_BROADCAST", errno);
00100 }
00101
00102 int reuse = 1;
00103 if ( setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1) {
00104 throw SocketException("Could not set SO_REUSEADDR", errno);
00105 }
00106
00107 struct ::sockaddr_in local;
00108 local.sin_family = AF_INET;
00109 local.sin_addr.s_addr = INADDR_ANY;
00110 local.sin_port = broadcast_addr->sin_port;
00111
00112 if (::bind(sock_fd, (struct ::sockaddr *) &local, sizeof(local)) < 0) {
00113 throw SocketException("Could not bind to port", errno);
00114 }
00115 }
00116
00117
00118
00119
00120
00121 Socket *
00122 BroadcastDatagramSocket::clone()
00123 {
00124 return new BroadcastDatagramSocket(*this);
00125 }
00126
00127
00128
00129
00130
00131
00132
00133
00134 void
00135 BroadcastDatagramSocket::send(void *buf, unsigned int buf_len)
00136 {
00137 try {
00138 Socket::send(buf, buf_len, (struct ::sockaddr *)broadcast_addr, sizeof(struct ::sockaddr_in));
00139 } catch (SocketException &e) {
00140 e.append("BroadcastDatagramSocket::send(void*, unsigned int) failed");
00141 throw;
00142 }
00143 }
00144
00145 }