LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-06-2009, 11:54 PM   #1
vigneshinbox
LQ Newbie
 
Registered: Mar 2009
Posts: 19

Rep: Reputation: 0
Exclamation How to broadcast a message ?


My problem definition is ,I have to send a message from one node in a network and it has to be broadcasted to all other nodes in the network.The program what I have given below will be running in all the nodes in the network.The same program should be capable of sending(broadcasting) and receiving. (i.e, there is no separate program for server and client like a chat program).I have written a code but I am not clear with how it has to be done.Kindly help me in this.


Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
void sigchld_handler(int s)
{
    while (waitpid(-1, NULL, WNOHANG) > 0);
}
void *get_in_addr(struct sockaddr *sa)
{
    if (sa->sa_family == AF_INET) {
	return &(((struct sockaddr_in *) sa)->sin_addr);
    }
    return &(((struct sockaddr_in6 *) sa)->sin6_addr);
}

char pass[100];
char pass1[100];

int main()
{
    int sockfd, new_fd, numbytes;
    struct addrinfo hints, *servinfo, *p;
    struct sockaddr_storage their_addr;
    socklen_t sin_size;
    socklen_t *size;
    struct sockaddr *names;
    int yes = 1, len = 0;
    struct sigaction sa;
    char s[INET6_ADDRSTRLEN], s1[INET6_ADDRSTRLEN];
    char name[20];
    int rv;
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;
    if ((rv = getaddrinfo(NULL, "2001", &hints, &servinfo)) == -1) {
	fprintf(stderr, "getaddrinfo:%s", gai_strerror(rv));
	return 1;
    }
    printf("\n \n getaddrinfo:%d", rv);
    printf("\n------------------------------");
    for (p = servinfo; p != NULL; p = p->ai_next) {

	if ((sockfd =
	     socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
	    perror("server:socket");
	    continue;
	}
	printf("\n server socket launched...");

	if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &yes, sizeof(int))
	    == -1) {
	    perror("setsockopt");
	    return 0;
	}
	printf("\n server setsocket option ...");

	if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {

	    close(sockfd);
	    perror("server:bind");
	    continue;
	}
	printf("\n socket binded....");
	break;
    }


    if (p == NULL) {
	fprintf(stderr, "server:failed");
	return 2;
    }
    if (listen(sockfd, 10) == -1) {
	perror("listen");
	return 0;
    }
    sa.sa_handler = sigchld_handler;
    sa.sa_flags = SA_RESTART;
    if (sigaction(SIGCHLD, &sa, NULL) == -1) {
	perror("sigaction");
	exit(0);
    }
    printf("\n\nlisten to socket :%d", sockfd);

    while (1) {
	sin_size = sizeof their_addr;
	new_fd =
	    accept(sockfd, (struct sockaddr *) &their_addr, &sin_size);
	printf("\n sockfd=%d new_fd=%d", sockfd, new_fd);
	if (new_fd == -1) {
	    perror("accept");
	    continue;
	}
	if ((rv = getpeername(new_fd, names, &sin_size)) == -1)
	    perror("r");
	inet_ntop(their_addr.ss_family, names, s1, sizeof s1);
	printf("\n Peer name:%s", s);
	inet_ntop(their_addr.ss_family,
		  get_in_addr((struct sockaddr *) &their_addr), s,
		  sizeof s);
	printf("\n\nserver:connected %s", s);
	if (!fork()) {
	    while (1) {

		len = strlen("CAN_U");

		if ((send(new_fd, "CAN_U", len + 1, 0)) == -1)
		    perror("error");
		if ((strcmp(pass, "bye")) == 0) {
		    close(new_fd);
		    break;
		}
		pass[0] = '\0';
		if (recv(new_fd, name, sizeof name, 0) == -1)
		    perror("error");
		if ((strcmp("CAN_U", name)) == 0) {
		    if (send(sockfd, "YES", strlen("YES"), 0) == -1)
			perror("error5");
		    printf("\nSuccess");


		}

	    }
	    close(new_fd);

	}
	close(new_fd);
    }
    return 0;
}
I want a single program which will be running in all the nodes in a network(cluster).The program should act as server at broadcasting node and as a client at the receiving node.
 
Old 04-08-2009, 09:19 AM   #2
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
It sure would be nice if you would clean up your code. You do know that functions can be created to modularize the code?

As for your code, once again, I do not see how a client on a remote node (host) can connect to this application. Your server has bound its port to 127.0.0.1. This address is not reachable by a remote client application.

You should spend some time getting the fundamentals down before attempting to develop a full-blown application.

For the server:
1. create the socket
2. bind the socket
3. listen on the socket
4. accept client connections

For the client:
1. create the socket
2. connect to the server

I recommend that you write these in two separate files, but if you rather deal with clutter, then place them both in the same file.

Here's a basic server (note, no send/receive is involved):
Code:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>

#include <stdio.h>

int FillAddress(int domain, const char* address, unsigned short port, struct sockaddr_in* sin);


int main(int argc, char** argv)
{
  const char* host = (argc > 1 ? argv[1] : "127.0.0.1");

  int sd = socket(AF_INET, SOCK_STREAM, 0);
  assert(sd > 0);

  struct sockaddr_in sin;

  int rtn = FillAddress(AF_INET, host, 8000, &sin);
  assert(rtn == 0);

  rtn = bind(sd, (struct sockaddr*) &sin, sizeof(sin));
  assert(rtn == 0);

  rtn = listen(sd, 5);
  assert(rtn == 0);

  for (;;)
  {
    int client_sd = accept(sd, 0, 0);

    printf("client connected.\n");

    // handle_client(client_sd);

    close(client_sd);
  }

  close(sd);

  return 0;
}

int FillAddress(int domain, const char* address, unsigned short port, struct sockaddr_in* sin)
{
  if (address == 0)
  {
    memset(sin, 0, sizeof(struct sockaddr_in));

    sin->sin_family      = domain;
    sin->sin_addr.s_addr = htonl(INADDR_ANY);
    sin->sin_port        = htons(port);
  }
  else
  {
    struct addrinfo hints;

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = domain;

    struct addrinfo* host_info = 0;

    if (getaddrinfo(address, 0, &hints, &host_info) != 0  ||
        !host_info || !host_info->ai_addr || host_info->ai_family != domain)
    {
      if (host_info) freeaddrinfo(host_info);
      return -1;
    }

    memcpy(sin, host_info->ai_addr, sizeof(struct sockaddr_in));
    sin->sin_port = htons(port);

    freeaddrinfo(host_info);
  }
  return 0;
}
A typical client (once again, no send/receive):
Code:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <errno.h>

#include <stdio.h>

int FillAddress(int domain, const char* address, unsigned short port, struct sockaddr_in* sin);


int main(int argc, char** argv)
{
  const char* host = (argc > 1 ? argv[1] : "127.0.0.1");

  int sd = socket(AF_INET, SOCK_STREAM, 0);
  assert(sd > 0);

  struct sockaddr_in sin;

  int rtn = FillAddress(AF_INET, host, 8000, &sin);
  assert(rtn == 0);

  if (connect(sd, (struct sockaddr*) &sin, sizeof(sin)) != 0)
  {
    printf("Failed to connect.  Reason = %s\n", strerror(errno));
    return 1;
  }

  printf("Connected!\n");

  close(sd);

  return 0;
}

int FillAddress(int domain, const char* address, unsigned short port, struct sockaddr_in* sin)
{
  if (address == 0)
  {
    memset(sin, 0, sizeof(struct sockaddr_in));

    sin->sin_family      = domain;
    sin->sin_addr.s_addr = htonl(INADDR_ANY);
    sin->sin_port        = htons(port);
  }
  else
  {
    struct addrinfo hints;

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = domain;

    struct addrinfo* host_info = 0;

    if (getaddrinfo(address, 0, &hints, &host_info) != 0  ||
        !host_info || !host_info->ai_addr || host_info->ai_family != domain)
    {
      if (host_info) freeaddrinfo(host_info);
      return -1;
    }

    memcpy(sin, host_info->ai_addr, sizeof(struct sockaddr_in));
    sin->sin_port = htons(port);

    freeaddrinfo(host_info);
  }
  return 0;
}
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Broadcast a message Fredde87 Linux - Networking 2 04-14-2008 03:51 AM
any broadcast message tool venki Linux - Networking 2 06-28-2007 01:29 AM
How to broadcast text message toraghun Red Hat 3 03-03-2006 01:13 AM
broadcast message to all santosh_rao99 Linux - Networking 2 07-28-2004 11:41 PM
How do I broadcast a message? miknight Linux - General 3 04-26-2003 01:24 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:47 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration