For Programmers: Free Programming Magazines  


Home > Archive > Unix Programming > September 2006 > UDP broadcasting reply









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author UDP broadcasting reply
Henrik Goldman

2006-09-09, 7:01 pm

Hi,

I am in progress of creating a UDP broadcasting client and server for the
purpose of doing automatic server discovery. The idea is that a client can
do a "ping" on the network and find out where servers are located in order
to switch to another protocol for the actual communication.

The udp server works fine and accepts request from clients which it answers
to. However the client is a bit fishy.

What I am unsure about is if it's possible to receive udp replies on the
socket which was used for the broadcasting?

Here is a non-working example (it uses a few macros for simplicity reasons):

if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)

{

printf("Cannot open socket\n");

return false;

}

setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *) &bEnable, sizeof(bEnable));


if (sendto(s, szMsg, strlen(szMsg)+1, 0, (struct sockaddr *) &ServAddr,
sizeof(ServAddr)) == SOCKET_ERROR)

{

printf("Cannot send request\n");

return false;

}

int nLen = sizeof(ServAddrResp);

if (recvfrom(s, szRecv, 5, 0, (struct sockaddr *) &ServAddrResp, &nLen) ==
SOCKET_ERROR)

{

printf("Cannot send request %d\n", WSAGetLastError());

return false;

}

closesocket(s);



The broadcast with sendto() works fine and the server recvfrom's the
request. The server then tries to send a reply back on the client addr and
port but the client gets an error or stalls at recvfrom.

A (sortof) working example is to setup another "listen server" at the client
side but then it needs to reside on a fixed port and it doesn't work all the
time either. E.g. on my current laptop I have a vmware network adaptor which
accepts the request and throws it away it seems.

I did not find any better examples through google so perhaps someone here
can shed some light on how to perform this?

Thanks.

-- Henrik


Barry Margolin

2006-09-09, 7:01 pm

In article <4502cdff$0$13950$edfadb0f@dread15.news.tele.dk>,
"Henrik Goldman" <henrik_goldman@mail.tele.dk> wrote:

> Hi,
>
> I am in progress of creating a UDP broadcasting client and server for the
> purpose of doing automatic server discovery. The idea is that a client can
> do a "ping" on the network and find out where servers are located in order
> to switch to another protocol for the actual communication.
>
> The udp server works fine and accepts request from clients which it answers
> to. However the client is a bit fishy.
>
> What I am unsure about is if it's possible to receive udp replies on the
> socket which was used for the broadcasting?


The client has to bind the socket to a local port. Then it will be able
to read the replies sent back to that port.

If you don't bind the socket, then sendto() binds it *temporarily*. But
by the time sendto() has returned, the socket will have been unbound
again. So it can't be used to read incoming packets.

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
Henrik Goldman

2006-09-10, 8:01 am

> The client has to bind the socket to a local port. Then it will be able
> to read the replies sent back to that port.


Thanks for the suggestion.

Does this mean that I have to have a local server running on the client side
as well?

> If you don't bind the socket, then sendto() binds it *temporarily*. But
> by the time sendto() has returned, the socket will have been unbound
> again. So it can't be used to read incoming packets.


That makes sense. So now I made a new test where the client port is bound to
7000 and the server sends back the reply at port 7000 as it should. However
the client hangs in recvfrom() which is mysterious.

Perhaps you can see what goes on: (the actual code has only been tested on
Windows but it doesn't matter since it should work platform independently):

if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
{
printf("Cannot open socket\n");
return false;
}

ServAddr2.sin_family = AF_INET;
ServAddr2.sin_addr.s_addr = htonl(INADDR_ANY);
ServAddr2.sin_port = htons(7000);

if (bind(s, (struct sockaddr *) &ServAddr2, sizeof(ServAddr2)) ==
SOCKET_ERROR)
{
printf("Cannot bind port %d %d\n", nPort, WSAGetLastError());
return false;
}

setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *) &bEnable,
sizeof(bEnable));

if (sendto(s, szMsg, strlen(szMsg)+1, 0, (struct sockaddr *) &ServAddr,
sizeof(ServAddr)) == SOCKET_ERROR)
{
printf("Cannot send request\n");
return false;
}

int nLen = sizeof(ServAddrResp);
if (recvfrom(s, szRecv, 5, 0, (struct sockaddr *) &ServAddrResp, &nLen) ==
SOCKET_ERROR)
{
printf("Cannot send request %d\n", WSAGetLastError());
return false;
}


Everything seems to be fine but at the very end it just hangs.
Perhaps you can explain why? The other idea is to have a local server in
another thread which just binds at the same port but I did not find that
working in all cases.

Thanks.
-- Henrik


Barry Margolin

2006-09-10, 7:01 pm

In article <450414c0$0$14011$edfadb0f@dread15.news.tele.dk>,
"Henrik Goldman" <henrik_goldman@mail.tele.dk> wrote:

>
> Thanks for the suggestion.
>
> Does this mean that I have to have a local server running on the client side
> as well?


No. A server is a process that listens for unsolicited incoming
messages on a well-known port (or a port advertised through a broker,
like portmapper). The client is just listening for responses to the
packets it sent.

>
>
> That makes sense. So now I made a new test where the client port is bound to
> 7000 and the server sends back the reply at port 7000 as it should. However
> the client hangs in recvfrom() which is mysterious.


There's no need to hard-code the port. Call bind() with port set to 0,
and the stack will select an unused port.

>
> Perhaps you can see what goes on: (the actual code has only been tested on
> Windows but it doesn't matter since it should work platform independently):
>
> if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
> {
> printf("Cannot open socket\n");
> return false;
> }
>
> ServAddr2.sin_family = AF_INET;
> ServAddr2.sin_addr.s_addr = htonl(INADDR_ANY);
> ServAddr2.sin_port = htons(7000);
>
> if (bind(s, (struct sockaddr *) &ServAddr2, sizeof(ServAddr2)) ==
> SOCKET_ERROR)
> {
> printf("Cannot bind port %d %d\n", nPort, WSAGetLastError());
> return false;
> }
>
> setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *) &bEnable,
> sizeof(bEnable));
>
> if (sendto(s, szMsg, strlen(szMsg)+1, 0, (struct sockaddr *) &ServAddr,
> sizeof(ServAddr)) == SOCKET_ERROR)
> {
> printf("Cannot send request\n");
> return false;
> }
>
> int nLen = sizeof(ServAddrResp);
> if (recvfrom(s, szRecv, 5, 0, (struct sockaddr *) &ServAddrResp, &nLen) ==
> SOCKET_ERROR)
> {
> printf("Cannot send request %d\n", WSAGetLastError());
> return false;
> }
>
>
> Everything seems to be fine but at the very end it just hangs.
> Perhaps you can explain why? The other idea is to have a local server in
> another thread which just binds at the same port but I did not find that
> working in all cases.


Run tcpdump or Wireshark and make sure the replies are coming back to
you properly.

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
Henrik Goldman

2006-09-11, 4:01 am


> Run tcpdump or Wireshark and make sure the replies are coming back to
> you properly.
>


Actually the code was fine. The problem was the sorrounding environment.
Both my vmware network adapters and VPN connection were able to cause
distortion. The result was that the ip address sent to the server was the
address the one from either devices but not the real one.
I don't know what can be done about this if anything.
Would it be possible to get the packages to get sent through the right ip?
The good question is which one is the right address though. Right and wrong
all depends on the network connected to and who you want to communicate to.

Thanks.

-- Henrik


Barry Margolin

2006-09-11, 7:00 pm

In article <4504fb65$0$20229$edfadb0f@dread16.news.tele.dk>,
"Henrik Goldman" <henrik_goldman@mail.tele.dk> wrote:

>
> Actually the code was fine. The problem was the sorrounding environment.
> Both my vmware network adapters and VPN connection were able to cause
> distortion. The result was that the ip address sent to the server was the
> address the one from either devices but not the real one.
> I don't know what can be done about this if anything.
> Would it be possible to get the packages to get sent through the right ip?
> The good question is which one is the right address though. Right and wrong
> all depends on the network connected to and who you want to communicate to.


If you specify an IP address instead of IPADDR_ANY in the call to
bind(), that will be the source address in the packets.

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com