?
Solved

UDP sockets (broadcasting) performance

Posted on 1997-05-05
11
Medium Priority
?
613 Views
Last Modified: 2013-12-26
Hi!

i've got a performance problem with UDP sockets:

i use broadcasting to let multiple instances of one program share
their data with all other instances in the net. (Using the same port)

It works fine as long as all the instances are running on different
machines.

But if i start two or more instances on the same machine, the
performance is dropping severely. (The programs don't use up
too much of the CPU time, so THAT isn't the reason...)

I know that there WOULD be better ways to share data if on the same
machine, but don't want to spend any effort on this special case.
It shouldn't be worse to send the data out and recieve it on the same
computer than on another machine, should it?

Thanks for your help.
0
Comment
Question by:prade
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
  • 2
11 Comments
 
LVL 1

Expert Comment

by:saji042497
ID: 1292768
Can you be a bit more specific how you manage to send broadcasts to two different ports on the same machine or run two programs that listen on the same port.
0
 
LVL 3

Expert Comment

by:dhm
ID: 1292769
Also, it might help to give the machine/OS you're using.  You say the performance "drop[s] severely."  But the program still works, right?  Have you written a pair of simple send/receive test programs?  You should try to find out whether packets are being lost (the machine sometimes can't hear its own broadcasts) or if it's just slow to process its own broadcasts.
0
 

Author Comment

by:prade
ID: 1292770
I send broadcasts to two (or more) programs on the same port.
The OS is Sun/Solaris.
The programs don't have problems to receive their own broadcasts,
but the broadcasting of another copy of the program on the same
machine. (i get mean delay times of about 0.1 seconds which is
far too much for my application. The packets ARE getting
delivered, but only with this nasty delay.)
When testing the two programs on two different machines, the
mean delay is below 0.01 sec.
0
Get MySQL database support online, now!

At Percona’s web store you can order your MySQL database support needs in minutes. No hassles, no fuss, just pick and click. Pay online with a credit card.

 

Author Comment

by:prade
ID: 1292771
Let me show you the important peace of code:
I got a class which does all socket-handling:
After calling Open(), i can use Send() and Receive()
in a loop.

her goes the code:
----------------------
class Socket {
  int socknr;                        /* Socket we will talk on             */
  struct sockaddr_in adress,adr_rcv; /* Address information                */
  int sizeof_addr;                   /* actual len. of address structure   */
  int true;
 
public:
  Socket() { true = 1; sizeof_addr = sizeof(adress); }
  void Open(int port = 15349 /* default Xraptor Port */ );
  void Send(void *buffer, size_t len);
  int Receive(void *buffer, size_t maxlen);
};

void Socket::Open(int port)
{
  true = 1; sizeof_addr = sizeof(adress);

  /* --- create socket --------------------------------------------------- */
  adress.sin_family = AF_INET;
  adress.sin_addr.s_addr = htonl(INADDR_BROADCAST);
  adress.sin_port = port;
 
  memset((char *) &adress.sin_zero, 0, sizeof(adress.sin_zero));
  memcpy((char *) &adr_rcv, (char *) &adress, sizeof_addr);

  socknr = socket(AF_INET, SOCK_DGRAM, 0);
  if (socknr < 0)
  { perror("socket"); exit(EXIT_FAILURE); }

  if(setsockopt(socknr, SOL_SOCKET, SO_REUSEADDR, (char *)&true, sizeof(true))<0)
  { perror("setsockopt"); exit(EXIT_FAILURE); }

  if (bind(socknr, (struct sockaddr *) &adress, sizeof(adress)) < 0)
  { perror("bind"); exit(EXIT_FAILURE); }

  /*  ioctl(socknr,FIONBIO,&true); /* set to nonblocking */
  if (fcntl(socknr, F_SETFL, O_NDELAY) == -1)
  { perror("fcntl"); exit(EXIT_FAILURE); }

}

void Socket::Send(void *buffer, size_t len)
{
  if (sendto(socknr, (const char *)buffer, len, 0,
             (struct sockaddr *) &adress, sizeof(adress)) < 0 )
  {
    perror("sendto");
    exit(EXIT_FAILURE);
  }
}

int Socket::Receive(void *buffer, size_t maxlen)
{
int ret;
  ret = recvfrom(socknr, (char *)buffer, maxlen, 0,
             (struct sockaddr *) &adr_rcv, &sizeof_addr);
  if (ret < 0 )
    if(errno!=EWOULDBLOCK)
    {
      perror("recvfrom");
      exit(EXIT_FAILURE);
    }
  return ret;
}


0
 
LVL 1

Accepted Solution

by:
saji042497 earned 300 total points
ID: 1292772
This is a bit of a suprise.
It is not clear how you are able to start the second incidence of the same program. This is not programatically correct. If this is going to work its behaviour could be just unpridictable.
Since you have already bound port 15349 during the first inidence, the program is bound to fail when you try to bind port 15349 during the second incidence.
The probable reason(I presume) why it is evading could be because you are using SO_REUSEADDR parameter which is ment only for testing.
You may have to device some other mechanism for your processes running on same machine to communicate to each other. Its absolutely fine as long as they are different machines.

0
 

Author Comment

by:prade
ID: 1292773
Hmm, uhmm...

I didn't find much of a documentation about that socket option
SO_REUSEADDR, but what i found didn't sound like
"for testing purpose only"...
i searched a bit more intensely after reading your answer and the
only example i found using this option is to restart a killed
daemon - so you may be right.

Can you definatly say that this option is not meant to be used in
the way i do? (Where to find DETAILED and DEFINITE information?)

And, if so - are there any other ways of multiple programs
communicating over one socket, or do i have to create an extra socket for each new instance (if on the same machine)?
I don't like the idea!

Thanks for your help,
  Prade

0
 
LVL 1

Expert Comment

by:saji042497
ID: 1292774
I guess you have valid enough reasons to start multiple instance of the programs on the same machine.
Is the solaris machine you are using a SUN or INTEL system. I might have a very complex work around.
I still recomend you to use RPC or ...




0
 

Author Comment

by:prade
ID: 1292775
Well, with RPC the netload will increase with n^2
(n beeing the number of instances of the program in the net)
With the broadcasting method, the netload only increases with n.
(Which will be a notificable difference if using 20 instances
or more of the same program in the net)

And yes, i have reasons to start multiple instances of the
same program on the same machine, this would be used to get
the maximum out of those machines that are faster than the
others (i cannot make the programs different or parametrized)

The OS is Sun/Solaris.

I would be happy to hear about your workaround...

And what do you recommend besides RPC? (the "or ..." ;-)

Is there some highlevel method which internally uses broadcasting
to lower the netload?

A lot of questions, i'll give you extra 50 points for that ;)
0
 
LVL 1

Expert Comment

by:saji042497
ID: 1292776
I can think of a work around, I am not sure if its going to work, I haven't tried it.
The le or hme driver have an option to bind multiple IP address to the interface.
You can use ifconfig and bind multiple IP addresses to le as le0:1, le0:2 etc.
Once you are through with this you can bind your listners specifically to these addresses.

netstat -a will check this binding.

I can't comment anything about the throughput you will get.

Regarding your Q on 'SO_REUSEADDR', this parameter is used during testing because, you will not be able to restart your listner(program) on the same port until around 4 minutes, this is the TTL time-out period. This period is important to reduce the probability of return of some packets ment for the old listner. To increase the productivity(I guess) of programmers this parameter has been provided.


0
 
LVL 3

Expert Comment

by:dhm
ID: 1292777
Hmmm...I've been following this thread, since I too have had network problems with Solaris (different problem, but still net-related).  I wonder if you coulnd't use multicast for this.  You'd even have the added advantage of being able to run your protocol over multiple subnets, if you can get your routers to participate in IGMP, and you don't hose up unrelated machines by  broadcasting stuff to them.  Just a thought.
0
 

Author Comment

by:prade
ID: 1292778
I will rate you excellent for the orig. question, since you
located the problem (i´d never found that out myself ;)
i had with my sample program. (damn SO_REUSEADDR)
But you didn't answer my extra questions for 50 points
(the "or ..." ;-) - i found some promising stuff in the web
myself: the PVM Project and the MPI Protocol which i will check
out these next days...)
which makes an average "good" - agreed?
Thanks for the help.
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
In this post we will learn different types of Android Layout and some basics of an Android App.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
In this video we outline the Physical Segments view of NetCrunch network monitor. By following this brief how-to video, you will be able to learn how NetCrunch visualizes your network, how granular is the information collected, as well as where to f…
Suggested Courses

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question