Problem with UDP broadcasting

udayashankark
udayashankark used Ask the Experts™
on
> I'm a Linux newbie. I need to code a client-server collision detection and centralized multiplayer control project demo.

  I've written a small program to test broadcasting.

//=======================================================

#include <unistd.h>
#include <sys/socket.h>
#include <sys/time.h>

#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#include <sys/param.h>
#include <sys/ioctl.h>

#include <sys/uio.h>
#include <errno.h>

//======================

#include <iostream.h>
#include <memory.h>
#include <stdlib.h>

//======================

#define  CLIENT_PORT      27001
#define  SERVER_PORT      27010

#define  NET_MAX_MSGLEN   1024

int      g_sock;
char     buffer[ NET_MAX_MSGLEN ];

char     testmsg[] = "This is to test";

//==========================================

int OpenUDPSocket( const char *interface, int port )
{
    int             nsock, i = 1;
    unsigned char   strue = 1;

    sockaddr_in     address;

    // Open UDP socket
    if( ( nsock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) == -1 )
    {
        cout<< "Error: socket( ) failed."<< endl;
        return 0;
    }

    ///* make it non blocking
    if( ioctl( nsock, FIONBIO, &strue ) == -1 )
    {
          cout<< "Error: make non-block failed."<< endl;
          close( nsock );
          return 0;
    }//*/

    // /* make it broadcast capable
    if( setsockopt( nsock, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof( int ) ) == -1 )
    {
          cout<< "Error: make bcast failed" << endl;
          close( nsock );
          return 0;
    } //*/

    address.sin_family = AF_INET;

    memset( &address, 0, sizeof( sockaddr_in ) );

    if( port == -1 )
        port = 0;
    else
        address.sin_port = htons( port );

    if( !interface )
        address.sin_addr.s_addr = INADDR_ANY;
    else
    {
        if( inet_pton( AF_INET, interface, &address.sin_addr ) != 1 )
        {
           cout<< "Bad address specified";
           close( nsock );
           return 0;
        }
    }

    // bind to specified port, so it can receive broadcast
    if( bind( nsock, (const sockaddr *)&address, sizeof(address) ) == -1 )
    {
        cout<< "Error: bind failed" <<endl;
        close( nsock );
        return 0;
    }

    cout<< "...socket initialized" <<endl;
    return nsock;
}

int ClientMain( int argc, char *argv[ ] )
{
    int           scode;
    sockaddr_in   addr;

    //NB: argv[ 1 ]
    g_sock = OpenUDPSocket( argv[ 1 ], CLIENT_PORT );
    if( !g_sock )
    {
        cout<<" OpenUDPSocket failed "<<endl;
        return -1;
    }

    addr.sin_family = AF_INET;
    addr.sin_port   = htons( SERVER_PORT );

    *( int *)&addr.sin_addr.s_addr = -1;

    errno = 0;

    scode = sendto( g_sock, testmsg, sizeof(testmsg), 0, (sockaddr *)&addr, sizeof( addr ) );
    if( scode == -1 )
    {
        cout<<" Sendto failed: errno = "<< strerror( errno ) <<endl;
        return -1;
    }
    else
        cout<<" Sent "<< scode <<" number of bytes";

    close( g_sock );
    return 0;
}

int ServerMain( int argc, char *argv[] )
{
    g_sock = OpenUDPSocket( argv[ 2 ], SERVER_PORT );
    if( !g_sock )
    {
        cout<<" OpenUDPSocket failed "<<endl;
        return -1;
    }

    sockaddr_in from;
    socklen_t   fromlen;

    int   ret = -1;
    int   err;

    while( ret == -1 )
    {
        fromlen = sizeof( from );

        memset( &from, 0, sizeof( from ) );
        ret     = recvfrom( g_sock, buffer , NET_MAX_MSGLEN,  0, (struct sockaddr *)&from, &fromlen );
        if( ret == -1 )
        {
          err = errno;

          if( err == EWOULDBLOCK || err == ECONNREFUSED )
              continue;
        }
        else if( ret >= NET_MAX_MSGLEN )
        {
            cout<< "Oversize packet "<<endl;
            break;
        }
        else
        {
            buffer[ ret ] = 0;
            break;
        }
  }

  //just to be sure...
  buffer[ NET_MAX_MSGLEN -1 ] = 0;

  if( ret != -1 )
  {
      cout<< "Msg recv: "<< buffer << endl;
  }

  close( g_sock );
  return 0;
}

int main( int argc, char *argv[ ] )
{
  if( argc == 2 )
      return ClientMain( argc, argv );
  else
  {

      if( argc != 3 )
      {
          cerr<<" Usage: testbc <mode> <ip addr> "<<endl;
          return EXIT_FAILURE;
      }

      return ServerMain( argc, argv );
  }
}

//======================================================

( my comp's eth0 ip addr ) = 100.100.100.102

to run the ServerMain codepath I give,

$> ./a.out server 100.100.100.102 & 

then I start the client,

$> ./a.out 100.100.100.102 &

the client prints "sent 16 number of bytes".
but the server never print's any thing and loops foreever
( you need to give ps -a and kill it )

Question: Why is this happening??
why client broadcasts the packet ok, but server dosen't receive it.

Is it a system configuration problem??

I configured my network using "netconfig".

Thanks in advance
Uday ( ud-ay )
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Commented:
the code looks ok.... check if the ports are not blocked.
/sbin/chkconfig --del ipchains
/sbin/chkconfig --del iptalbles.
By default ports might be blocked hence the server is not able to get the data packets.... UDP just sends the packet and will not wait for the ack from the server.
No comment has been added lately, so it's time to clean up this TA.
I will leave the following recommendation for this question in the Cleanup topic area:

Accept: jayname {http:#7637267}

Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

jmcg
EE Cleanup Volunteer

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial