Raising an exception in a Sockets Async Callback Problem.

D

David

Hi,

Ive been trying to work this out for the past 2 days now and im not
getting anywhere fast.

The problem i have is that i am using Asynchronous sockets to create a
Socket Client library. When i try to connect to a server that doesnt
exist it raises a "Connection forcibly rejected by the resmote host"
SocketException.

Because this is thrown inside an Async Callback it is not "bubbling up"
the call stack so the user can handle it so I end up with an
UnhandledException error.

Because of the nature of the exception message i need to report this so
that the user of the client can handle this themselves (by using a
messagebox or whatever they want to do).

Does anyone know how i can cause this exception to be thrown in the
method that calls BeginInvoke() so i can bubble it back up to the user
to handle themselves in their app?

My code for this block is as follows:
=====================================

/// <summary>
/// Begins a aynchronous connection operation and delegates a async
/// callback so we don't lock up resources while waiting for the
/// operation to complete.
/// </summary>
public void Connect()
{
if(m_SocketClient != null)
{
try
{
m_SocketState = SocketState.Connecting;

// Begin the asynchronous connection to the
// host.

m_SocketClient.BeginConnect(m_ipEndPoint, new
AsyncCallback(ConnectCallBack), m_SocketClient);
}
catch(SocketException se)
{
m_SocketState = SocketState.Error;

throw new ClientException("An error has occured
while trying to connect to the remote host.",
se);
}
}
else
{
m_SocketState = SocketState.Error;

throw new ClientException("Cannot open connection when
the socket is uninitiated.");
}
}


----------------------------------------------------------------------


/// <summary>
/// Asynchronous callback for Connect method.
/// </summary>
/// <param name="asyn">Status of the asynchronous operation.</param>
private void ConnectCallBack(IAsyncResult asyn)
{
try
{
// End connection procedure.
m_SocketClient.EndConnect(asyn);

if(m_SocketClient.Connected)
{
m_SocketState = SocketState.Connected;

// Begin receiving data.
ReceiveData();

// Check to see if the event handler exists
if(OnSocketConnected != null)
{
// Create event args
ClientEventArgs args = new
ClientEventArgs(m_SocketClient);
args.SocketID = m_SocketID;
args.RemoteHost = m_HostAddress;
args.RemoteIP = m_HostIP;
args.RemotePort = m_Port;
args.State = m_SocketState;

// Raise the Connected event.
OnSocketConnected(this, args);
}
}
}
catch(SocketException se)
{
m_SocketState = SocketState.Error;

throw new ClientException("An Error occured while
attempting to end connection process with remote host.",
se);
}
}

Cheers,

David
 
H

hOSAM

Why don't you just always save the exception in a variable or so inside your
class that connects.. then the caller class can check for errors afterwards.

Another way you can go is that you may like to fire an event in case there
is some error out there.
 
D

David

The socket library is going to be a generic one for all the apps i and
other people write so i dont have to keep messing with sockets so
handling it with a variable like that isnt an option as it would involve
manual checking which is a little messy.

Having it fire an event would make it get handled in the wrong place in
the consuming program, i need to be able to catch the exception in a try
/ catch block around the place where the user instantiates a client and
connects.


David
 
H

hOSAM

You don't have to show all the mess to the user..
It is really that simple as I see it:

I understand that you want to "Block and wait" if there will be any
exceptions on connection operation... because you simply want to throw
exceptions from the function that is seen by the user.

So that means you have to wait *for at least some time* until the
EndConnect() throws the exception that you are after..
something that might smell like this:

// Here it is:
Exception myException = null;
public void Connect(){
if(m_SocketClient != null)
{
try
{
m_SocketState = SocketState.Connecting;
// Begin the asynchronous connection to the host.
m_SocketClient.BeginConnect(m_ipEndPoint, new
AsyncCallback(ConnectCallBack), m_SocketClient);
while( m_SocketState == SocketState.Connecting )
{
System.Threading.Thread.Sleep(10);
}
if ( m_SocketState == SocketState.Error )
{
throw myException;
}

}
catch(SocketException se)
{
m_SocketState = SocketState.Error;
throw new ClientException("An error has occured while trying to connect to
the remote host.", se)
}
}

else
{
m_SocketState = SocketState.Error;
throw new ClientException("Cannot open connection when the socket is
uninitiated.") }
}

// <summary>
/// Asynchronous callback for Connect method.
/// </summary>
/// <param name="asyn">Status of the asynchronous operation.</param>
private void ConnectCallBack(IAsyncResult asyn)
{
try
{
// End connection procedure.
m_SocketClient.EndConnect(asyn);
if(m_SocketClient.Connected)
{
m_SocketState = SocketState.Connected;
// Begin receiving data.
ReceiveData();
// Check to see if the event handler exists
if(OnSocketConnected != null)
{
// Create event args
ClientEventArgs args = new
ClientEventArgs(m_SocketClient);
args.SocketID = m_SocketID;
args.RemoteHost = m_HostAddress;
args.RemoteIP = m_HostIP;
args.RemotePort = m_Port;
args.State = m_SocketState;
// Raise the Connected event.
OnSocketConnected(this, args);
}

}

}
catch(SocketException se)
{
m_SocketState = SocketState.Error;
// keep it with you.
myException = ClientException("An Error occured while attempting to end
connection process with remote host.", se);
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top