Solved

UDP sockets (broadcasting) performance

Posted on 1997-05-05
11
595 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
  • 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
 

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 150 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
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 

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

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Perl Awk Need Help 3 94
sum67 challenge 35 89
mapBully challenge 6 92
Trying to run powershell  in a batch file. How do I do this? 8 47
Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
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.
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

747 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now