PC Review


Reply
Thread Tools Rate Thread

How to do Async TCP Listener?

 
 
Terry Olsen
Guest
Posts: n/a
 
      21st Nov 2004
I've tried the following code straight out of MSDN. But my app still blocks
while listening. Isn't this code supposed to keep the UI responsive while
listening? Or maybe I'm not doing it right.... any help is begged for ;-)

Public Class Listener

Public Event Connected(ByVal client As TcpClient)
Public ClientConnected As New ManualResetEvent(False)

Public Sub DoBeginAcceptTcpClient()
Dim myListener As New TcpListener(IPAddress.Parse("127.0.0.1"), 23)
myListener.Start()
ClientConnected.Reset()
myListener.BeginAcceptTcpClient(New AsyncCallback(AddressOf
DoAcceptTcpClientCallback), myListener)
ClientConnected.WaitOne()
End Sub

Public Sub DoAcceptTcpClientCallback(ByVal ar As IAsyncResult)
Dim myListener As TcpListener = CType(ar.AsyncState, TcpListener)
Dim client As TcpClient = myListener.EndAcceptTcpClient(ar)
RaiseEvent Connected(client)
ClientConnected.Set()
End Sub

End Class


 
Reply With Quote
 
 
 
 
Michael D. Ober
Guest
Posts: n/a
 
      21st Nov 2004
I suspect your listening socket is a "blocking" socket (not always obvious)
that the OS is running in an internal thread for you. If so, your client
socket that is created during the accept function will also be blocking. To
fix this, issue a socket ioctl call to the new client socket immediately
after the accept to switch it from blocking to non-blocking.

Mike Ober.

"Terry Olsen" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> I've tried the following code straight out of MSDN. But my app still

blocks
> while listening. Isn't this code supposed to keep the UI responsive while
> listening? Or maybe I'm not doing it right.... any help is begged for

;-)
>
> Public Class Listener
>
> Public Event Connected(ByVal client As TcpClient)
> Public ClientConnected As New ManualResetEvent(False)
>
> Public Sub DoBeginAcceptTcpClient()
> Dim myListener As New TcpListener(IPAddress.Parse("127.0.0.1"),

23)
> myListener.Start()
> ClientConnected.Reset()
> myListener.BeginAcceptTcpClient(New AsyncCallback(AddressOf
> DoAcceptTcpClientCallback), myListener)
> ClientConnected.WaitOne()
> End Sub
>
> Public Sub DoAcceptTcpClientCallback(ByVal ar As IAsyncResult)
> Dim myListener As TcpListener = CType(ar.AsyncState, TcpListener)
> Dim client As TcpClient = myListener.EndAcceptTcpClient(ar)
> RaiseEvent Connected(client)
> ClientConnected.Set()
> End Sub
>
> End Class
>
>



 
Reply With Quote
 
Terry Olsen
Guest
Posts: n/a
 
      21st Nov 2004
How do I create a listener that doesn't block? I want to be able to stop
the listner from my app, but the app is locked up while it's listening.


"Michael D. Ober" <obermd.@.alum.mit.edu.nospam> wrote in message
news:(E-Mail Removed)...
>I suspect your listening socket is a "blocking" socket (not always obvious)
> that the OS is running in an internal thread for you. If so, your client
> socket that is created during the accept function will also be blocking.
> To
> fix this, issue a socket ioctl call to the new client socket immediately
> after the accept to switch it from blocking to non-blocking.
>
> Mike Ober.
>
> "Terry Olsen" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> I've tried the following code straight out of MSDN. But my app still

> blocks
>> while listening. Isn't this code supposed to keep the UI responsive
>> while
>> listening? Or maybe I'm not doing it right.... any help is begged for

> ;-)
>>
>> Public Class Listener
>>
>> Public Event Connected(ByVal client As TcpClient)
>> Public ClientConnected As New ManualResetEvent(False)
>>
>> Public Sub DoBeginAcceptTcpClient()
>> Dim myListener As New TcpListener(IPAddress.Parse("127.0.0.1"),

> 23)
>> myListener.Start()
>> ClientConnected.Reset()
>> myListener.BeginAcceptTcpClient(New AsyncCallback(AddressOf
>> DoAcceptTcpClientCallback), myListener)
>> ClientConnected.WaitOne()
>> End Sub
>>
>> Public Sub DoAcceptTcpClientCallback(ByVal ar As IAsyncResult)
>> Dim myListener As TcpListener = CType(ar.AsyncState, TcpListener)
>> Dim client As TcpClient = myListener.EndAcceptTcpClient(ar)
>> RaiseEvent Connected(client)
>> ClientConnected.Set()
>> End Sub
>>
>> End Class
>>
>>

>
>



 
Reply With Quote
 
Michael D. Ober
Guest
Posts: n/a
 
      21st Nov 2004
You need to derive a new object from your listening socket object. There is
an overridable "OnAccept" event in VB6's WINSOCK.ocs and in the MFC
CAsyncSocket class so there should be one in .Net as well.

Mike.

"Terry Olsen" <(E-Mail Removed)> wrote in message
news:OdEgVg%(E-Mail Removed)...
> How do I create a listener that doesn't block? I want to be able to stop
> the listner from my app, but the app is locked up while it's listening.
>
>
> "Michael D. Ober" <obermd.@.alum.mit.edu.nospam> wrote in message
> news:(E-Mail Removed)...
> >I suspect your listening socket is a "blocking" socket (not always

obvious)
> > that the OS is running in an internal thread for you. If so, your

client
> > socket that is created during the accept function will also be blocking.
> > To
> > fix this, issue a socket ioctl call to the new client socket immediately
> > after the accept to switch it from blocking to non-blocking.
> >
> > Mike Ober.
> >
> > "Terry Olsen" <(E-Mail Removed)> wrote in message
> > news:(E-Mail Removed)...
> >> I've tried the following code straight out of MSDN. But my app still

> > blocks
> >> while listening. Isn't this code supposed to keep the UI responsive
> >> while
> >> listening? Or maybe I'm not doing it right.... any help is begged for

> > ;-)
> >>
> >> Public Class Listener
> >>
> >> Public Event Connected(ByVal client As TcpClient)
> >> Public ClientConnected As New ManualResetEvent(False)
> >>
> >> Public Sub DoBeginAcceptTcpClient()
> >> Dim myListener As New TcpListener(IPAddress.Parse("127.0.0.1"),

> > 23)
> >> myListener.Start()
> >> ClientConnected.Reset()
> >> myListener.BeginAcceptTcpClient(New AsyncCallback(AddressOf
> >> DoAcceptTcpClientCallback), myListener)
> >> ClientConnected.WaitOne()
> >> End Sub
> >>
> >> Public Sub DoAcceptTcpClientCallback(ByVal ar As IAsyncResult)
> >> Dim myListener As TcpListener = CType(ar.AsyncState,

TcpListener)
> >> Dim client As TcpClient = myListener.EndAcceptTcpClient(ar)
> >> RaiseEvent Connected(client)
> >> ClientConnected.Set()
> >> End Sub
> >>
> >> End Class
> >>
> >>

> >
> >

>
>



 
Reply With Quote
 
Tom Shelton
Guest
Posts: n/a
 
      23rd Nov 2004
On 2004-11-21, Terry Olsen <(E-Mail Removed)> wrote:
> I've tried the following code straight out of MSDN. But my app still blocks
> while listening. Isn't this code supposed to keep the UI responsive while
> listening? Or maybe I'm not doing it right.... any help is begged for ;-)
>
> Public Class Listener
>
> Public Event Connected(ByVal client As TcpClient)
> Public ClientConnected As New ManualResetEvent(False)
>
> Public Sub DoBeginAcceptTcpClient()
> Dim myListener As New TcpListener(IPAddress.Parse("127.0.0.1"), 23)
> myListener.Start()
> ClientConnected.Reset()
> myListener.BeginAcceptTcpClient(New AsyncCallback(AddressOf
> DoAcceptTcpClientCallback), myListener)
> ClientConnected.WaitOne()
> End Sub
>
> Public Sub DoAcceptTcpClientCallback(ByVal ar As IAsyncResult)
> Dim myListener As TcpListener = CType(ar.AsyncState, TcpListener)
> Dim client As TcpClient = myListener.EndAcceptTcpClient(ar)
> RaiseEvent Connected(client)
> ClientConnected.Set()
> End Sub
>
> End Class
>
>


Unless your DoBeginAcceptTcpClient () method is on a separate thread,
then it will block - but not at the BeginAcceptTcpClient, but at the
ClientConnected.WaitOne ().

Normally, I would start listening on a separate thread, and do something
like:

Do While Until Terminate
ClientConnected.Reset()
MyListener.BeginAccept......
ClientConnected.WaiteOne ()
Loop

This way, you can handle multiple clients, and you won't block the main
thead. When you need to kill the thread, just close the listener...

Don't ask me any specifics about TcpListener/Client - I never use them.
I always use the Socket class in System.Net.Sockets

--
Tom Shelton [MVP]
 
Reply With Quote
 
Terry Olsen
Guest
Posts: n/a
 
      23rd Nov 2004
Speaking of the ManualResetEvent...what's it used for? I commented out all
the "ClientConnected.x" code and the listener still worked fine...without
blocking at all...

"Tom Shelton" <(E-Mail Removed)> wrote in message
news:upDf1$(E-Mail Removed)...
> On 2004-11-21, Terry Olsen <(E-Mail Removed)> wrote:
>> I've tried the following code straight out of MSDN. But my app still
>> blocks
>> while listening. Isn't this code supposed to keep the UI responsive
>> while
>> listening? Or maybe I'm not doing it right.... any help is begged for
>> ;-)
>>
>> Public Class Listener
>>
>> Public Event Connected(ByVal client As TcpClient)
>> Public ClientConnected As New ManualResetEvent(False)
>>
>> Public Sub DoBeginAcceptTcpClient()
>> Dim myListener As New TcpListener(IPAddress.Parse("127.0.0.1"),
>> 23)
>> myListener.Start()
>> ClientConnected.Reset()
>> myListener.BeginAcceptTcpClient(New AsyncCallback(AddressOf
>> DoAcceptTcpClientCallback), myListener)
>> ClientConnected.WaitOne()
>> End Sub
>>
>> Public Sub DoAcceptTcpClientCallback(ByVal ar As IAsyncResult)
>> Dim myListener As TcpListener = CType(ar.AsyncState, TcpListener)
>> Dim client As TcpClient = myListener.EndAcceptTcpClient(ar)
>> RaiseEvent Connected(client)
>> ClientConnected.Set()
>> End Sub
>>
>> End Class
>>
>>

>
> Unless your DoBeginAcceptTcpClient () method is on a separate thread,
> then it will block - but not at the BeginAcceptTcpClient, but at the
> ClientConnected.WaitOne ().
>
> Normally, I would start listening on a separate thread, and do something
> like:
>
> Do While Until Terminate
> ClientConnected.Reset()
> MyListener.BeginAccept......
> ClientConnected.WaiteOne ()
> Loop
>
> This way, you can handle multiple clients, and you won't block the main
> thead. When you need to kill the thread, just close the listener...
>
> Don't ask me any specifics about TcpListener/Client - I never use them.
> I always use the Socket class in System.Net.Sockets
>
> --
> Tom Shelton [MVP]



 
Reply With Quote
 
tcarvin
Guest
Posts: n/a
 
      23rd Nov 2004
It was the "ClientConnected.WaitOne()" that caused you to block.

The ManualResetEvent is an object that lets a thread sleep until the "Set"
is called. The problem you hit is that you called WaitOne() from your UI
thread. You should have called that from a worker (listener) thread, like in
Tom's example.

Regards,
Tom C

"Terry Olsen" <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>...
> Speaking of the ManualResetEvent...what's it used for? I commented out all
> the "ClientConnected.x" code and the listener still worked fine...without
> blocking at all...
>

 
Reply With Quote
 
Terry Olsen
Guest
Posts: n/a
 
      24th Nov 2004
Can you tell me why I would need a ManualResetEvent at all (in this
particular situation)? I removed it and now everything seems to work fine.


"tcarvin" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> It was the "ClientConnected.WaitOne()" that caused you to block.
>
> The ManualResetEvent is an object that lets a thread sleep until the "Set"
> is called. The problem you hit is that you called WaitOne() from your UI
> thread. You should have called that from a worker (listener) thread, like
> in
> Tom's example.
>
> Regards,
> Tom C
>
> "Terry Olsen" <(E-Mail Removed)> wrote in message
> news:<(E-Mail Removed)>...
>> Speaking of the ManualResetEvent...what's it used for? I commented out
>> all
>> the "ClientConnected.x" code and the listener still worked fine...without
>> blocking at all...
>>



 
Reply With Quote
 
tcarvin
Guest
Posts: n/a
 
      29th Nov 2004
Terry,

In this particular situation (because you are using a callback and don't
need/want to "wait" for a connection, you do not need to use one.

(Be careful in your callback though, because it is called from a non-GUI
thread and you must use Invoke() to update GUI components),

Regards,
Tom C.

"Terry Olsen" <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>...
> Can you tell me why I would need a ManualResetEvent at all (in this
> particular situation)? I removed it and now everything seems to work fine.
>
>
> "tcarvin" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
> > It was the "ClientConnected.WaitOne()" that caused you to block.
> >
> > The ManualResetEvent is an object that lets a thread sleep until the "Set"
> > is called. The problem you hit is that you called WaitOne() from your UI
> > thread. You should have called that from a worker (listener) thread, like
> > in
> > Tom's example.
> >
> > Regards,
> > Tom C
> >
> > "Terry Olsen" <(E-Mail Removed)> wrote in message
> > news:<(E-Mail Removed)>...
> >> Speaking of the ManualResetEvent...what's it used for? I commented out
> >> all
> >> the "ClientConnected.x" code and the listener still worked fine...without
> >> blocking at all...
> >>

 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Connect without async but get timeout error when async=true Joseph Microsoft ADO .NET 5 16th Jul 2008 10:13 PM
writing an async client (sockets/async/thread) asharda@woh.rr.com Microsoft C# .NET 8 17th Mar 2008 10:04 PM
Any harm in using Async=true to sql server 2005 for non-async db calls Chris Becker Microsoft ADO .NET 1 23rd Mar 2007 12:18 AM
Async in asp.net 2.0 and async application block =?Utf-8?B?TGVuZWlzZTQ0?= Microsoft Dot NET 2 4th Jan 2006 03:41 AM
Async TCPClient / TCP Listener Sagaert Johan Microsoft C# .NET 3 14th Feb 2004 11:15 AM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 02:44 AM.