473,378 Members | 1,493 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

Finding server with broadcast

I need some code that gets the address from a server. I read somewhere
that you could do this by starting some broadcast server using UDP. The
client should send an broadcast message, and when the server answering
the client gets the address. But how do I implement this?

I did this simple quick-hack:

Server:
Socket server = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp);
server.Bind( new IPEndPoint( IPAddress.Any, 48000 ) );

while(true)
{
byte[] buffer = new byte[1000];
server.Receive(buffer);

Console.Write("Server got: " + buffer[0]);
//Next line crash cause some permission error.
server.SendTo( new byte[] {2},
new IPEndPoint( IPAddress.Broadcast, 48000 ) );
}

Client:
Socket client = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp);
client.Connect(new IPEndPoint( IPAddress.Broadcast, 48000 ));

Console.Write("Client send: 1");
client.Send( new byte[] {1} );

byte[] buffer = new byte[1000];
client.Receive(buffer);
Console.Write("Client got: " + buffer[0]);

client.Close();

To my surprise the code almost worked :-). The server receive the
message from the client, but it fails when sending data. And even if it
did it doesn't help the client cause will not know who send the
message.

I'm thankful for any ideas. What I'm looking for is a way to find the
address of a server. It doesn't need to be perfect, it will just give
the users a hint which address to use for the real application.

Nov 17 '05 #1
6 10271
pe*****@home.se wrote:
I did this simple quick-hack:
see below
Server:
Socket server = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp);
server.Bind( new IPEndPoint( IPAddress.Any, 48000 ) );

while(true)
{
byte[] buffer = new byte[1000];
server.Receive(buffer);
use ReceiveFrom here. this will give you an IPEndPoint with the address of
the sending client.
Console.Write("Server got: " + buffer[0]);
//Next line crash cause some permission error.
server.SendTo( new byte[] {2},
new IPEndPoint( IPAddress.Broadcast, 48000 ) );
don't send the response back by broadcast. you can send it directly to the
client using the above IPEndPoint.
}

Client:
Socket client = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp);
client.Connect(new IPEndPoint( IPAddress.Broadcast, 48000 ));
not sure if Connect should be used for a connectionless (UDP) socket. I
think it should work, but I always prefer the SendTo and ReceiveFrom
functions for UDP. also you might want to use port 0 for the client. this
way some free source port will be allocated automatically. in your case, if
client and server are running on the same system, they will both access
port 48000, which might fail.

Console.Write("Client send: 1");
client.Send( new byte[] {1} );

byte[] buffer = new byte[1000];
client.Receive(buffer);
Console.Write("Client got: " + buffer[0]);

client.Close();


hth,
Max

Nov 17 '05 #2
Markus Stoeger wrote:
not sure if Connect should be used for a connectionless (UDP) socket. I
think it should work, but I always prefer the SendTo and ReceiveFrom
functions for UDP. also you might want to use port 0 for the client. this
way some free source port will be allocated automatically. in your case, if
client and server are running on the same system, they will both access
port 48000, which might fail.


Thank you, I followed your instructions and now the code works. I also
tried to use port 0 on the client, but then the server didn't received
any message (btw, should I use bind on the server?).

This is the code that have so far. Works pretty well:

Server:
//Start server
Socket server = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp);
Console.Write("Running server..." + Environment.NewLine);
server.Bind( new IPEndPoint( IPAddress.Any, 48000 ) );

while(true)
{
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint tempRemoteEP = (EndPoint)sender;
byte[] buffer = new byte[1000];
//Recive message from anyone.
server.ReceiveFrom(buffer, ref tempRemoteEP);

Console.Write("Server got '" + buffer[0] +
"' from " + tempRemoteEP.ToString() +
Environment.NewLine);

Console.Write("Sending '2' to " + tempRemoteEP.ToString() +
Environment.NewLine);

//Replay to client
server.SendTo( new byte[] {2},
tempRemoteEP );
}

Client:
Socket client = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram,
ProtocolType.Udp);

IPEndPoint AllEndPoint = new IPEndPoint( IPAddress.Broadcast, 48000 );

//Allow sending broadcast messages
client.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.Broadcast, 1);

//Send message to everyone
client.SendTo( new byte[] {1}, AllEndPoint );
Console.Write("Client send '1' to " + AllEndPoint.ToString() +
Environment.NewLine);

IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint tempRemoteEP = (EndPoint)sender;
byte[] buffer = new byte[1000];

string serverIp;

try
{
//Recieve from server. Don't wait more than 3000 milliseconds.
client.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReceiveTimeout, 3000);
client.ReceiveFrom(buffer, ref tempRemoteEP);
Console.Write("Client got '" + buffer[0] + "' from " +
tempRemoteEP.ToString()+ Environment.NewLine);

//Get server IP (ugly)
serverIp = tempRemoteEP.ToString().Split(":".ToCharArray(), 2)[0];
}
catch
{
//Timout. No server answered.
serverIp = "?";
}

Console.Write("ServerIp: " + serverIp + Environment.NewLine);

Nov 17 '05 #3
pe*****@home.se wrote:
Thank you, I followed your instructions and now the code works. I also
tried to use port 0 on the client, but then the server didn't received
any message
I think you have to bind the port on the client side also. Then it should
work with port 0 (haven't tried it right now though).
(btw, should I use bind on the server?).


Yes you have to, otherwise it doesn't know where to listen for the
broadcast.

Have you tested this code on a system with multiple network interfaces yet?
I did something like that a while ago and as far as I remember such a
broadcast is only sent out on one interface, not on all. You have to lookup
the network interface addresses and send a broadcast on each of them. You
can use the Dns functions to resolve your computers hostname, that should
give you all available local network interface addresses.

Max

Nov 17 '05 #4
Markus Stoeger wrote:
I think you have to bind the port on the client side also. Then it should
work with port 0 (haven't tried it right now though).
I added a bind call in the client code. It failed, as expected, cause
two programs where listening on port 48000 at the same time. I then
changed to port 0. No program crashed, but the client didn't find the
server.
Have you tested this code on a system with multiple network interfaces yet?
I did something like that a while ago and as far as I remember such a
broadcast is only sent out on one interface, not on all. You have to lookup
the network interface addresses and send a broadcast on each of them. You
can use the Dns functions to resolve your computers hostname, that should
give you all available local network interface addresses.


Good point. I could get all addresses by calling:
string hostname = System.Net.Dns.GetHostName();
IPHostEntry allLocalNetworkAddresses = Dns.Resolve(hostname);

But how do I use that information? Creating EndPoint like this:

foreach(IPAddress ip in allLocalNetworkAddresses.AddressList)
{
IPEndPoint AllEndPoint = new IPEndPoint( ip, Port );

will only make the client call it self to find the server. In the
original code I do this:

IPEndPoint AllEndPoint = new IPEndPoint( IPAddress.Broadcast, Port );

How do I get the broadcast address for each network?

PEK

Nov 17 '05 #5
pe*****@home.se wrote:
Markus Stoeger wrote:
Good point. I could get all addresses by calling:
string hostname = System.Net.Dns.GetHostName();
IPHostEntry allLocalNetworkAddresses = Dns.Resolve(hostname);

But how do I use that information?


I don't have the source code here right now, but I think you have to create
one socket for each ip address that you get from Dns.Resolve. Then bind the
sockets to these addresses (instead of binding them to IPAddress.Any).
When you call SendTo, use IPAddress.Broadcast as destination.
This way it will be sent out as broadcast on exactly the interface you have
bound the socket to. You'll also have to call ReceiveFrom on each socket.
I think you have to bind the port on the client side also. Then it should
work with port 0 (haven't tried it right now though).


I added a bind call in the client code. It failed, as expected, cause
two programs where listening on port 48000 at the same time. I then
changed to port 0. No program crashed, but the client didn't find the
server.


It should work.. maybe there is another problem? Take a look at the Bind
description on MSDN: http://tinyurl.com/cqoce
It says "If you do not care which local port is used, you can create an
IPEndPoint using 0 for the port number. In this case, the service provider
will assign an available port number between 1024 and 5000."

hth,
Max

Nov 17 '05 #6
Markus Stoeger wrote:
I don't have the source code here right now, but I think you have to create
one socket for each ip address that you get from Dns.Resolve. Then bind the
sockets to these addresses (instead of binding them to IPAddress.Any).
When you call SendTo, use IPAddress.Broadcast as destination.
This way it will be sent out as broadcast on exactly the interface you have
bound the socket to. You'll also have to call ReceiveFrom on each socket.
Yes, of course. I should have figured out that myself.

It should work.. maybe there is another problem? Take a look at the Bind
description on MSDN: http://tinyurl.com/cqoce
It says "If you do not care which local port is used, you can create an
IPEndPoint using 0 for the port number. In this case, the service provider
will assign an available port number between 1024 and 5000."


My mathematical knowledge tells me that 48000 > 5000 :-). Changing to
port 4800 solved the final problem. To those that are interested, this
is the code:

Server:
//Start server
const int Port = 4800;
Socket server = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp);
Console.Write("Running server..." + Environment.NewLine);
server.Bind( new IPEndPoint( IPAddress.Any, Port ) );

while(true)
{
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint tempRemoteEP = (EndPoint)sender;
byte[] buffer = new byte[1000];
//Recive message from anyone.
//Server could crash here if there is another server
//on the network listening at the same port.
server.ReceiveFrom(buffer, ref tempRemoteEP);

Console.Write("Server got '" + buffer[0] +
"' from " + tempRemoteEP.ToString() + Environment.NewLine);

Console.Write("Sending '2' to " + tempRemoteEP.ToString() +
Environment.NewLine);

//Replay to client
server.SendTo( new byte[] {2},
tempRemoteEP );
}

Client:
const int Port = 4800;
string serverIp = "?";

//Get all addresses
string hostname = System.Net.Dns.GetHostName();
IPHostEntry allLocalNetworkAddresses = Dns.Resolve(hostname);

//Walk thru all network interfaces.
foreach(IPAddress ip in allLocalNetworkAddresses.AddressList)
{
Socket client = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp);

//Bind on port 0. The OS will give some port between 1025 and 5000.
client.Bind( new IPEndPoint( ip, 0 ) );

//Create endpoint, broadcast.
IPEndPoint AllEndPoint = new IPEndPoint( IPAddress.Broadcast, Port );

//Allow sending broadcast messages
client.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.Broadcast, 1);

//Send message to everyone on this network
client.SendTo( new byte[] {1}, AllEndPoint );
Console.Write("Client send '1' to " + AllEndPoint.ToString() +
Environment.NewLine);

try
{
//Create object for the server.
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint tempRemoteEP = (EndPoint)sender;
byte[] buffer = new byte[1000];

//Recieve from server. Don't wait more than 3000 milliseconds.
client.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReceiveTimeout, 3000);

//Recive message, save wherefrom in tempRemoteIp
client.ReceiveFrom(buffer, ref tempRemoteEP);
Console.Write("Client got '" + buffer[0] + "' from " +
tempRemoteEP.ToString()+ Environment.NewLine);

//Get server IP (ugly)
serverIp = tempRemoteEP.ToString().Split(":".ToCharArray(), 2)[0];

//Don't try any more networkss
break;
}
catch
{
//Timout. No server answered. Try next network.
}
}

Console.Write("ServerIp: " + serverIp + Environment.NewLine);
Thanks for your excellent support Max!

PEK

Nov 17 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: David Hofmann | last post by:
I'm setting up 2 database servers. The first is on our local network which is our staging server. The second is an external server setup at my hosting company. On a nightly bases I want to copy all...
1
by: Doug | last post by:
The html below shows DataList "DiscountList" nested within DataList "EventItemList". DiscountList contains a Label control. I'm trying to find the label, using FindControl, during...
1
by: Aussie Rules | last post by:
Hi, I have a classic client server app. When the client is installed on the PC I would like the client application to some how 'find' the server or servers that host the server logic. Kind...
6
by: Anony Mous | last post by:
Hi, We've got some clients that are concerned about running Postgresql 7.3.4 on a Win2k Server box, alongside MS SQL Server. I've been running pg on my XP machines for a long time now (with...
4
by: ruben | last post by:
Hi: I'm getting this error when accessing a table with certain WHERE condition: "server closed the connection unexpectedly This probably means the server terminated abnormally before or while...
2
by: Gunnar_Frenzel | last post by:
Hello, this might be an easy question, but I don't have any handy solution at hand. I have an application that is supposed to send UDP broadcast. So far so easy, I did: Socket sockSendBroadcast...
0
by: Crisco www.misericordia.com.br | last post by:
Hi I m working on WEBRADIO Software. im using Windows media encoder 9 SDK on Windows 2003 server using VB.NET. My current scenario is my soundcard . My application will push my server the...
2
by: sunny | last post by:
I need to find my server over the network!!! so my installer installs client on one machine and server on other machine on the same network. How can i do that??? How can my client know where my...
1
by: viswanathtvs | last post by:
java.util.NoSuchElementException javax.faces.el.EvaluationException: java.util.NoSuchElementException at...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.