How to get error codes for Dns.GetHostAddresses - c#

Still new with C#.
I'm trying to get the error codes for my line below so that I know if the hostname is a validhost or not. I did some research on sockets but I am not sure how to use it.
IPAddress[] IPstr = Dns.GetHostAddresses("hostname");

It throws different kind of Exception for exceptions (pun intended):
Exception
Description
ArgumentNullException
hostNameOrAddress is null.
ArgumentOutOfRangeException
The length of hostNameOrAddress is greater than 255 characters.
SocketException
An error is encountered when resolving hostNameOrAddress.
ArgumentNullException
hostNameOrAddress is an invalid IP address.
You probably want to listen for the SocketException like:
public static bool IsHostReachable(string hostname)
{
try
{
_ = Dns.GetHostAddresses(hostname);
return true;
}
catch(SocketException ex)
{
Console.WriteLine("The host could not be reached!")
return false;
}
}
Source: MS Docs

Related

I am trying to form FTP connections in C# with unknown IP addresses. How would I check if each address is valid or not?

The following function successfully returns the FTP server's welcome message when the input IP address is valid.
When I test it with something that has the format of an IP address but doesn't correspond to an FTP server, I get a WebException that is thrown from System.dll, and not from the function. The WebException takes a very long time to get caught, and I would like to avoid relying on try-catch if possible.
How would I fix this so when I pass in an invalid IP address, CheckIP returns "Timeout" (or finishes execution in some other way) instead of dealing with the exception?
Note: I'm aware that connections can be tested with Ping, I just wanted to know if there's a way to do it natively within FTP.
public string CheckIP(string ip){
string respStr="Timeout";
try
{
var connection = (FtpWebRequest)WebRequest.Create(#"ftp://" + ip + #"/");
connection.Credentials = new NetworkCredential(Username, Password);
connection.Method = WebRequestMethods.Ftp.PrintWorkingDirectory;
connection.Timeout = 500;
var response = (FtpWebResponse)connection.GetResponse();
respStr = response.WelcomeMessage.ToString();
response.Close();
}
catch (Exception)
{
respStr = "Exception";
}
return respStr;
}

How to differ from writing exception to a reading one?

I have a socket and I'd like to send messages and read from it.
When I read/write with the socket while the other side is offline, I get the same Exception: System.IO.IOException: Unable to read data from the transport connection: Operation on non-blocking socket would block.
How can I identify in which of the two it happened besides having two separate try-catch blocks? Can't I just get a Timeout Exception when the reading timeout is over?
example:
try
{
SendData("!GetLocation!");
string data = GetData();
}
catch (Exception ex)
{
if (ex is System.IO.IOException)
{
//How can I identify if the exception was raised at the read method or the write method?
}
}
Yeah, exception handling is heavy resource wise, but sometimes is not so bad.
If you stick to only one try-catch you can check the error message.
Note: I have also added a second try-catch for generic (non IO) errors
try
{
SendData("!GetLocation!");
string data = GetData();
}
catch (System.IO.IOException ex)
{
if (ex.Message.IndexOf("Unable to read") != -1)
{
// GetData error
}
else if (ex.Message.IndexOf("Unable to write") != -1)
{
// SendData error
}
else
{
//Other IO errors
}
}
catch(Exception exc)
{
// Unspected errors
}
you could also set a boolean variable and check its value to know where it
broke your code.
bool sendCalled = false;
try
{
SendData("!GetLocation!");
sendCalled = true;
string data = GetData();
}
catch (System.IO.IOException ex)
{
if (sendCalled)
{
// GetData error
}
else
{
// SendData error
}
}
Not that I endorse either of these solutions, but an answer is an answer: you can either
analyze the stack trace of the exception to find out which call failed (e.g. name of the method at the top of the stack frame
set a flag after the write, and do logic based on that flag
Neither of these is as straight forward as wrapping each method call. In fact, wrapping each call conveys your intent. In the catch of your first call, you can return/break/skip the read call, which explicitly tells the reader you're bailing out fast.

Create a Computer Request Including IP address Subject Alternative Name

I'm trying to create a request with IP address SAN. This is the function that is responsible for creating the CAlternativeName:
public static CAlternativeNameClass GetCurrentIpName() {
//get current machine IP address
IPAddress ip = GetCurrentIp();
if (ip == null) {
return null;
}
try {
CAlternativeNameClass nameClass = new CAlternativeNameClass();
nameClass.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_IP_ADDRESS, ip.ToString());
return nameClass;
} catch (Exception e) {
Console.WriteLine(e);
return null;
}
}
The problem is that I'm getting the next error:
System.ArgumentException: Value does not fall within the expected range.
at CERTENROLLLib.CAlternativeNameClass.InitializeFromString(AlternativeNameType Type, String strValue)
What am I doing wrong?
InitializeFromString does not accept an AlternativeNameType of XCN_CERT_ALT_NAME_IP_ADDRESS**. You have to use InitializeFromRawData instead. The error is something of a misnomer because it's not actually the value parameter that's the issue, it's the type, but hey.
InitializeFromRawData takes a string as input (because this is Microsoft, not Ronseal), so you need to encode your raw data as a string so it can turn it in to raw data again:
String ipBase64 = Convert.ToBase64String(ip.GetAddressBytes());
nameClass.InitializeFromRawData(AlternativeNameType.XCN_CERT_ALT_NAME_IP_ADDRESS, EncodingType.XCN_CRYPT_STRING_BASE64, ipBase64);
About as intuitive as an Escher artpiece.
** Source: http://msdn.microsoft.com/en-us/library/windows/desktop/aa375024%28v=vs.85%29.aspx

C# - Avoid getting a SocketException

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.
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; } }
}
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.
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);
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.

WCF proxy faulted but does not throw an exception

I have a method which accesses a service to perform two calls. Here is the (simplified) client code:
try
{
using (var client = new IntegrationServiceClient())
{
int taskID = client.CreateTask(param, taskType, taskDate);
if (taskID < 0)
{
//There was some error
return -1;
}
if (!client.ExecuteTask(taskID, taskType))
{
//There was some error
}
}
}
catch (Exception ex)
{
LogManager.Log("Error while creating and executing task", ex);
}
I'm getting a CommunicationObjectFaultedException exception only on the second call. How is this possible? If there was some kind of fault, shouldn't I get a FaultException (or some other exception) after the first call? Is there something other than an exception that can cause the proxy to enter a faulted state?
It seems there was a bad web.config file. The stack trace was telling me there was an error on line with the second call because that was the last meaningful line within the using statement, after which the proxy is disposed. The CommunicationObjectFaultedException is raised only when disposing the proxy.
It was just the way that the code was written that caused the stack trace look like the exception was thrown when calling the second method.

Categories