#include
<sys/socket.h>
#include
<netinet/in.h>
#include
<arpa/inet.h>
#include
<net/if.h>
#include
<ifaddrs.h>
#include
<string.h>
#include
<stdio.h>
#include
<errno.h>
#define
kPortNumber 1234
#define
kBufferSize 1024
#define
kMaxSockets 16
int
transmit(char * data, int length) {
int sock_fds[kMaxSockets];
struct ifaddrs *addrs;
if ( getifaddrs(&addrs) < 0 ) {
// Error occurred
return 0;
}
// Loop through interfaces, selecting those
AF_INET devices that support broadcast, but aren't loopback or point-to-point
const struct ifaddrs *cursor = addrs;
struct sockaddr_in addr;
int number_sockets = 0;
while ( cursor != NULL && number_sockets
< kMaxSockets ) {
if ( cursor->ifa_addr->sa_family ==
AF_INET
&& !(cursor->ifa_flags
& IFF_LOOPBACK)
&& !(cursor->ifa_flags
& IFF_POINTOPOINT)
&& (cursor->ifa_flags & IFF_BROADCAST) )
{
// Create socket
sock_fds[number_sockets] =
socket(AF_INET, SOCK_DGRAM, 0);
if ( sock_fds[number_sockets] == -1 ) {
// Error occurred
return 0;
}
// Create address from which we want to
send, and bind it
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr = ((struct sockaddr_in
*)cursor->ifa_addr)->sin_addr;
addr.sin_port = 0;
if ( bind(sock_fds[number_sockets],
(struct sockaddr*)&addr, sizeof(addr)) < 0 ) {
// Error occurred
return 0;
}
// Enable broadcast
int flag = 1;
if ( setsockopt(sock_fds[number_sockets],
SOL_SOCKET, SO_BROADCAST, &flag, sizeof(flag)) != 0 ) {
// Error occurred
return 0;
}
number_sockets++;
}
cursor = cursor->ifa_next;
}
// Initialise broadcast address
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_BROADCAST;
addr.sin_port = htons(kPortNumber);
// Send through each interface
int i;
for ( i=0; i<number_sockets; i++ ) {
if ( sendto(sock_fds[i], data, length, 0,
(struct sockaddr*)&addr, sizeof(addr)) < 0 ) {
// Error occurred
return 0;
}
}
return 1;
}
int
receive() {
// Create socket
int sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
if ( sock_fd == -1 ) {
// Error occurred
return 0;
}
// Create address from which we want to
receive, and bind it
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(kPortNumber);
if ( bind(sock_fd, (struct
sockaddr*)&addr, sizeof(addr)) < 0 ) {
// Error occurred
return 0;
}
char buffer[kBufferSize];
int addr_len = sizeof(addr);
while ( 1 ) {
// Receive a message, waiting if there's
nothing there yet
int bytes_received = recvfrom(sock_fd,
buffer, kBufferSize, 0, (struct sockaddr*)&addr, &addr_len);
if ( bytes_received < 0 ) {
// Error occurred
return 0;
}
// Now we have bytes_received bytes of data
in buffer. Print it!
fwrite(buffer, sizeof(char),
bytes_received, stdout);
printf("\n");
}
}
int
main(int argc, char** argv) {
if ( argc < 2 ) {
// No argument: Just listen
printf("Listening...\n");
if ( !receive() ) {
printf("Error occurred: %s\n",
strerror(errno));
return 1;
}
return 0;
}
// Argument provided: Transmit this
if ( transmit(argv[1], strlen(argv[1])) ) {
printf("\"%s\"
transmitted.\n", argv[1]);
} else {
printf("Error occurred: %s\n",
strerror(errno));
return 1;
}
return 0;
}
No comments:
Post a Comment
Have some problem with this code? or Request the code you want if you cant find it in Blog Archive.