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

80酷酷网    80kuku.com

  异步这个类还没有完全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)



分享到
  • 微信分享
  • 新浪微博
  • QQ好友
  • QQ空间
点击: