这个类还没有完全OK,但基本的功能已经完成,异常还有待改进,欢迎批评。
Imports System.Threading
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.ComponentModel
1<defaultevent("dataarrival")> Public Class MyTCPClient
2Private m_sckClient As Socket
3Private ipepRemote As IPEndPoint
4Private m_ConnDone As New ManualResetEvent(False)
5Private m_SendDone As New ManualResetEvent(False)
6Private m_ReceiveDone As New ManualResetEvent(False)
7
8Public Event DataArrival As DataArrivalHandler
9Public Event ConnectionComplete As EventHandler
10Public Event DisConnect As EventHandler
11
12Public ReadOnly Property Connected() As Boolean
13Get
14Return Me.m_sckClient.Connected
15End Get
16End Property
17Public ReadOnly Property RemoteIPEndPoint() As IPEndPoint
18Get
19Return Me.ipepRemote
20End Get
21End Property
22
23Public Sub New(ByVal RemotePort As Integer, ByVal RemoteIP As String, ByVal LocalPort As Integer)
24Try
25Me.SetSocket(RemotePort, RemoteIP, LocalPort)
26Catch ex As Exception
27Throw New Exception("New--" & ex.ToString)
28End Try
29End Sub
30
31Public Sub SetSocket(ByVal RemotePort As Integer, ByVal RemoteIP As String, ByVal LocalPort As Integer)
32
33Me.m_sckClient = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
34ipepRemote = New IPEndPoint(IPAddress.Parse(RemoteIP), RemotePort)
35Me.m_sckClient.Blocking = False
36
37Me.m_sckClient.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, 0)
38Me.m_sckClient.BeginConnect(Me.ipepRemote, New System.AsyncCallback(AddressOf CBConn), m_sckClient)
39
40If Me.m_ConnDone.WaitOne(3000, False) = False Then
41Me.m_sckClient = Nothing
42Throw New Exception("SetSocket--NoConnection,目标主机没有响应")
43End If
44
45End Sub
46
47Public Sub SendData(ByVal strSend As String)
48If Not Me.m_sckClient Is Nothing Then
49If Me.m_sckClient.Connected Then
50Dim strReady As String = Chr(1) & strSend & ComputeChecksum(strSend) & Chr(4)
51Me.m_sckClient.BeginSend(System.Text.Encoding.Default.GetBytes(strReady), 0, strReady.Length, SocketFlags.None, New System.AsyncCallback(AddressOf Me.CBSend), Me.m_sckClient)
52Me.m_SendDone.WaitOne()
53Else
54Throw New SocketException("SendData--,连接还没有打开")
55End If
56Else
57Throw New Exception("SendData--,未将对象引用设置到对象的实例")
58End If
59End Sub
60
61Public Sub Close()
62If Not Me.m_sckClient Is Nothing Then
63If Me.m_sckClient.Connected Then
64Me.m_sckClient.Shutdown(SocketShutdown.Both)
65Me.m_sckClient.Close()
66Else
67Throw New Exception("Close--,连接还没有打开")
68End If
69Else
70Throw New Exception("Close--,未将对象引用设置到对象的实例")
71End If
72End Sub
73
74Public Sub Dispose()
75If Not Me.m_sckClient Is Nothing Then
76If Me.m_sckClient.Connected Then
77Me.m_sckClient.Shutdown(SocketShutdown.Both)
78Me.m_sckClient.Close()
79End If
80Me.m_sckClient = Nothing
81End If
82If Not Me.ipepRemote Is Nothing Then
83Me.ipepRemote = Nothing
84End If
85End Sub
86
87#Region "回调函数"
88Private Sub CBConn(ByVal ar As System.IAsyncResult)
89Dim objSocket As Socket = CType(ar.AsyncState, Socket)
90If objSocket.Connected Then
91Try
92objSocket.EndConnect(ar)
93Me.m_ConnDone.Set()
94Dim state As New sckStructure
95state.worksocket = Me.m_sckClient
96Me.m_sckClient.BeginReceiveFrom(state.buffer, 0, state.buffersize, SocketFlags.None, Me.ipepRemote, AddressOf Me.CBReceive, state)
97Me.m_ReceiveDone.WaitOne()
98Catch ex As Exception
99Throw New Exception("CBConn--HasConnected" & ex.ToString)
100End Try
101RaiseEvent ConnectionComplete(Me, New EventArgs)
102Else
103Throw New Exception("CBConn--NoConnection,目标主机没有响应")
104End If
105End Sub
106
107Private Sub CBSend(ByVal ar As System.IAsyncResult)
108Try
109Me.m_sckClient.EndSend(ar)
110Me.m_SendDone.Set()
111Catch ex As Exception
112Throw New Exception("CBSend--" & ex.ToString)
113End Try
114End Sub
115
116Private Sub CBReceive(ByVal ar As System.IAsyncResult)
117Dim bytesread As Integer
118Try
119bytesread = Me.m_sckClient.EndReceive(ar)
120Me.m_ReceiveDone.Set()
121Catch ex As SocketException
122If ex.ErrorCode = 10054 Then
123RaiseEvent DisConnect(Me, New EventArgs)
124Else
125Throw New Exception("CBReceive--" & ex.tostring)
126End If
127Catch ex As Exception
128Throw New Exception("CBReceive--" & ex.ToString)
129End Try
130Try
131Dim obj1 As New sckStructure
132obj1.worksocket = Me.m_sckClient
133Me.m_sckClient.BeginReceive(obj1.buffer, 0, obj1.buffersize - 1, SocketFlags.None, AddressOf Me.CBReceive, obj1)
134Me.m_ReceiveDone.WaitOne()
135Dim obj As sckStructure = CType(ar.AsyncState, sckStructure)
136Dim strReceive As String = Encoding.Default.GetString(obj.buffer, 0, bytesread)
137If CleanString(strReceive) <> "" Then
138RaiseEvent DataArrival(strReceive)
139End If
140Catch ex As SocketException
141If ex.ErrorCode = 10054 Then
142RaiseEvent DisConnect(Me, New EventArgs)
143Else
144Throw New Exception("CBReceive--" & ex.tostring)
145End If
146Catch ex As Exception
147Throw New Exception("CBReceive--" & ex.ToString)
148End Try
149
150End Sub
151#End Region
152End Class
153
154Friend Class sckStructure
155Public worksocket As Socket = Nothing
156Public Const buffersize As Integer = 1024
157Public buffer(buffersize) As Byte
158End Class
159
160Public Delegate Sub DataArrivalHandler(ByVal strReceive As String)</defaultevent("dataarrival")>