UDP sockets (broadcasting) performance


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

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.
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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.
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.
pradeAuthor Commented:
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.
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

pradeAuthor Commented:
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;
  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 )

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 )
  return ret;

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.


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
pradeAuthor Commented:
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,

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 ...

pradeAuthor Commented:
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 ;)
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.

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.
pradeAuthor Commented:
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.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.