Onega

a lot of VC++ posts, a few C# posts, and some miscellaneous stuff

Tuesday, November 15, 2005

ACE broadcast sender and receiver

// ACE broadcast sample

// the following command run the program as server: argv[0] 1234 -s

// the following command run the program as client: argv[0] 1234 -c

#include "stdafx.h"

#include "ace/SOCK_Dgram_Bcast.h"

#include "ace/INET_Addr.h"

#include "ace/log_msg.h"

#include "ace/OS_NS_string.h"

#include "ace/OS.h"



#ifdef _DEBUG

#pragma comment(lib,"D:\\ACE\\ACE_wrappers\\lib\\aced.lib")

#else

#pragma comment(lib,"D:\ACE\ACE_wrappers\lib\ace.lib")

#endif



u_short PORT = ACE_DEFAULT_SERVER_PORT;

#define DATA_BUFFER_SIZE 1024

#define SIZE_DATA 256

class Server

{

public:

    Server(int local_port)

        :local_addr_(local_port),local_(local_addr_),data_buf(NULL)

    {

        data_buf = new char[DATA_BUFFER_SIZE];

    }

    //Expect data to arrive from the remote machine. Accept it and display

    //it. After receiving data, immediately send some data back to the

    //remote.

    int accept_data()

    {

        int byte_count=0;

        while( (byte_count=local_.recv(data_buf,SIZE_DATA,remote_addr_))!=-1)

        {

            data_buf[byte_count]=0;

            ACE_DEBUG((LM_DEBUG, "Data received from remote %s was %s \n"

                ,remote_addr_.get_host_name(), data_buf));

            ACE_OS::sleep(1);

            if(send_data()==-1) break;

        }

        return -1;

    }

    //Method used to send data to the remote using the datagram component

    //local_

    int send_data()

    {

        ACE_DEBUG((LM_DEBUG,"Preparing to send reply to client %s:%d\n",

            remote_addr_.get_host_name(),remote_addr_.get_port_number()));

        ACE_OS::sprintf(data_buf,"Server(www.fruitfruit.com) greets you");

        if( local_.send(data_buf, ACE_OS::strlen(data_buf)+1,remote_addr_)==-1)

            return -1;

        else

            return 0;

    }

private:

    char *data_buf;

    ACE_INET_Addr remote_addr_;

    ACE_INET_Addr local_addr_;

    ACE_SOCK_Dgram local_;

};

int

main (int argc,char *argv[])

{

    if(argc<3)

    {

        ACE_DEBUG((LM_DEBUG,"Usage: %s <Port Number> -s | -c\n", argv[0]));

        ACE_OS::exit(1);

    }

    PORT = ACE_OS::atoi(argv[1]);

    if( ACE_OS::strstr(argv[2],"s") || ACE_OS::strstr(argv[2], "S"))

    {

        ACE_DEBUG((LM_DEBUG,"(%P|%t) %s listens on port %d\n",argv[0], PORT));

        Server server(PORT);

        server.accept_data();

    }

    else

    {

        ACE_DEBUG((LM_DEBUG,"(%P|%t) %s broadcasts to port %d\n",argv[0], PORT));

        ACE_INET_Addr local ((u_short) 0);

        /* Instead of creating the ACE_SOCK_Dgram we created last time,

        we'll create an ACE_SOCK_Dgram_Bcast.  "Bcast" means, of course,

        "Broadcast".  This ACE object is clever enough to go out to the OS

        and find all of the network interfaces.  When you send() on a

        Dgram_Bcast, it will send the datagram out on all of those

        interfaces.  This is quiet handy if you do it on a multi-homed

        host that plays router...  */

        ACE_SOCK_Dgram_Bcast dgram;

        if (dgram.open (local) == -1)

            ACE_ERROR_RETURN ((LM_ERROR,

            "%p\n",

            "datagram open"),

            -1);

        char buf[BUFSIZ];

        sprintf (buf, "Wecome to www.fruitfruit.com!");

        /* The only other difference between us and the directed client is

        that we don't specify a host to receive the datagram.  Instead, we

        use the magic value "INADDR_BROADCAST".  All hosts are obliged to

        respond to datagrams directed to this address the same as they

        would to datagrams sent to their hostname.

        Remember, the Dgram_Bcast will send a datagram to all interfaces

        on the host.  That's true even if the address is for a specific

        host (and the host address makes sense for the interface).  The

        real power is in using an INADDR_BROADCAST addressed datagram

        against all interfaces.  */

        ACE_INET_Addr remote (PORT,INADDR_BROADCAST);

        ACE_DEBUG ((LM_DEBUG,

            "(%P|%t) Sending (%s) to the server.\n",

            buf));

        if (dgram.send (buf,

            ACE_OS::strlen (buf) + 1,

            remote) == -1)

            ACE_ERROR_RETURN ((LM_ERROR,

            "%p\n",

            "send"),

            -1);

        if (dgram.recv (buf,

            sizeof (buf),

            remote) == -1)

            ACE_ERROR_RETURN ((LM_ERROR,

            "%p\n",

            "recv"),

            -1);

        ACE_DEBUG ((LM_DEBUG,

            "(%P|%t) The server said:  %s\n",

            buf));

        /* Using the "remote" object instance, find out where the server

        lives.  We could then save this address and use directed datagrams

        to chat with the server for a while.  */

        ACE_DEBUG ((LM_DEBUG,

            "(%P|%t) The server can be found at:  (%s:%d)\n",

            remote.get_host_name(),

            PORT));

    }

    ACE_DEBUG((LM_DEBUG,"(%P|%t) %s end\n",argv[0]));

    return 0;

}

0 Comments:

Post a Comment

<< Home