views:

987

answers:

7

Hi,

I'm looking for a way to check if a server is still available. We have a offline application that saves data on the server, but if the serverconnection drops (it happens occasionally), we have to save the data to a local database instead of the online database. So we need a continues check to see if the server is still available.

We are using C# for this application

Greetz,

Sem

ps: the check on the sqlconnection.open is not really an option because this takes about 20 sec before an error is thrown, we can't wait this long + i'm using some http services as well.

A: 

Does this example code help you?

schnaader
+8  A: 

Just use the System.Net.NetworkInformation.Ping class. If you server does not respond to ping (for some reason you decided to block ICMP Echo request) you'll have to invent you own service for this. Personally, I'm all for not blocking ICMP Echo requests, and I think this is the way to go. The ping command has been used for ages to check reachability of hosts.

using System.Net.NetworkInformation;
var ping = new Ping();
var reply = ping.Send("google.com", 60 * 1000); // 1 minute time out (in ms)
// or...
reply = ping.Send(new IPAddress(new byte[]{127,0,0,1}), 3000);
John Leidegren
One problem with this might be if the router/swith replies to the ping, or if the DB service itself has crashed.
Unkwntech
Both seem fairly unlikely, the services shouldn't really fail with out the server crashing. The network would have to be setup so that ping serves as a reliable test of reachability.
John Leidegren
If ping fails, it could be a firewall issue (it's not uncommon for firewalls and NAT routers to drop ping requests).If ping succeeds, the database service could still be down.Thus, ping is not useful to test availability of a service.
DonkeyMaster
I agree with DonkeyMaster, people say that pinging is not always the correct way to check if a server is still running.
Sem Dendoncker
I agree with DonkeyMaster, it's the database he's interested in. So he really needs to be checking that, not just that the server responds to a PING
Chris Driver
Ping is a reachability test, if it doesn't work then your network is not setup properly. Firewall and other stuff included. If the database is installed as a reliable service on target host well, than a echo reply would be the equivalent working server.
John Leidegren
If ping does fail, you can still try and open a connection, if that doesn't work the the database is definitely not reachable. But you still don't know if that is because of network or server failure.
John Leidegren
Someone could easily mis-configure the firewall on the server so that it will respond to the ping but block the db ports, so connecting to the database is the only reliable way to see that the db is up and accessible.
Unkwntech
A: 

Since you want to see if the database server is there either catch any errors when you attempt to connect to the database or use a socket and attempt a raw connection to the server on some service, I'd suggest the database as that is the resource you need.

Unkwntech
+1  A: 

If this is an sql server then you can just try to open a new connection to it. If the SqlConnection.Open method fails then you can check the error message to determine if the server is unavailable.

Rune Grimstad
+1  A: 

If the connection is as unreliable as you say, I would not use a seperate check, but make saving the data local part of the exception handling. I mean if the connection fails and throws an exception, you switch strategies and save the data locally.

If you check first and the connection drops afterwards (when you actually save data), then you still would still run into an exception you need to handle. So the initial check was unnecessary. The check would only be useful if you can assume that after a succesfull check the connection is up and stays up.

f3lix
+1  A: 

What you are doing now is:

  • use distant server
  • if distant server fails, resort to local cache

How to determine if the server is available? Use a catch block. That's the simplest to code.


If you actually have a local database (and not, for example, a list of transactions or data waiting to be inserted), I would turn the design around:

  • use the local database
  • regularly synchronize the local database and the distant database


I'll let you be the judge on concurrency constraints and other stuff related to your application to pick a solution.

DonkeyMaster
good advise thx.
Sem Dendoncker
+1  A: 

From your question it appears the purpose of connecting to the server is to use its database. Your priority must be to check whether you can successfully connect to the database. It doesn't matter if you can PING the server or get an HTTP response (as suggested in other answers), your process will fail unless you successfully establish a connection to the database. You mention that checking a database connection takes too long, why don't you just change the Connection Timeout setting in your application's connection string to a more impatient value such as 5 seconds (Connection Timeout=5)?

Chris Driver
doesn't this inflict the time a query gets to be executed? We have some scripts that take 10 sec's ... and a timeout of 5 would crash no?
Sem Dendoncker
Yes you are correct, but I am suggesting you use this shortened Connection Timeout only for your initial 'probe' to check the server and database is alive. After that, connect using a more sensible sized timeout.
Chris Driver
indeed, thx chris this is a good solution, thx
Sem Dendoncker