[.net] Silly socket shenanigans

Started by
0 comments, last by AmzBee 13 years, 1 month ago
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;	}}
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]

We are now on Tumblr, so please come and check out our site!

http://xpod-games.com

This topic is closed to new replies.

Advertisement