locked
TcpClient.BeginAcceptTcpClient / Socket.BeginAccept / all other variations...

    Question

  • First, I'm sorry for the cross-post...I didn't see the networking forum, so I posted into the vb.net forum.

    I've been having a problem with the use of any of the async methods of TcpClient, Socket, etc eating >95% cpu after receiving the first connection.  I've been working on this for over a week now and I'm unable to find references to this issue anywhere.  I've tried every way I can think of to work around this problem.

    Even if no data is sent or received on the connection....or if I close the received connection -- some unknown thread uses all the available cpu power after the first connection occurs.

    I created a small project that reproduces the problem -- I've zipped it up and posted it here:

    http://www.profitfuel.net/TcpClientProblem.zip

    If anyone can confirm they have this problem on their machine....or if anyone knows how to fix this issue, please let me know.

    Thanks,
    - Joshua Garvin

    dimanche 24 septembre 2006 19:02

Réponses

  • Hello,

    I have downloaded your code, Unfortunately, It was in VB and I donnt have installed it. Anyhow I opend the files in notepad and had a look on MyServer class in NetworkTest.vb file.

    I found this block Strange:

    Shadows Sub Start(ByVal backlog As Integer)
        MyBase.Start()

        For i As Integer = 0 To 10
          MyBase.BeginAcceptTcpClient(m_AcceptDelegate, Nothing)
        Next
      End Sub

    First of all, BackLog property doesnot require work on your end i.e if you need to set Backlog pass it in Start of TcpListener class like

    MyBase.Start(10); // It'll automatically que the ne incoming clients.

    And you dont need to Loop and Call BeginAccept() 10 times. It's ok When one client is done with its connection then It'll call BeginAccept() again. i.e in

    Private Sub AcceptCallback(ByVal result As IAsyncResult)
        Try
          If MyBase.Active Then

            Dim MyClient As TcpClient = MyBase.EndAcceptTcpClient(result)
            RaiseEvent ClientConnected(MyClient, New EventArgs())

            MyBase.BeginAcceptTcpClient(m_AcceptDelegate, Nothing)
          End If
        Catch ex As SocketException
          Console.WriteLine("Socket exception: " & ex.SocketErrorCode)

        Catch ex As Exception
          Console.WriteLine("Exception: " & ex.ToString)
        End Try
      End Sub

    The other way, I personally use for listening clients only is the Syncrhonous way of accepting clients that is AcceptTcpClient() or AcceptSocket() in a while loop in a thread respectively.

    Like

    Thread threadListen = new Thread(AcceptClients);

    threadListen.Start();

    private void AcceptClients()

    {

             Listener.Start();

            while(true)

            {

                  TcpClient client = listener.AcceptTcpClient();

                  // Do stuff like attach events so on...

             }

    }

     

    Try Removing this Loop and call BeginAccept once and see what happens

        For i As Integer = 0 To 10
          MyBase.BeginAcceptTcpClient(m_AcceptDelegate, Nothing)
        Next

    I really hope this is the only fault with your code and get back if you have +ve or -ve response.

    Best of luck ;-)

    dimanche 24 septembre 2006 20:08

Toutes les réponses

  • Hello,

    I have downloaded your code, Unfortunately, It was in VB and I donnt have installed it. Anyhow I opend the files in notepad and had a look on MyServer class in NetworkTest.vb file.

    I found this block Strange:

    Shadows Sub Start(ByVal backlog As Integer)
        MyBase.Start()

        For i As Integer = 0 To 10
          MyBase.BeginAcceptTcpClient(m_AcceptDelegate, Nothing)
        Next
      End Sub

    First of all, BackLog property doesnot require work on your end i.e if you need to set Backlog pass it in Start of TcpListener class like

    MyBase.Start(10); // It'll automatically que the ne incoming clients.

    And you dont need to Loop and Call BeginAccept() 10 times. It's ok When one client is done with its connection then It'll call BeginAccept() again. i.e in

    Private Sub AcceptCallback(ByVal result As IAsyncResult)
        Try
          If MyBase.Active Then

            Dim MyClient As TcpClient = MyBase.EndAcceptTcpClient(result)
            RaiseEvent ClientConnected(MyClient, New EventArgs())

            MyBase.BeginAcceptTcpClient(m_AcceptDelegate, Nothing)
          End If
        Catch ex As SocketException
          Console.WriteLine("Socket exception: " & ex.SocketErrorCode)

        Catch ex As Exception
          Console.WriteLine("Exception: " & ex.ToString)
        End Try
      End Sub

    The other way, I personally use for listening clients only is the Syncrhonous way of accepting clients that is AcceptTcpClient() or AcceptSocket() in a while loop in a thread respectively.

    Like

    Thread threadListen = new Thread(AcceptClients);

    threadListen.Start();

    private void AcceptClients()

    {

             Listener.Start();

            while(true)

            {

                  TcpClient client = listener.AcceptTcpClient();

                  // Do stuff like attach events so on...

             }

    }

     

    Try Removing this Loop and call BeginAccept once and see what happens

        For i As Integer = 0 To 10
          MyBase.BeginAcceptTcpClient(m_AcceptDelegate, Nothing)
        Next

    I really hope this is the only fault with your code and get back if you have +ve or -ve response.

    Best of luck ;-)

    dimanche 24 septembre 2006 20:08
  • Very interesting -- everything works fine now.

    Originally I had written this same sort of code using the Sockets.Socket object based on the msdn article I found here.  (The full article, by Daryn Kiely, is here.)

    At any rate, I had the same issue with the Socket code as I have with this code.  Is the code in the article just busted?

    Thanks,
    - Josh

    dimanche 24 septembre 2006 22:34
  •  Joshua Garvin wrote:

    At any rate, I had the same issue with the Socket code as I have with this code.  Is the code in the article just busted?

    Thanks,
    - Josh

    Hello Josh, I'm happy your work is going on. The article you mentioned  is named High Performance Sockets and is published on MSDN. I dont think so anything can be published without any review on MSDN. I did not have time to check it but I'll surely check it very soon when have some free time.

    Cheers ;-)

    dimanche 24 septembre 2006 23:32
  • By the way, thanks for all your help.  I tried clicking on the "Mark As Answer" button on your post, but it keeps saying an error has occurred in the forum and the administrator has been notified.

    Thanks again,
    - Josh

    dimanche 24 septembre 2006 23:58
  • Lol, its ok and your queries are always welcome @ r.ahmed@protectstar.com and rizwansharp@hotmail.com

    Wish you best of luck.

    Cheers ;-)

    lundi 25 septembre 2006 00:16
  • I had the very same problems. The strange thing is that it works very good on my PC, while on others it eats the CPU. Also it mess the socket blocking type somehow. With that loop they will always react as non-blocking and syncronized reading will fail.
    lundi 25 septembre 2006 15:21