问题
I was wondering if there's a way to avoid getting a SocketException whenever I cannot connect rather than catching the SocketException using try/catch.
I have this code which checks if a server is available of not:
public bool CheckServerStatus(string IP, int Port)
{
try
{
IPAddress[] IPs = Dns.GetHostAddresses(IP);
using (Socket s = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp))
s.Connect(IPs[0], Port);
return true;
}
catch (SocketException)
{
return false;
}
}
Thanks in advance.
回答1:
You may subclass Socket
and provide your specific implementation:
public class MySocket : Socket{
//...
public boolean TryConnect(...){
}
}
You could also instead of a boolean, return a Result
object that save the exception for error handling:
public class Result {
public Exception Error { get; set; }
public boolean Success { get{ return Error != null; } }
}
回答2:
Getting a SocketException
isn't a problem; this is what the exception should be used for. Depending on the type of exception you get, you can handle them different ways. It would have been bad if you just caught Exception
rather than the more specific SocketException
.
Why do you want to avoid it so much? As the comments say, at some point, somewhere, code will fail if the other end of the connection is not available. Just make sure you catch that failure at the appropriate place, like you appear to be doing now.
回答3:
Maybe you can solve the problem in the first place by using Ahmed approach, but this simply moves the problem a lever deeper.
The main reason why there exists no such a test method is the possibility of a race condition. Just imagine you would check if such a socket is possible and before you can try to establish this socket in the next line a context switch happens (to another thread or application) that just allocates this socket for himself. Now you still get the exception and you have to check for it (by using the try-catch approach).
So this test simply adds no benefit to your code, cause you still have to be prepared for a failing of this method. And that's the reason with this test doesn't exist.
回答4:
I managed to accomplish this using BeginConnect as follows
int connectTimeoutMS = 1000;
IPEndPoint endPoint = GetEndPoint();
var evt = new AutoResetEvent(false);
_socket.BeginConnect(endPoint, (AsyncCallback)delegate { evt.Set(); }, null);
evt.WaitOne(connectTimeoutMS);
来源:https://stackoverflow.com/questions/16334530/c-sharp-avoid-getting-a-socketexception