Jump to content
  • Advertisement
Sign in to follow this  
Grenwood

[.net] Silly socket shenanigans

This topic is 2712 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have been having some difficulty in a C# application that uses a UDP socket connection. Everything works all sorts of fancy and fun until the closing of my Form application, and then I can't seem to stop receiving messages.

I always get some form of exception inside of the receive callback stating that the socket is disposed. This is, of course, true. The problem is, why am I getting a message after I have closed down and shutdown the sockets? I'm not too familiar with every in and out of C# (don't think I'll ever get used to managed code. Can I have C back?) Included, I have the receive callback, which parses a message and continues to listen. I also included the CloseConnections method, which is called within the Form Closing event.

Does Shutdown and Close not stop the messages from being received? If so, how can I so that the GC may dispose of my sockets without receiving a message afterwards?

"An unhandled exception of type 'System.ObjectDisposedException' occurred in system.dll
Additional information: Cannot access a disposed object named "System.Net.Sockets.Socket"."


private static void ReceiveCallback(IAsyncResult ar)
{
// End Receive
StateObject stateObject = (StateObject)ar.AsyncState;

if(stateObject != null && stateObject.Socket != null && stateObject.DataBuffer != null && stateObject.EventMap != null)
{
int bytesReceived = stateObject.Socket.EndReceive(ar);

if(bytesReceived > 0)
{
// Parse Data
SocketConnection.ParseReceiveBuffer(stateObject);
}
}
if(stateObject != null && stateObject.Socket != null && stateObject.DataBuffer != null && stateObject.EventMap != null)
{
// Begin Receive
stateObject.Socket.BeginReceive(stateObject.DataBuffer, 0, stateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), stateObject);
}
}


public void CloseConnections()
{
// Receive
if(_recvSocket != null)
{
_recvSocket.Shutdown(SocketShutdown.Both);
_recvSocket.Close();
_recvSocket = null;
_recvState.Socket = null;
_recvState = null;
}

// Send
if(_sendSocket != null)
{
_sendSocket.Shutdown(SocketShutdown.Both);
_sendSocket.Close();
_sendSocket = null;
_sendState.Socket = null;
_sendState = null;
}
}

Share this post


Link to post
Share on other sites
Advertisement

I have been having some difficulty in a C# application that uses a UDP socket connection. Everything works all sorts of fancy and fun until the closing of my Form application, and then I can't seem to stop receiving messages.

I always get some form of exception inside of the receive callback stating that the socket is disposed. This is, of course, true. The problem is, why am I getting a message after I have closed down and shutdown the sockets? I'm not too familiar with every in and out of C# (don't think I'll ever get used to managed code. Can I have C back?) Included, I have the receive callback, which parses a message and continues to listen. I also included the CloseConnections method, which is called within the Form Closing event.

Does Shutdown and Close not stop the messages from being received? If so, how can I so that the GC may dispose of my sockets without receiving a message afterwards?

"An unhandled exception of type 'System.ObjectDisposedException' occurred in system.dll
Additional information: Cannot access a disposed object named "System.Net.Sockets.Socket"."


private static void ReceiveCallback(IAsyncResult ar)
{
// End Receive
StateObject stateObject = (StateObject)ar.AsyncState;

if(stateObject != null && stateObject.Socket != null && stateObject.DataBuffer != null && stateObject.EventMap != null)
{
int bytesReceived = stateObject.Socket.EndReceive(ar);

if(bytesReceived > 0)
{
// Parse Data
SocketConnection.ParseReceiveBuffer(stateObject);
}
}
if(stateObject != null && stateObject.Socket != null && stateObject.DataBuffer != null && stateObject.EventMap != null)
{
// Begin Receive
stateObject.Socket.BeginReceive(stateObject.DataBuffer, 0, stateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), stateObject);
}
}


public void CloseConnections()
{
// Receive
if(_recvSocket != null)
{
_recvSocket.Shutdown(SocketShutdown.Both);
_recvSocket.Close();
_recvSocket = null;
_recvState.Socket = null;
_recvState = null;
}

// Send
if(_sendSocket != null)
{
_sendSocket.Shutdown(SocketShutdown.Both);
_sendSocket.Close();
_sendSocket = null;
_sendState.Socket = null;
_sendState = null;
}
}



Looking at the MSDN article on Socket.EndRecieve, it seems that you are missing an else when the bytesRecieved does equal zero. The MSDN article shows that a socket close should be placed here. If I was to take a wild guess, id say that calling the close within the callback may actually be required as the async thread is then in scope. Give it a try anyway. I maybe way off the mark :) here's what id append:


private static void ReceiveCallback(IAsyncResult ar)
{
// End Receive
StateObject stateObject = (StateObject)ar.AsyncState; [font=Consolas, Courier, monospace][size=2]Socket s = stateObject.workSocket;[/font]

if(stateObject != null && stateObject.Socket != null && stateObject.DataBuffer != null && stateObject.EventMap != null)
{
int bytesReceived = stateObject.Socket.EndReceive(ar);

if(bytesReceived > 0)
{
// Parse Data
SocketConnection.ParseReceiveBuffer(stateObject);
} else { s.Close(); } }
if(stateObject != null && stateObject.Socket != null && stateObject.DataBuffer != null && stateObject.EventMap != null)
{
// Begin Receive
stateObject.Socket.BeginReceive(stateObject.DataBuffer, 0, stateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), stateObject);
}
}



Also thinking about it now, perhaps when you begin an async recieve, it may actually create a new reciever socket like old server programming does to accept information, in that case [font=monospace]_sendSocket.Close(); would only close the listener and not the socket actually recieving data.[/font]
[font=monospace]
[/font]
[font=monospace]All the best.[/font]
[font=monospace]
[/font]
[font=monospace]Aimee.[/font]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!