Jump to content
Xtreme .Net Talk

Recommended Posts

  • *Experts*
Posted

In writing code to handle the listening and connection-accepting

of a Socket instance, I've run into a snag after calling

BeginAccept. After calling BeginAccept, I want to be able to cancel

the calling of my callback function and essentially stop the Socket

from listening before it actually receives a connection request.

 

When a connection request does come, the Socket accepts it,

receives from it, and closes it fine, but I'd like to be able to stop

the Socket from listening before a connection is requested.

 

GavinO suggested a very creative kludge that invoves creating a

new Socket and connecting with listening one so that the

connection would be made (behind the scenes) and then

successfully closed right away. Needless to say, I'm hoping

there's a more elegant way. :)

 

Oh, and this is the code I'm using to start the accept callback:

IAsyncResult beginAcceptResult;
beginAcceptResult = listenSocket.BeginAccept(new AsyncCallback(ListenCallback), null);

 

Thanks.

"Being grown up isn't half as fun as growing up

These are the best days of our lives"

-The Ataris, In This Diary

  • *Experts*
Posted

I have tried each and both of these methods, with no success.

 

Calling Shutdown first raises a SocketError when I try to Close or

dispose of the Socket, quote, "A request to send or receive data

was disallowed because the socket is not connected and (when

sending on a datagram socket using a sendto call) no address

was supplied".

 

Just calling Close raises an InvalidOperationException that only

says "AcceptCallback", and it points to a location in the

disassembly, though Close is what causes it.

"Being grown up isn't half as fun as growing up

These are the best days of our lives"

-The Ataris, In This Diary

  • *Experts*
Posted

EndAccept never gets a chance to be called. When calling

Shutdown, the error points to the line

listenSocket = null;

 

When calling Close, there is only a disassembly location for the error.

"Being grown up isn't half as fun as growing up

These are the best days of our lives"

-The Ataris, In This Diary

  • 4 weeks later...
Posted

You could always cheat and set a flag to specify whether the code within the EndInvoke is executed or not.

 

private bool flag = true;

private void EndCallback(IAsyncResult result){

if(flag){

..... execute code....

}

 

}

  • *Experts*
Posted

Yes, but then I cannot call Close and then Listen on the same

port, because a socket will still be bound to that port.

"Being grown up isn't half as fun as growing up

These are the best days of our lives"

-The Ataris, In This Diary

  • 3 weeks later...
  • 11 months later...
Posted

How to cancel asynchronous socket accept calls.

 

Right firstly, Bucky.

When you call close on an accepting socket, the asynchronous request is triggered as completed with an invalid socket, therefore when your program calls EndAccept it tries to access a non-existant socket and causes the EndAccept exception.

 

As Rodenburg suggested a flag can be used to catch when this occurs so that you don't call EndAccept in these cases. However there is another way.

 

The IAsyncResult parameter that is passed to the function contains the data about the socket that accepts the connection. I.e. A member of IAsyncResult contains the socket returned by EndAccept. This member is AsyncState. If you cast this to a socket, then you can look at the underlining handle for the socket to see if it is valid (>= 0) or invalid (-1). If the handle is -1 then the accept call was cancelled.

 

Example....

 

private void AcceptSmtp(IAsyncResult ar)

{

Socket test = (Socket)ar.AsyncState; // Cast the result to a socket.

if (test.Handle.ToInt32() == -1) // Check if the handle is invalid.

{

return; // Exit as the call was cancelled.

}

 

// If we get here then this is an actual accept.

Socket client = smtpListener.EndAccept(ar); // Get the socket.

 

........

}

 

Hope this helps you all, Mike Nimmo.

Posted
As a quick update, it appears that EndAccept must be called within the asynchronous function but if the socket is invalid then you can call EndAccept within a trap.
Posted (edited)

Actually, I've never encountered that problem.

 

To close down the listening socket:

 

if (serverThread != null)
		{
			if (serverThread.IsAlive)
			{
				if (listeningSocket.Connected)
				{
					listeningSocket.Shutdown(System.Net.Sockets.SocketShutdown.Both);
					listeningSocket.Close();
				}

				serverThread.Abort();
			}
		}

 

 

When calling BeginAccept, why do you save the AsyncResult? The AsyncResult is passed to the EventHandling function.

 

 

Try:

 

private static System.Threading.ManualResetEvent allDone = new System.Threading.ManualResetEvent(false);

 

while (true)

{

allDone.Reset();

listeningSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);

allDone.WaitOne();

}

 

private void AcceptCallback(IAsyncResult ar)

{

allDone.Set();

socket = listeningSocket.EndAccept(ar);

}

Edited by Diesel

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...