Link to home
Start Free TrialLog in
Avatar of udayashankark
udayashankark

asked on

Problem with UDP broadcasting

> 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 )
ASKER CERTIFIED SOLUTION
Avatar of jayname
jayname

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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