UdpClient not failing when endpoint is unavailable - c#

It was my expectation that, if the endpoint is not available, the UdpClient.Connect() method would throw an exception that I could capture and, say, alter a label's text to say if the program was connected to the server or not. However, despite me having turned off the server that I'm trying to connect to, the method completes with no issue. Is there some way to resolve this issue, or some other method I should be attempting?
My current code (IP address blanked out, but is valid):
UdpClient chatConnection = new UdpClient();
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("xxx.xx.xxx.xxx"), 1000);
// Initialize client/server connection and set status text
try
{
chatConnection.Connect(serverEndPoint);
SL_Status.Text = "Connected";
}
catch (Exception ex)
{
SL_Status.Text = "Not Connected";
MessageBox.Show("Unable to connect to server. See console for logs.");
Console.WriteLine(ex);
}

Since UDP is connectionless checking if client is connected doesn't apply to it.
There is however a workaround that in some cases may work:
answer by Yahia

Related

TcpListener - how to start server with global ip address

I would start TcpListener server with my global IP address.
I have open ports and using DMZ and my port 8074 is available and i should be able to start this server.
My code looks like :
IPAddress ip = IPAddress.Parse("XX.XXX.XX.XXX.XX");
TcpListener server = new TcpListener(ip, Convert.ToInt32(8888));
TcpClient client = default(TcpClient);
try
{
server.Start();
Console.WriteLine("Server started...");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
};
And all the time i have Error looks like:
Activated Event Time Duration Thread Exception: An exception was
thrown: "System.Net.Sockets.SocketException" in System.dll ("The
requested address is different in this context"). An exception was
thrown: "System.Net.Sockets.SocketException" in System.dll ("The
requested address is different in this context") 5.52s [5780] Worker
thread
You can check if you want this port is accessible on my IP address but can't start server on this.
Yeah thanks #jdweng .
All i need to change was just this lane :
IPAddress ip = IPAddress.Any;

Mono obtain remote ip address when socket is timed out

catch (SocketException se)
{
if(se.ErrorCode == 10054 || se.ErrorCode == 10053) // Error code for Connection reset by peer
{
Console.WriteLine("User from " + currentSocket.RemoteEndPoint.ToString() + " timed out");
}
}
I have a problem with socket exception with mono, above code runs perfectly on windows, while on mono throws exception that RemoteEndPoint is null.
My question is how to obtain ip address of disconnected user using mono?
Create a wrapper which holds the socket and any additional information you need. Upon connection, you can populate the values you want to save such as their ip address. When a disconnect occurs, you can log from this variable instead of off the socket object.

Reading data from a server and detecting network unavailability in C#

I have a simple task: to read data from a server, if the server is unreachable (server down or bad network), load data (possibly stale) from local disk cache.
Here's a simple pseudo representation of what the Java code would look like:
try {
//read from server
} catch (IOException ioe) {
//most likely a socket timeout exception
//read from local disk
} finally {
//free I/O resources
}
but implementing that in C# doesn't seem to work as WebClient doesn't seem to throw any exception even when there's no internet access on the host machine so there's no way to detect that condition via the catch block and revert back to the local cache.
I'm aware of WebClient's async APIs and its rather funny callback chain but I perceive this as too awkward and doesn't suit my design goal properly. Is there a way I can do this in C# as easily as the Java skeleton code shown above? Thanks.
WebClient will timeout, but only after 100s.
I would recommend you use HttpWebRequest instead. This has a settable timeout property.
See http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.timeout.aspx
Furthermore to bobbymond's answer, it's a WebException that will be returned by the WebClient, so that's what you're looking to catch:
WebClient wc = new WebClient();
try
{
wc.Credentials = new NetworkCredential("Administrator", "SomePasword", "SomeDomain");
byte[] aspx = wc.DownloadData("http://SomeServer/SomeSub/SomeFile.aspx");
}
catch (WebException we)
{
//Catches any error in the WebClient, including an inability to contact the remote server
}
catch (System.Exception ex)
{
}

The I/O operation has been aborted because of either a thread exit or an application request

My application is working as a client application for a bank server. The application is sending a request and getting a response from the bank. This application is normally working fine, but sometimes
The I/O operation has been aborted because of either a thread exit or
an application request
error with error code as 995 comes through.
public void OnDataReceived(IAsyncResult asyn)
{
BLCommonFunctions.WriteLogger(0, "In :- OnDataReceived",
ref swReceivedLogWriter, strLogPath, 0);
try
{
SocketPacket theSockId = (SocketPacket)asyn.AsyncState;
int iRx = theSockId.thisSocket.EndReceive(asyn); //Here error is coming
string strHEX = BLCommonFunctions.ByteArrToHex(theSockId.dataBuffer);
}
}
Once this error starts to come for all transactions after that same error begin to appear, so
please help me to sort out this problem. If possible then with some sample code
Regards,
Ashish Khandelwal
995 is an error reported by the IO Completion Port. The error comes since you try to continue read from the socket when it has most likely been closed.
Receiving 0 bytes from EndRecieve means that the socket has been closed, as does most exceptions that EndRecieve will throw.
You need to start dealing with those situations.
Never ever ignore exceptions, they are thrown for a reason.
Update
There is nothing that says that the server does anything wrong. A connection can be lost for a lot of reasons such as idle connection being closed by a switch/router/firewall, shaky network, bad cables etc.
What I'm saying is that you MUST handle disconnections. The proper way of doing so is to dispose the socket and try to connect a new one at certain intervals.
As for the receive callback a more proper way of handling it is something like this (semi pseudo code):
public void OnDataReceived(IAsyncResult asyn)
{
BLCommonFunctions.WriteLogger(0, "In :- OnDataReceived", ref swReceivedLogWriter, strLogPath, 0);
try
{
SocketPacket client = (SocketPacket)asyn.AsyncState;
int bytesReceived = client.thisSocket.EndReceive(asyn); //Here error is coming
if (bytesReceived == 0)
{
HandleDisconnect(client);
return;
}
}
catch (Exception err)
{
HandleDisconnect(client);
}
try
{
string strHEX = BLCommonFunctions.ByteArrToHex(theSockId.dataBuffer);
//do your handling here
}
catch (Exception err)
{
// Your logic threw an exception. handle it accordinhly
}
try
{
client.thisSocket.BeginRecieve(.. all parameters ..);
}
catch (Exception err)
{
HandleDisconnect(client);
}
}
the reason to why I'm using three catch blocks is simply because the logic for the middle one is different from the other two. Exceptions from BeginReceive/EndReceive usually indicates socket disconnection while exceptions from your logic should not stop the socket receiving.
In my case, the request was getting timed out. So all you need to do is to increase the time out while creating the HttpClient.
HttpClient client = new HttpClient();
client.Timeout = TimeSpan.FromMinutes(5);
I had the same issue with RS232 communication. The reason, is that your program executes much faster than the comport (or slow serial communication).
To fix it, I had to check if the IAsyncResult.IsCompleted==true. If not completed, then IAsyncResult.AsyncWaitHandle.WaitOne()
Like this :
Stream s = this.GetStream();
IAsyncResult ar = s.BeginWrite(data, 0, data.Length, SendAsync, state);
if (!ar.IsCompleted)
ar.AsyncWaitHandle.WaitOne();
Most of the time, ar.IsCompleted will be true.
I had this problem. I think that it was caused by the socket getting opened and no data arriving within a short time after the open. I was reading from a serial to ethernet box called a Devicemaster. I changed the Devicemaster port setting from "connect always" to "connect on data" and the problem disappeared. I have great respect for Hans Passant but I do not agree that this is an error code that you can easily solve by scrutinizing code.
In my case the issue was caused by the fact that starting from .NET 5 or 6 you must either call async methods for async stream, or sync methods for sync strem.
So that if I called FlushAsync I must have get context using GetContextAsync
What I do when it happens is Disable the COM port into the Device Manager and Enable it again.
It stop the communications with another program or thread and become free for you.
I hope this works for you. Regards.
I ran into this error while using Entity Framework Core with Azure Sql Server running in Debug mode in Visual Studio. I figured out that it is an exception, but not a problem. EF is written to handle this exception gracefully and complete the work. I had VS set to break on all exceptions, so it did. Once I unchecked the check box in VS to not break on this exception, my C# code, calling EF, using Azure Sql worked every time.

TCP stuff never works for me

I am trying to get a little client/server thing going just to learn how to do it... But after using many samples, following several tutorials even on msdn, none of them have ever worked.
I keep getting the following exception:
System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it 220.101.27.107:8000
at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
at t.MainForm.toolStripButton1344_Click(Object sender, EventArgs e) in C:\Users\Jason\Documents\Visual Studio 2008\Projects\t\t\MainForm.cs:line 1648
and the code i have is:
private void toolStripButton1344_Click(object sender, EventArgs e)
{
String strHostName;
string ipaddy;
// Getting Ip address of local machine...
// First get the host name of local machine.
strHostName = Dns.GetHostName();
Console.WriteLine("Local Machine's Host Name: " + strHostName);
// Then using host name, get the IP address list..
IPHostEntry ipEntry = Dns.GetHostByName(strHostName);
IPAddress[] addr = ipEntry.AddressList;
for (int i = 0; i < addr.Length; i++)
{
ipaddy = addr[i].ToString();
}
Socket st = new Socket(
AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipe = new IPEndPoint(addr[0], 8000);
try
{
st.Connect(ipe);
}
catch (ArgumentNullException ae)
{
MessageBox.Show("ArgumentNullException : {0}" + ae.ToString());
}
catch (SocketException se)
{
MessageBox.Show("SocketException : {0}" + se.ToString());
}
catch (Exception ex)
{
MessageBox.Show("Unexpected exception : {0}" + ex.ToString());
}
}
Can someone please help me understand why this won't work??
Thank you :)
Have you started the server, before trying to connect with the client?
Also, make sure that the port you are using (8000) isn't blocked by a firewall or occupied by another process.
Basically, the error message says the target machine (the one you're trying to connect to) answered the SYN (connection request packet) with an RST (reset, i.e. no connection possible in this case). What it means is, there's no server process listening on the other end.
Client-server software comes in two parts, the client which is connecting to the second part, the server. The server process needs to be listening on a tcp port in order to accept connections, and the client must connect to the servers IP address, along with the port it's listening on.
Well, if all you are trying to do is test creating a socket connection, use "google.com" as your host name and 80 as your port. That is guaranteed to always be listening. And if it's not, then, well, that would probably mean that the world has stopped.
I figured out why it wasn't working. Recently a little application (which I had no idea about) was installed along with a program that I chose to install, and that app was using up several ports. I've managed to get rid of that app, and everything's working just fine :)
Thank you all for your help and suggestions!

Categories