VB.NET编写的TCP异步通讯类(目前测试中)

类别:.NET开发 点击:0 评论:0 推荐:

这个类还没有完全OK,但基本的功能已经完成,异常还有待改进,欢迎批评。

Imports System.Threading
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.ComponentModel

<DefaultEvent("DataArrival")> Public Class MyTCPClient
    Private m_sckClient As Socket
    Private ipepRemote As IPEndPoint
    Private m_ConnDone As New ManualResetEvent(False)
    Private m_SendDone As New ManualResetEvent(False)
    Private m_ReceiveDone As New ManualResetEvent(False)

    Public Event DataArrival As DataArrivalHandler
    Public Event ConnectionComplete As EventHandler
    Public Event DisConnect As EventHandler

    Public ReadOnly Property Connected() As Boolean
        Get
            Return Me.m_sckClient.Connected
        End Get
    End Property
    Public ReadOnly Property RemoteIPEndPoint() As IPEndPoint
        Get
            Return Me.ipepRemote
        End Get
    End Property

    Public Sub New(ByVal RemotePort As Integer, ByVal RemoteIP As String, ByVal LocalPort As Integer)
        Try
            Me.SetSocket(RemotePort, RemoteIP, LocalPort)
        Catch ex As Exception
            Throw New Exception("New--" & ex.ToString)
        End Try
    End Sub

    Public Sub SetSocket(ByVal RemotePort As Integer, ByVal RemoteIP As String, ByVal LocalPort As Integer)

        Me.m_sckClient = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
        ipepRemote = New IPEndPoint(IPAddress.Parse(RemoteIP), RemotePort)
        Me.m_sckClient.Blocking = False

        Me.m_sckClient.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, 0)
        Me.m_sckClient.BeginConnect(Me.ipepRemote, New System.AsyncCallback(AddressOf CBConn), m_sckClient)

        If Me.m_ConnDone.WaitOne(3000, False) = False Then
            Me.m_sckClient = Nothing
            Throw New Exception("SetSocket--NoConnection,目标主机没有响应")
        End If

    End Sub

    Public Sub SendData(ByVal strSend As String)
        If Not Me.m_sckClient Is Nothing Then
            If Me.m_sckClient.Connected Then
                Dim strReady As String = Chr(1) & strSend & ComputeChecksum(strSend) & Chr(4)
                Me.m_sckClient.BeginSend(System.Text.Encoding.Default.GetBytes(strReady), 0, strReady.Length, SocketFlags.None, New System.AsyncCallback(AddressOf Me.CBSend), Me.m_sckClient)
                Me.m_SendDone.WaitOne()
            Else
                Throw New SocketException("SendData--,连接还没有打开")
            End If
        Else
            Throw New Exception("SendData--,未将对象引用设置到对象的实例")
        End If
    End Sub

    Public Sub Close()
        If Not Me.m_sckClient Is Nothing Then
            If Me.m_sckClient.Connected Then
                Me.m_sckClient.Shutdown(SocketShutdown.Both)
                Me.m_sckClient.Close()
            Else
                Throw New Exception("Close--,连接还没有打开")
            End If
        Else
            Throw New Exception("Close--,未将对象引用设置到对象的实例")
        End If
    End Sub

    Public Sub Dispose()
        If Not Me.m_sckClient Is Nothing Then
            If Me.m_sckClient.Connected Then
                Me.m_sckClient.Shutdown(SocketShutdown.Both)
                Me.m_sckClient.Close()
            End If
            Me.m_sckClient = Nothing
        End If
        If Not Me.ipepRemote Is Nothing Then
            Me.ipepRemote = Nothing
        End If
    End Sub

#Region "回调函数"
    Private Sub CBConn(ByVal ar As System.IAsyncResult)
        Dim objSocket As Socket = CType(ar.AsyncState, Socket)
        If objSocket.Connected Then
            Try
                objSocket.EndConnect(ar)
                Me.m_ConnDone.Set()
                Dim state As New sckStructure
                state.worksocket = Me.m_sckClient
                Me.m_sckClient.BeginReceiveFrom(state.buffer, 0, state.buffersize, SocketFlags.None, Me.ipepRemote, AddressOf Me.CBReceive, state)
                Me.m_ReceiveDone.WaitOne()
            Catch ex As Exception
                Throw New Exception("CBConn--HasConnected" & ex.ToString)
            End Try
            RaiseEvent ConnectionComplete(Me, New EventArgs)
        Else
            Throw New Exception("CBConn--NoConnection,目标主机没有响应")
        End If
    End Sub

    Private Sub CBSend(ByVal ar As System.IAsyncResult)
        Try
            Me.m_sckClient.EndSend(ar)
            Me.m_SendDone.Set()
        Catch ex As Exception
            Throw New Exception("CBSend--" & ex.ToString)
        End Try
    End Sub

    Private Sub CBReceive(ByVal ar As System.IAsyncResult)
        Dim bytesread As Integer
        Try
            bytesread = Me.m_sckClient.EndReceive(ar)
            Me.m_ReceiveDone.Set()
        Catch ex As SocketException
            If ex.ErrorCode = 10054 Then
                RaiseEvent DisConnect(Me, New EventArgs)
            Else
                Throw New Exception("CBReceive--" & ex.tostring)
            End If
        Catch ex As Exception
            Throw New Exception("CBReceive--" & ex.ToString)
        End Try
        Try
            Dim obj1 As New sckStructure
            obj1.worksocket = Me.m_sckClient
            Me.m_sckClient.BeginReceive(obj1.buffer, 0, obj1.buffersize - 1, SocketFlags.None, AddressOf Me.CBReceive, obj1)
            Me.m_ReceiveDone.WaitOne()
            Dim obj As sckStructure = CType(ar.AsyncState, sckStructure)
            Dim strReceive As String = Encoding.Default.GetString(obj.buffer, 0, bytesread)
            If CleanString(strReceive) <> "" Then
                RaiseEvent DataArrival(strReceive)
            End If
        Catch ex As SocketException
            If ex.ErrorCode = 10054 Then
                RaiseEvent DisConnect(Me, New EventArgs)
            Else
                Throw New Exception("CBReceive--" & ex.tostring)
            End If
        Catch ex As Exception
            Throw New Exception("CBReceive--" & ex.ToString)
        End Try

    End Sub
#End Region
End Class

Friend Class sckStructure
    Public worksocket As Socket = Nothing
    Public Const buffersize As Integer = 1024
    Public buffer(buffersize) As Byte
End Class

Public Delegate Sub DataArrivalHandler(ByVal strReceive As String)

本文地址:http://com.8s8s.com/it/it41856.htm