.NET Sockets and asynchronous disconnects
.NET Sockets and asynchronous disconnects
.NET Sockets and asynchronous disconnects
.NET Sockets and asynchronous disconnects
.NET Sockets and asynchronous disconnects
.NET Sockets and asynchronous disconnects .NET Sockets and asynchronous disconnects .NET Sockets and asynchronous disconnects .NET Sockets and asynchronous disconnects .NET Sockets and asynchronous disconnects .NET Sockets and asynchronous disconnects .NET Sockets and asynchronous disconnects .NET Sockets and asynchronous disconnects
.NET Sockets and asynchronous disconnects .NET Sockets and asynchronous disconnects
.NET Sockets and asynchronous disconnects
Go Back  Xtreme Visual Basic Talk > > > .NET Sockets and asynchronous disconnects


Reply
 
Thread Tools Display Modes
  #1  
Old 10-02-2007, 11:28 AM
gayouj's Avatar
gayouj.NET Sockets and asynchronous disconnects gayouj is offline
Junior Contributor

* Expert *
 
Join Date: Jan 2006
Location: California
Posts: 317
Unhappy .NET Sockets and asynchronous disconnects


Okay, I've seen this question asked before but without any definite answer. I'm doing a BeginDisconnect on an asynchronous socket and it's taking a ridiculously long time to complete. I'm using the following code to accomplish this:

Code:
        Public Sub Disconnect()
            Try
                m_Socket.Shutdown(SocketShutdown.Both)
                m_Socket.BeginDisconnect(True, New AsyncCallback(AddressOf DisconnectCallback), m_Socket)
                disconnectDone.WaitOne()
            Catch ex As Exception
                RaiseEvent Exception(ex)
            End Try
        End Sub


        Private Shared Sub DisconnectCallback(ByVal ar As IAsyncResult)
            Dim client As Socket = CType(ar.AsyncState, Socket)

            Try
                client.EndDisconnect(ar)
            Catch ex As Exception
                RaiseEvent Exception(ex)
            End Try

            disconnectDone.Set()
        End Sub
It's taking forever! Has anyone ever managed to solve this before (short of disabling adaptors)? I refuse to believe that we just have to live with this, especially when the old Winsock control could accomplish this immediately.

Thanks for any help you might be able to provide.
__________________
http://www.joshuagayou.com
Reply With Quote
  #2  
Old 10-03-2007, 11:29 AM
gayouj's Avatar
gayouj.NET Sockets and asynchronous disconnects gayouj is offline
Junior Contributor

* Expert *
 
Join Date: Jan 2006
Location: California
Posts: 317
Default BeginDisconnect

Actually, on further testing, I'm seeing that my problem is the BeginDisconnect method. Can anyone tell me the correct way to disconnect a TCP connection on a reusable socket? Because I don't seem to be getting it right.

Code follows:

Code:
Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Imports System.Text
Imports X.Lists

Namespace Communication

    Public Class EthClient

        ' Asynch callback methods
        Private Shared connectDone As New ManualResetEvent(False)
        Private Shared sendDone As New ManualResetEvent(False)
        Private Shared receiveDone As New ManualResetEvent(False)
        Private Shared disconnectDone As New ManualResetEvent(False)

        ' Socket characteristics
        Private Shared m_Family As AddressFamily = AddressFamily.InterNetwork
        Private Shared m_Type As SocketType = SocketType.Stream
        Private Shared m_Protocol As ProtocolType = ProtocolType.Tcp

        Private Shared m_RemoteHost As String = String.Empty
        Private Shared m_Port As Integer
        Private Shared m_Socket As New Socket(m_Family, m_Type, m_Protocol)

        Private Shared m_RcvByteThreshold As Integer = 4
        Private Shared WithEvents m_Buffer As CommBuffer

        Public Shared Event Err(ByVal Description As String)
        Public Shared Event DataReceived(ByVal Length As Integer)
        Public Shared Event Exception(ByVal ex As System.Exception)
        Public Shared Event Connected()

        '--------------------------------------------------------------------------------------------
        ' Constructor/Destructor
        '============================================================================================

        Public Sub New()
            Initialize(E_BUFFER_DATA_TYPES.eByte)
        End Sub

        Public Sub New(ByVal BufferFormat As CommDefs.E_BUFFER_DATA_TYPES)
            Initialize(BufferFormat)
        End Sub

        '--------------------------------------------------------------------------------------------
        ' Events
        '============================================================================================

        Private Shared Sub m_Buffer_Err(ByVal Description As String) Handles m_Buffer.Err
            RaiseEvent Err("EthClient::m_Buffer::Err - " + Description)
        End Sub

        Private Shared Sub m_Buffer_Exception(ByVal ex As System.Exception) Handles m_Buffer.Exception
            RaiseEvent Exception(ex)
        End Sub

        '--------------------------------------------------------------------------------------------
        ' Properties
        '============================================================================================

        Public Property RemoteHost() As String
            Get
                Return m_RemoteHost
            End Get
            Set(ByVal value As String)
                m_RemoteHost = value
            End Set
        End Property

        Public Property RemotePort() As Integer
            Get
                Return m_Port
            End Get
            Set(ByVal value As Integer)
                m_Port = value
            End Set
        End Property

        Public ReadOnly Property IsConnected() As Boolean
            Get
                Return m_Socket.Connected
            End Get
        End Property

        Public ReadOnly Property Buffer() As CommBuffer
            Get
                Return m_Buffer
            End Get
        End Property

        Public Property RxThreshold() As Integer
            Get
                Return m_RcvByteThreshold
            End Get
            Set(ByVal value As Integer)
                m_RcvByteThreshold = value
            End Set
        End Property

        Public Property SocketObject() As Socket
            Get
                Return m_Socket
            End Get
            Set(ByVal value As Socket)
                m_Socket = value

                If (m_Socket.Connected) Then
                    StartReceiving()
                End If
            End Set
        End Property

        '--------------------------------------------------------------------------------------------
        ' Methods
        '============================================================================================

        Public Function Clone() As EthClient
            Return Me.MemberwiseClone()
        End Function

        Public Function BytesToString(ByVal Data() As Byte) As String
            Return Encoding.ASCII.GetString(Data, 0, Data.Length)
        End Function

        Public Function Connect(ByVal RemoteHost As String, ByVal RemotePort As Integer) As Boolean

            m_RemoteHost = RemoteHost
            m_Port = RemotePort

            ' Get an address for the remote host.
            Dim HostInfo As IPHostEntry = Dns.GetHostEntry(m_RemoteHost)
            Dim Address As IPAddress = HostInfo.AddressList(0)

            ' Setup a remote endpoint.
            Dim EndPt As New IPEndPoint(Address, m_Port)

            Return ConnectToHost(EndPt)

        End Function

        Public Function Connect() As Boolean
            ' Get an address for the remote host.
            Dim HostInfo As IPHostEntry = Dns.GetHostEntry(m_RemoteHost)
            Dim Address As IPAddress = HostInfo.AddressList(0)

            ' Setup a remote endpoint.
            Dim EndPt As New IPEndPoint(Address, m_Port)

            Return ConnectToHost(EndPt)
        End Function

        Public Sub Disconnect()
            Try
                m_Socket.Shutdown(SocketShutdown.Both)
                m_Socket.BeginDisconnect(True, New AsyncCallback(AddressOf DisconnectCallback), m_Socket)
                disconnectDone.WaitOne()
            Catch ex As Exception
                RaiseEvent Exception(ex)
            End Try
        End Sub

        Public Function Send(ByVal Data As String) As Boolean
            If (Not (m_Socket.Connected)) Then Return False
            Dim byteData As Byte() = Encoding.ASCII.GetBytes(Data)
            Return SendToHost(byteData)
        End Function

        Public Function Send(ByVal Data() As Byte) As Boolean
            If (Not (m_Socket.Connected)) Then Return False
            Return SendToHost(Data)
        End Function

        '--------------------------------------------------------------------------------------------
        ' Private Methods
        '============================================================================================

        Private Shared Sub StartReceiving()
            If (Not (m_Socket.Connected)) Then Exit Sub

            Try
                ' Create the state object.
                Dim state As New EthStateObject
                state.WorkerSocket = m_Socket

                ' Begin receiving the data from the remote device.
                m_Socket.BeginReceive(state.Buffer, 0, EthStateObject.BufferSize, 0, New AsyncCallback(AddressOf ReceiveCallback), state)
            Catch ex As Exception
                RaiseEvent Exception(ex)
            End Try
        End Sub

        Private Function SendToHost(ByVal Data() As Byte) As Boolean
            Try
                m_Socket.BeginSend(Data, 0, Data.Length, 0, New AsyncCallback(AddressOf SendCallback), m_Socket)
            Catch ex As Exception
                RaiseEvent Exception(ex)
                Return False
            End Try

            Return True

        End Function

        Private Function ConnectToHost(ByRef HostEndPoint As IPEndPoint) As Boolean
            Try
                connectDone.Reset()
                m_Socket.BeginConnect(HostEndPoint, New AsyncCallback(AddressOf ConnectCallback), m_Socket)
                connectDone.WaitOne()
            Catch ex As SocketException

                RaiseEvent Exception(ex)
                Return False
            End Try

            Return True

        End Function

        Private Shared Sub ConnectCallback(ByVal ar As IAsyncResult)
            ' Retrieve the socket from the state object.
            Dim client As Socket = CType(ar.AsyncState, Socket)

            Try
                ' Complete the connection.
                client.EndConnect(ar)
                RaiseEvent Connected()
                StartReceiving()
            Catch ex As Exception
                RaiseEvent Exception(ex)
            End Try

            ' Signal that the connection has been made.
            connectDone.Set()
        End Sub
__________________
http://www.joshuagayou.com
Reply With Quote
  #3  
Old 10-03-2007, 11:30 AM
gayouj's Avatar
gayouj.NET Sockets and asynchronous disconnects gayouj is offline
Junior Contributor

* Expert *
 
Join Date: Jan 2006
Location: California
Posts: 317
Default Continued

(Continued)

Code:
Private Shared Sub ReceiveCallback(ByVal ar As IAsyncResult)
            Try
                ' Retrieve the state object and the client socket 
                ' from the asynchronous state object.
                Dim state As EthStateObject = CType(ar.AsyncState, EthStateObject)
                Dim client As Socket = state.WorkerSocket
                Dim bytesRead As Integer

                ' Read data from the remote device.
                Try
                    bytesRead = client.EndReceive(ar)
                Catch ex As Exception
                    RaiseEvent Exception(ex)
                    receiveDone.Set()
                    Exit Sub
                End Try

                If bytesRead > 0 Then
                    ' There might be more data, so store the data received so far.
                    state.StrData.Append(Encoding.ASCII.GetString(state.Buffer, 0, bytesRead))
                    m_Buffer.Push(state.Buffer)

                    If (bytesRead > m_RcvByteThreshold) Then
                        RaiseEvent DataReceived(m_Buffer.Length)
                    End If

                    ' Get the rest of the data.
                    client.BeginReceive(state.Buffer, 0, EthStateObject.BufferSize, 0, New AsyncCallback(AddressOf ReceiveCallback), state)
                Else
                    ' All the data has arrived; put it in response.
                    If (state.StrData.Length > 1) Then
                        m_Buffer.Push(state.Buffer)
                    End If

                    ' Signal that all bytes have been received.
                    receiveDone.Set()
                    RaiseEvent DataReceived(m_Buffer.Length)
                End If
            Catch ex As Exception
                RaiseEvent Exception(ex)
            End Try
        End Sub

        Private Shared Sub SendCallback(ByVal ar As IAsyncResult)
            Try
                ' Retrieve the socket from the state object.
                Dim client As Socket = CType(ar.AsyncState, Socket)

                ' Complete sending the data to the remote device.
                Dim bytesSent As Integer = client.EndSend(ar)

                ' Signal that all bytes have been sent.
                sendDone.Set()
            Catch ex As Exception
                RaiseEvent Exception(ex)
            End Try
        End Sub

        Private Shared Sub DisconnectCallback(ByVal ar As IAsyncResult)
            Dim client As Socket = CType(ar.AsyncState, Socket)

            Try
                client.EndDisconnect(ar)
            Catch ex As Exception
                RaiseEvent Exception(ex)
            End Try

            disconnectDone.Set()
        End Sub

        Private Sub Initialize(ByVal Format As CommDefs.E_BUFFER_DATA_TYPES)
            m_Buffer = New CommBuffer(Format)
            m_Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, True)
        End Sub

    End Class

End Namespace
__________________
http://www.joshuagayou.com
Reply With Quote
  #4  
Old 10-03-2007, 12:58 PM
gayouj's Avatar
gayouj.NET Sockets and asynchronous disconnects gayouj is offline
Junior Contributor

* Expert *
 
Join Date: Jan 2006
Location: California
Posts: 317
Default The answer

Okay, I think I've got this figured out. Instead of trying to reuse the socket, I just .Close() it and set it to nothing on each Disconnect callback, and the New it when I want to connect again.

It seams that the socket wasn't being truely disconnected before, so when I did a subsequent reconnect, I'd get an exception saying that the socket was already connected. Doing a .Close() on the socket takes care of the disconnect (with malice) and ensures that the resources are freed up. After that, you have to set the socket to Nothing and then New it again because it has been disposed and you won't be allows to just connect again.
__________________
http://www.joshuagayou.com
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

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 Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
.NET Sockets and asynchronous disconnects
.NET Sockets and asynchronous disconnects
.NET Sockets and asynchronous disconnects .NET Sockets and asynchronous disconnects
.NET Sockets and asynchronous disconnects
.NET Sockets and asynchronous disconnects
.NET Sockets and asynchronous disconnects .NET Sockets and asynchronous disconnects .NET Sockets and asynchronous disconnects .NET Sockets and asynchronous disconnects .NET Sockets and asynchronous disconnects .NET Sockets and asynchronous disconnects .NET Sockets and asynchronous disconnects
.NET Sockets and asynchronous disconnects
.NET Sockets and asynchronous disconnects
 
.NET Sockets and asynchronous disconnects
.NET Sockets and asynchronous disconnects
 
-->