Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / New Users / July 2006

Tip: Looking for answers? Try searching our database.

Waiting for incoming data on multiple sockets

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Markus Ewald - 21 Jul 2006 09:29 GMT
Hi!

Using the System.Net.Sockets.Socket class, how am I supposed to wait for
incoming data?

If, for example, I've got a large number of connections that all need to
be monitored for incoming data, do I have to call BeginReceive() for
each socket (possibly producing 50 background threads assuming a naive
socket implementation) and then spawn another 50 threads myself for
blocking on the EndReceive() methods of all the sockets?

Back in C++ I had a shared monitoring thread which blocked by calling
WaitForMultipleObjects() on an array of all the sockets.

I think I could reimplement this concept in .NET using the WaitHandles
provided by the AsyncResult class that is returned from
Socket.BeginReceive(). Is that the way to go?

Thanks,
-Markus-
Barry Kelly - 21 Jul 2006 10:54 GMT
> Using the System.Net.Sockets.Socket class, how am I supposed to wait for
> incoming data?
[quoted text clipped - 3 lines]
> each socket (possibly producing 50 background threads assuming a naive
> socket implementation)

The socket implementation is not naive in that way, it uses asynchronous
I/O instead.

> and then spawn another 50 threads myself for
> blocking on the EndReceive() methods of all the sockets?

I personally find it much easier to pass a callback to the BeginReceive
method. That way, a thread will be allocated from the threadpool only
when some data arrives.

> Back in C++ I had a shared monitoring thread which blocked by calling
> WaitForMultipleObjects() on an array of all the sockets.

That sounds like a Windows-ism for the BSD select() call. You can do
that via Socket.Select, if you wish - it won't be as performant as the
callback, though, and you have a potential socket starvation problem for
sockets towards the end of the array.

> I think I could reimplement this concept in .NET using the WaitHandles
> provided by the AsyncResult class that is returned from
> Socket.BeginReceive(). Is that the way to go?

I wouldn't recommend it, no. In C# 2.0 I'd use anonymous delegates to
simulate continuation passing style code, passing the anonymous delegate
as the callback to the BeginReceive method.

-- Barry

Signature

http://barrkel.blogspot.com/

Chris Mullins - 21 Jul 2006 18:15 GMT
> If, for example, I've got a large number of connections that all need to
> be monitored for incoming data, do I have to call BeginReceive() for each
> socket (possibly producing 50 background threads assuming a naive socket
> implementation) and then spawn another 50 threads myself for blocking on
> the EndReceive() methods of all the sockets?

Call BeginReceive on all 50 sockets, and pass in a callback function. For
good luck, pass in the actual socket as state.

When your callback hits, call EndReceive, pull out the data, and proceed.

For more details on this than you ever wanted:
http://makeashorterlink.com/?R2EE5246D

--
Chris Mullins
http://www.coversant.net/blogs/cmullins
Markus Ewald - 24 Jul 2006 08:11 GMT
>> If, for example, I've got a large number of connections that all need to
>> be monitored for incoming data, do I have to call BeginReceive() for each
[quoted text clipped - 6 lines]
>
> When your callback hits, call EndReceive, pull out the data, and proceed.

Thanks Barry and Chris, sounds like the callback is the way to go.

Just to sum it up:
- Call BeginReceive() on all the sockets, passing a callback function to
handle incoming data
- Do *not* call EndReceive() in the callback function so that it will be
triggered again when new data arrives (?)
- When the application needs to terminate, call Close() on each socket
and skip the EndReceive() call.

I think the MSDN documentation on this is rather scarce. What if, for
example, new data arrives while my callback is executing? Will the
callback be entered again immediately after it finishes?

-Markus-
Barry Kelly - 24 Jul 2006 09:27 GMT
> - Call BeginReceive() on all the sockets, passing a callback function to
> handle incoming data
> - Do *not* call EndReceive() in the callback function so that it will be
> triggered again when new data arrives (?)

No, you DO call EndReceive() in the callback. You must, in general for
any Begin*/End* pair, in order to get any return value or out
parameters, and in order to free resources associated with the
IAsyncResult. You call BeginReceive() again in the callback once you're
done processing / queuing for processing the data you've just received.

> - When the application needs to terminate, call Close() on each socket
> and skip the EndReceive() call.

You should call Shutdown() and close both sides of the connection
instead. You can safely call Shutdown() on any thread, as long as the
socket isn't closed. That will cause the Receive() to receive 0 bytes,
which is part of the normal clean TCP shutdown sequence. You should call
Close() in a thread that logically owns the socket, or at the very least
in a thread which isn't logically blocking on the socket (I'm including
a pending callback from a Begin* call as "logically blocking"). So,
typically, you'll call Close() on the socket in the callback when you
receive 0 bytes.

> I think the MSDN documentation on this is rather scarce. What if, for
> example, new data arrives while my callback is executing? Will the
> callback be entered again immediately after it finishes?

You need to play with it, to get a feel for how it works. I advise
writing a test application pair with socket server & client, in order to
get a feel for how it all works. You may need to develop some
abstractions to get it all to work together nicely, I know I did.

Coordinating clean shutdowns and handling exceptions gracefully are
probably the two harder parts of asynchronous socket programming, IMHO,
once you've gotten your head around the continuation-passing-style
nature of callback-based .NET async.

-- Barry

Signature

http://barrkel.blogspot.com/


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.