I'm trying to connect to a server using BeginConnect and when I specified an incorrect IpAddress or Port I get a SocketException.
The problem is that my try/catch doesn't catch the Exception:
private void OnConnect(IAsyncResult result)
{
try
{
socket.EndConnect(result);
status = Status.WaitAck;
socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, onDataReady, null);
}
catch (Exception ex)
{
if (ConnectionError != null)
ConnectionError(this, new OpenWebNetErrorEventArgs(ex));
}
}
When I call the socket.EndConnect method VS report me the exception and block the program...
How can I handle it?
Thanks
Federico
Are you running the program under debugger? If so, you either have VS to break on any exception being thrown, or break on the SocketException being thrown.
If you fix that (uncheck the "thrown" column for that exception) and it should allow your Catch handler to execute.
Related
i'm trying to handle the exception of a failed tcp connection, but i don't know how exactly do it. I need it when it's impossible to connect to the server and i would a simple Message box that says the it's impossible to contact the server and than the program return to the main form.
public Connessione(string Hostname, int Port)
{
try
{
tcpSocket = new TcpClient(Hostname, Port);
}
catch
{
show the message box and go back to the main form
}
}
this is the part of the code. i would ask you also a good guide about how to handle exception. thank you so much!!
In the catch statement you can get the exception thrown like this (or anything similar):
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Also, if you do not catch the exception (or throw a new one), any code calling the Connessione method can catch the exception like this:
void FirstMethod()
{
try
{
Connessione("google.com", 80);
}
catch (Exception ex)
{
MessageBox.Show("Could not connect to server: " + ex.Message);
}
}
public void Connessione(string hostname, int port)
{
TcpClient tcpSocket = new TcpClient(hostname, port);
// ... Doing things with tcpSocket
}
This is a great article going through how exceptions work and how to use them properly:
https://stackify.com/csharp-exception-handling-best-practices/?utm_referrer=https%3A%2F%2Fduckduckgo.com%2F
I have a program that deals with socket communication asynchronously. The exception I've been getting only occurs in release build (on build machines). The code that causes the problem is really simple routine to start listening for incoming socket connections:
public async Task Listen()
{
try
{
var endpoint = new IPEndPoint(IPAddress.Loopback, Port);
using (Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
Socket.Bind(endpoint);
Socket.Listen(Limit);
while (!Shutdown)
{
var socket = await Socket.AcceptAsync().ConfigureAwait(false);
// some code handling connection
var result = await Socket.ReceiveAsync(state).ConfigureAwait(false);
Received(result, state);
}
}
}
catch (ObjectDisposedException) {}
catch (Exception ex) when (ex is SocketException || ex is ApplicationException || ex is ThreadAbortException)
{
OnError?.Invoke(this, ex);
Dispose();
}
}
AcceptAsync and ReceiveAsync are extension methods that use TPL pattern with Task.Factory.FromAsync. The exact exception is following:
Exception Type: System.InvalidProgramException
Exception Message: Common Language Runtime detected an invalid program.
This seem to occur in:
System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Start
The exception is generated instantly when call is made to this method. Any ideas what might be wrong?
According to MSDN, this exception informs the user about invalid IL code. So something could be broken in the framework. I recommend you to try your luck at Connect.Microsoft. Also, if you're really interested and are looking for a quick fix you may want to inspect the IL code of the failing methods' chain.
I have a List of TCP sockets I write data to. If the writing fails, I remove it from the list and just carry on.
At least thats the plan. What happens is, that when a client disconnects, the SocketException escalates and the program crashes, even though that exception is handled. The code is below:
// sockets is type List<Socket>
foreach (Socket s in sockets)
{
String jsonString = skeleton.Marshall();
byte[] jsonBytes = System.Text.Encoding.UTF8.GetBytes(jsonString);
try
{
s.Send(jsonBytes); // boom! System.Net.Sockets.SocketException!
}
catch (System.Net.Sockets.SocketException except)
{
sockets.Remove(s);
Console.WriteLine(except.StackTrace);
}
catch (Exception except)
{
Console.WriteLine(except.StackTrace);
}
}
I don't get why any exception could go through this. I didn't look at the console output because Visual Studio clears that when an exception occurs (at least I didn't see anything meaningful over there)
Thanks for your help!
Edit
As Sebastian Negraszus pointed out, I can't directly remove the Socket from the List, so the code now is
List<Socket> remove = new List<Socket>();
// sockets still is of type List<Socket>
foreach (Socket s in sockets)
{
String jsonString = skeleton.Marshall();
byte[] jsonBytes = System.Text.Encoding.UTF8.GetBytes(jsonString);
try
{
s.Send(jsonBytes);
}
catch (System.Net.Sockets.SocketException except)
{
remove.Add(s);
Console.WriteLine(except.StackTrace);
}
catch (Exception except)
{
Console.WriteLine(except.StackTrace);
}
}
foreach (Socket s in remove)
{
sockets.Remove(s);
}
However, even if the Socket is not removed from the list, it should just escalate here.
Edit 2
This code runs in an event handler, while sockets is being filled in the main Thread, so I assumed the lack of locking caused problems. However, after adding locks, the error still appeared.
main thread:
// ...
sockets = new List<Socket>();
delegateFoo += handlerFunction;
// ...
TcpListener tcpListener = new TcpListener(IPAddress.Any, 20001);
tcpListener.Start();
while (true) {
Socket s = tcpListener.AcceptSocket();
lock (sockets) {
sockets.Add(s);
}
}
handler function:
// ...generate skeleton...
lock (sockets)
{
foreach (Socket s in sockets)
{
String jsonString = skeleton.Marshall();
byte[] jsonBytes = System.Text.Encoding.UTF8.GetBytes(jsonString);
try
{
s.Send(jsonBytes);
}
catch (System.Net.Sockets.SocketException except)
{
remove.Add(s);
Console.WriteLine(except.StackTrace);
}
catch (Exception except)
{
Console.WriteLine(except.StackTrace);
}
}
foreach (Socket s in remove)
{
sockets.Remove(s);
}
}
Bad luck though, the Exception still escalates (at least I think so, the program interrupts in VS and this little window occurs saying "SocketException occured" (I use the German version, so the wording might be different).
The error can be triggered by connecting twice using putty and closing one of the two puttys. The next time Send() is called - boom.
Edit 3: Exception details
I'm sorry these are in German. Translations:
"... ist aufgetreten" = "... occured"
"bei" = "at"
message = "An existing connection has been aborted/terminated by the host computer"
System.Net.Sockets.SocketException ist aufgetreten.
_HResult=-2147467259
_message=Eine bestehende Verbindung wurde softwaregesteuert durch den Hostcomputer abgebrochen
HResult=-2147467259
IsTransient=false
Message=Eine bestehende Verbindung wurde softwaregesteuert durch den Hostcomputer abgebrochen
Source=System
ErrorCode=10053
NativeErrorCode=10053
StackTrace:
bei System.Net.Sockets.Socket.Send(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
InnerException:
And yes, I only Send() once in my program.
Edit 4: Visual Studio weirdness
Okay, it's Visual Studio being weird. I can uncheck the "break on Exceptions of this type" checkbox and then it just continues. So the exception didn't escalate, but nevertheless made the program stop.
I don't get why you would want to break on handled exceptions by default. I figured that if I uncheck that the program just faults. If you have a better solution, I'd be glad to accept your answer.
I assume sockets is a List<T>? You cannot modify the list with sockets.Remove(s); while still inside the foreach loop, because this invalidates the enumerator. The next iteration causes an InvalidOperationException.
Uncheck "break on exceptions of this type" (or whatever it's called in English). Works fine afterwards.
I have a certain issue which I'm facing. My contract implementation (besides other stuff) has something like this:
try
{
response = _socketRequest.SendRequest(request, emmiterHeader);
trCode = response.TraceCodeInt;
if (trCode == 0)
statusRequest = (int) TSRequestAttemptStatus.active;
}
catch (TimeoutException tex)
{
throw;
}
catch (Exception)
{
statusRequest = (int) TSRequestAttemptStatus.notActive;
throw;
}
finally
{
tsra = CreateTireaSincoRequestAttemptRow(DateTime.Now, statusRequest, emmiterHeader.HeaderId,
string.Empty,
string.Empty,
string.Empty,
previousContractNumber,
taxIdentificationCode,
policyHolderName,
policyHolderFirstName,
policyHolderLastName,
registrationNumberType.Substring(0, 1),
registrationNumber,
((byte) ControlCodes.F),
DateTime.Now.AddDays(emmiterHeader.ValidityPeriod));
}
Then in
_socketRequest.SendRequest(request, emmiterHeader);
Among other stuff is something like below:
using (var client = new TcpClient(header.SocketServerAddress,
header.SocketServerPort == null ? 1 : (int)header.SocketServerPort))
{
Socket socket = client.Client;
// send data with timeout 10s
//socket.Send(arr);
Send(socket, arr, 0, arr.Length, 1000);
if (header.DebugMode)
_logger.LogInfo(InterfaceName, string.Format("Data Socket Send: {0} ", tempArr));
// receive data with timeout 10s
//Receive(client, arr);
len = Receive(socket, arrResponse, 0, arrResponse.Length, 5000, header.DebugMode, _logger);
if (socket.Connected)
socket.Close();
if (client.Connected)
client.Close();
}
The part under the using key word is never called because built in WCF Client is "hanging" on the TCPClient part, whcich in conclusion raises a SocketExeption error. I have set the timeouts in the web config to lets say 5 seconds. What I like to achieve is to throw not socket exception but the timeout exception. It looks like the SocketException is thrown but I can't make my wcf service throw a timeout exception. Is it possible to do that? I hope my questin is understandable what I want to do. If not I will try to explain as clearly as I can.
TcpClient does not know or care what you talk to. It has no notion of WCF, web services or the TimeoutException that you want.
All it does it maintain a TCP connection.
Catch the SocketException and analyze the error code stored in it. There is a code for timeouts. Throw TimeoutException yourself.
And get rid of this superstitious dispose stuff:
if (socket.Connected)
socket.Close();
if (client.Connected)
client.Close();
Once is enough.
I create a TCP listener by using the code below:
TCPListener = new TcpListener(IPAddress.Any, 1234);
I start to listen TCP devices by using the code below:
TCPListener.Start();
But here, i don't control if the port is in use. When the port is in use, program gives an exception: "Only one usage of each socket address (protocol/network address/port) is normally permitted.".
How do i handle this exception? I want to warn user that the port is in use.
Put a try/catch block around TCPListener.Start(); and catch SocketException. Also if you are opening multiple connections from your program, then its better if you keep track of your connections in a list and before opening a connection see if you already have a connection opened
It's not a good idea to get an exception to check whether the port is in use or not. Use the IPGlobalProperties object to get to an array of TcpConnectionInformation objects, which you can then interrogate about endpoint IP and port.
int port = 1234; //<--- This is your value
bool isAvailable = true;
// Evaluate current system tcp connections. This is the same information provided
// by the netstat command line application, just in .Net strongly-typed object
// form. We will look through the list, and if our port we would like to use
// in our TcpClient is occupied, we will set isAvailable to false.
IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
TcpConnectionInformation[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections();
foreach (TcpConnectionInformation tcpi in tcpConnInfoArray)
{
if (tcpi.LocalEndPoint.Port==port)
{
isAvailable = false;
break;
}
}
// At this point, if isAvailable is true, we can proceed accordingly.
For details please read this.
For handling the exception you will use try/catch as habib suggested
try
{
TCPListener.Start();
}
catch(SocketException ex)
{
...
}
Catch it and display your own error message.
Check the exception type and use this type in catch clause.
try
{
TCPListener.Start();
}
catch(SocketException)
{
// Your handling goes here
}
Put it in a try catch block.
try {
TCPListener = new TcpListener(IPAddress.Any, 1234);
TCPListener.Start();
} catch (SocketException e) {
// Error handling routine
Console.WriteLine( e.ToString());
}
Use try-catch blocks and catch the SocketException.
try
{
//Code here
}
catch (SocketException ex)
{
//Handle exception here
}
Well, considering that you're talking about exceptional situation, just handle that exception with suitable try/catch block, and inform a user about a fact.