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