异步这个类还没有完全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)
VB.NET编写的TCP异步通讯类(目前测试中)
80酷酷网 80kuku.com