一个基于VB.net的异步Socket网络TCP通信可防止任意一端意外终止TCP连接的类,。
2013-12-04 16:13
741 查看
之前,因为要做一个TCP通信的项目,有研究一下Socket类,但是为了快速完成任务,还是在网上找了一些源码来调试测试,发现很多源码都无法触发TCP连接的任意一端
的突然意外中断连接的事件,于是本人基于他人的源码基础上进行了修改,可以触发这一事件,可使TCP连接的另一端触发对方已经终止TCP连接事件。
以下,奉上本人修改后的源码类:
1)TCP 服务器TCP 侦听类。
[vb]
view plaincopyprint?
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Imports System.Text
'**********************************************************************************************************
'''''' 类名:TCPServer
'''''' 说明:监听主线程,用于监听客户端联接,并记录客户端联接,接收和发送数据
'''''' 与客户端的联接采用TCP联接
'**********************************************************************************************************
''' <summary>
''' 侦听客户端联接
''' </summary>
Public Class TCPServer
#Region "私有成员"
Private _LocationListenSocket As Socket '本地侦听服务
Private _ListenPort As String '服务器侦听客户端联接的端口
Private _MaxClient As Integer '最大客户端连接数
Private _Clients As New SortedList '客户端队列
Private _ListenThread As Thread = Nothing '侦听线程
Private _ServerStart As Boolean = False '服务器是否已经启动
Private _RecvMax As Integer '接收缓冲区大小
#End Region
#Region "事件"
''' <summary>
''' 客户端联接事件
''' </summary>
''' <param name="IP">客户端联接IP</param>
''' <param name="Port">客户端联接端口号</param>
''' <remarks></remarks>
Public Event ClientConnected(ByVal IP As String, ByVal Port As String)
''' <summary>
''' 客户端断开事件
''' </summary>
''' <param name="IP">客户端联接IP</param>
''' <param name="Port">客户端联接端口号</param>
''' <remarks></remarks>
Public Event ClientClose(ByVal IP As String, ByVal Port As String)
''' <summary>
''' 接收到客户端的数据
''' </summary>
''' <param name="value">数据</param>
''' <param name="IPAddress">数据来源IP</param>
''' <param name="Port">数据来源端口</param>
''' <remarks></remarks>
Public Event DataArrived(ByVal value As Byte(), ByVal Len As Integer, ByVal IPAddress As String, ByVal Port As String)
''' <summary>
''' 异常数据
''' </summary>
''' <param name="ex"></param>
''' <remarks></remarks>
Public Event Exception(ByVal ex As Exception)
#End Region
#Region "属性"
''' <summary>
''' 侦听服务是否已经启动
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property IsServerStart() As Boolean
Get
Return _ServerStart
End Get
End Property
#End Region
#Region "方法"
''' <summary>
''' 实例 TCPServer
''' </summary>
''' <param name="Port">侦听客户端联接的端口号</param>
''' <param name="MaxClient">最大可以联接的客户端数量</param>
''' <param name="RecvMax">接收缓冲区大小</param>
''' <param name="RecvSleep">接收线程睡眠时间</param>
''' <remarks></remarks>
Sub New(ByVal Port As String, ByVal MaxClient As Integer, ByVal RecvMax As Integer, ByVal RecvSleep As Integer)
Try
Dim strHostName As String = Dns.GetHostName()
_ListenPort = Port
_MaxClient = MaxClient
_RecvMax = RecvMax
Dim strServerHost As New IPEndPoint(IPAddress.Any, Int32.Parse(_ListenPort))
'建立TCP侦听
_LocationListenSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
_LocationListenSocket.Bind(strServerHost)
_LocationListenSocket.Listen(_MaxClient)
_LocationListenSocket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.AcceptConnection, 1)
Catch ex As Exception
RaiseEvent Exception(ex)
End Try
End Sub
''' <summary>
''' 开始侦听服务
''' </summary>
''' <remarks></remarks>
Public Sub StartServer()
_ServerStart = True
Try
_ListenThread = New Thread(New ThreadStart(AddressOf ListenClient))
_ListenThread.Name = "监听客户端主线程"
_ListenThread.Start()
Catch ex As Exception
If (Not _LocationListenSocket Is Nothing) Then
If _LocationListenSocket.Connected Then
_LocationListenSocket.Close()
End If
End If
RaiseEvent Exception(ex)
End Try
End Sub
''' <summary>
''' 关闭侦听
''' </summary>
''' <remarks></remarks>
Public Sub Close()
Try
_ServerStart = False
'CloseAllClient()
Thread.Sleep(5)
_ListenThread.Abort()
_LocationListenSocket.Close()
_ListenThread = Nothing
Catch ex As Exception
RaiseEvent Exception(ex)
End Try
End Sub
''' <summary>
''' 客户端侦听线程
''' </summary>
''' <remarks></remarks>
Private Sub ListenClient()
Dim sKey As String
While (_ServerStart)
Try
If Not _LocationListenSocket Is Nothing Then
Dim clientSocket As System.Net.Sockets.Socket
clientSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
clientSocket = _LocationListenSocket.Accept()
If Not clientSocket Is Nothing Then
Dim clientInfoT As IPEndPoint = CType(clientSocket.RemoteEndPoint, IPEndPoint)
sKey = clientInfoT.Address.ToString & "\&" & clientInfoT.Port.ToString
_Clients.Add(sKey, clientSocket)
RaiseEvent ClientConnected(clientInfoT.Address.ToString, clientInfoT.Port.ToString) '举起有客户端联接的事件
'启动客户端接收主线程,开始侦听并接收客户端上传的数据
Dim lb As New ClientCommunication(_LocationListenSocket, clientSocket, Me)
AddHandler lb.Exception, AddressOf WriteErrorEvent_ClientCommunication
Dim thrClient As New Thread(New ThreadStart(AddressOf lb.serverThreadProc))
thrClient.Name = "客户端接收线程,客户端" & clientInfoT.Address.ToString & ":" & clientInfoT.Port.ToString
thrClient.Start()
End If
End If
Catch ex As Exception
RaiseEvent Exception(ex)
End Try
End While
End Sub
Private Sub WriteErrorEvent_ClientCommunication(ByVal ex As Exception)
RaiseEvent Exception(ex)
End Sub
Public Sub CloseClient(ByVal IP As String, ByVal Port As String)
GetClientSocket(IP, Port).Close()
GetClientClose(IP, Port)
End Sub
'Public Sub AlertNoticeClientAll(ByVal DepartmentName As String, ByVal LineName As String, ByVal ErrorCode As Integer)
' '#DepartmentName,LineName,AlertCodeValue.
' ' ''Dim mStr As String
' ' ''mStr = "#" & DepartmentName & "," & LineName & "," & ErrorCode
' ' ''Dim SendByte() As Byte = System.Text.UTF8Encoding.Default.GetBytes(mStr)
' ' ''For Each sc As System.Net.Sockets.Socket In _ClientComputers.Values
' ' '' sc.Send(SendByte, SendByte.Length(), SocketFlags.None)
' ' ''Next
'End Sub
Public Sub CloseAllClient()
For Each sc As System.Net.Sockets.Socket In _Clients.Values
'断开所有工作站的Socket连接。
Dim clientInfoT As IPEndPoint = CType(sc.RemoteEndPoint, IPEndPoint)
CloseClient(clientInfoT.Address.ToString, clientInfoT.Port.ToString)
Next
End Sub
#Region "接收客户端的数据"
''' <summary>
''' 接收到客户端的数据-字节数组
''' </summary>
''' <param name="value">数据内容</param>
''' <param name="Len">字节长度</param>
''' <param name="IPAddress">发送该数据的IP地址</param>
''' <param name="Port">发送该数据的端口号</param>
''' <remarks></remarks>
Private Sub GetData_Byte(ByVal value As Byte(), ByVal Len As Integer, ByVal IPAddress As String, ByVal Port As String)
Try
RaiseEvent DataArrived(value, Len, IPAddress, Port)
'Catch exx As Sockets.SocketException
' CloseClient(IPAddress, Port)
Catch ex As Exception
RaiseEvent Exception(ex)
End Try
End Sub
''' <summary>
''' 得到客户端断开或失去客户端联连事件
''' </summary>
''' <param name="IP">客户端联接IP</param>
''' <param name="Port">客户端联接端口号</param>
''' <remarks></remarks>
Private Sub GetClientClose(ByVal IP As String, ByVal Port As String)
Try
If _Clients.ContainsKey(IP & "\&" & Port) Then
SyncLock _Clients.SyncRoot
'_Clients.Item(IP & "\&" & Port)
_Clients.Remove(IP & "\&" & Port)
End SyncLock
End If
RaiseEvent ClientClose(IP, Port)
Catch ex As Exception
RaiseEvent Exception(ex)
End Try
End Sub
#End Region
#Region "向客户端发送数据"
''' <summary>
''' 向客户端发送信息
''' </summary>
''' <param name="value">发送的内容</param>
''' <param name="IPAddress">IP地址</param>
''' <param name="Port">端口号</param>
''' <returns> Boolean</returns>
''' <remarks></remarks>
Public Function SendData(ByVal value As Byte(), ByVal IPAddress As String, ByVal Port As String) As Boolean
Try
Dim clientSocket As System.Net.Sockets.Socket
clientSocket = _Clients.Item(IPAddress & "\&" & Port)
clientSocket.Send(value, value.Length, SocketFlags.None)
Return True
Catch ex As Exception
RaiseEvent Exception(ex)
Return False
End Try
End Function
Public Function SendFile(ByVal value As String, ByVal IPAddress As String, ByVal Port As String) As Boolean
Try
Dim clientSocket As System.Net.Sockets.Socket
clientSocket = _Clients.Item(IPAddress & "\&" & Port)
clientSocket.SendFile(value)
Return True
Catch ex As Exception
RaiseEvent Exception(ex)
Return False
End Try
End Function
Public Function SendDataToAllClient(ByVal value As Byte()) As Boolean
Try
For Each clientSocket As System.Net.Sockets.Socket In _Clients.Values
clientSocket.Send(value, value.Length, SocketFlags.None)
Next
Return True
Catch ex As Exception
RaiseEvent Exception(ex)
Return False
End Try
End Function
#End Region
''' <summary>
''' 得到客户端的Socket联接
''' </summary>
''' <param name="IPAddress">客户端的IP</param>
''' <param name="Port">客户端的端口号</param>
''' <returns>Socket联接</returns>
''' <remarks></remarks>
Private Function GetClientSocket(ByVal IPAddress As String, ByVal Port As String) As Socket
Try
Dim ClientSocket As Socket
ClientSocket = _Clients.Item(IPAddress & "\&" & Port)
Return ClientSocket
Catch ex As Exception
RaiseEvent Exception(ex)
Return Nothing
End Try
End Function
#End Region
Private Class ClientCommunication
Public Event Exception(ByVal ex As Exception)
Private ServerSocket As New System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
Private myClientSocket As New System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
Private myParentObject As TCPServer
Private oldbytes() As Byte
Private _IPAddress, _Port As String
Private NclientInfoT As IPEndPoint = Nothing
Private iLen As Integer
Private allDone As New ManualResetEvent(False)
''' <summary>
''' 实例ClientCommunication类
''' </summary>
''' <param name="ServerSocket"></param>
''' <param name="ClientSocket"></param>
''' <param name="ParentObject"></param>
''' <remarks></remarks>
Public Sub New(ByVal ServerSocket As Socket, ByVal ClientSocket As Socket, ByVal ParentObject As TCPServer)
Me.ServerSocket = ServerSocket
myClientSocket = ClientSocket
myParentObject = ParentObject
NclientInfoT = CType(myClientSocket.RemoteEndPoint, IPEndPoint)
_IPAddress = NclientInfoT.Address.ToString
_Port = NclientInfoT.Port.ToString
End Sub
''' <summary>
''' 客户端通讯主线程
''' </summary>
''' <remarks></remarks>
Public Sub serverThreadProc()
Try
Dim sb As New SocketAndBuffer
sb.Socket = myClientSocket
sb.Socket.BeginReceive(sb.Buffer, 0, sb.Buffer.Length, SocketFlags.None, AddressOf ReceiveCallBack, sb)
'allDone.WaitOne()
Catch ex As Exception
RaiseEvent Exception(ex)
End Try
End Sub
''' <summary>
''' socket异步接收回调函数
''' </summary>
''' <param name="ar"></param>
''' <remarks></remarks>
Private Sub ReceiveCallBack(ByVal ar As IAsyncResult)
Dim sb As SocketAndBuffer
allDone.Set()
sb = CType(ar.AsyncState, SocketAndBuffer)
Try
If sb.Socket.Connected Then
iLen = sb.Socket.EndReceive(ar)
If iLen > 0 Then
ReDim oldbytes(iLen - 1)
Array.Copy(sb.Buffer, 0, oldbytes, 0, iLen)
myParentObject.GetData_Byte(oldbytes, oldbytes.Length, _IPAddress, _Port)
sb.Socket.BeginReceive(sb.Buffer, 0, sb.Buffer.Length, SocketFlags.None, AddressOf ReceiveCallBack, sb)
Else
If (Not myClientSocket Is Nothing) Then
If myClientSocket.Connected Then
myClientSocket.Close()
Else
myClientSocket.Close()
End If
myClientSocket = Nothing
If Not NclientInfoT Is Nothing Then
myParentObject._Clients.Remove(_IPAddress & "\&" & _Port)
myParentObject.GetClientClose(_IPAddress, _Port)
End If
End If
End If
End If
Catch ex As Exception
If (Not myClientSocket Is Nothing) Then
If myClientSocket.Connected Then
myClientSocket.Close()
Else
myClientSocket.Close()
End If
myClientSocket = Nothing
If Not NclientInfoT Is Nothing Then
myParentObject._Clients.Remove(_IPAddress & "\&" & _Port)
myParentObject.GetClientClose(_IPAddress, _Port)
End If
End If
RaiseEvent Exception(ex)
End Try
End Sub
''' <summary>
''' 异步操作socket缓冲类
''' </summary>
''' <remarks></remarks>
Private Class SocketAndBuffer
Public Socket As System.Net.Sockets.Socket
Public Buffer(8192) As Byte
End Class
End Class
End Class
2)TCP 客户端连接通信类
[vb]
view plaincopyprint?
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Public Class TCPClient
#Region "私有成员"
Private _LocationClientSocket As Socket '本地侦听服务
Private _LocalPort As String '本地端口
Private _LocalHostName As String
Private _LocalIP As String
Private autoEvent As AutoResetEvent
Private _RemoteHostName As String '遠程端計算機名
Private _RemoteIP As String '遠程端計算機IP
Private _RemotePort As String '遠程端計算機Port
Private _RemoteIPOrHostName As String
'Private _MaxClient As Integer '最大客户端连接数
'Private _Clients As New SortedList '客户端队列
'Private _ListenThread As Thread = Nothing '侦听线程
'Private _ServerStart As Boolean = False '服务器是否已经启动
Private _RecvMax As Integer '接收缓冲区大小
Private ClientThread As Thread
'Private ClitenStream As NetworkStream
Private IsStop As Boolean = False
#End Region
#Region "事件"
''' <summary>
''' 客户端联接事件
''' </summary>
''' <remarks></remarks>
Public Event ClientConnected()
''' <summary>
''' 客户端断开事件
''' </summary>
''' <remarks></remarks>
Public Event ClientClosed()
''' <summary>
''' 接收到客户端的数据
''' </summary>
''' <param name="value">数据</param>
''' <remarks></remarks>
Public Event DataArrived(ByVal value As Byte(), ByVal Len As Integer)
''' <summary>
''' 异常数据
''' </summary>
''' <param name="ex"></param>
''' <remarks></remarks>
Public Event Exception(ByVal ex As Exception)
#End Region
#Region "属性"
''' <summary>
''' 是否已經連接
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property Connected() As Boolean
Get
Return _LocationClientSocket.Connected
End Get
End Property
''' <summary>
''' 本地計算機名稱
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property LocalHostName() As String
Get
Return _LocalHostName
End Get
End Property
''' <summary>
''' 本地計算IP
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property LocalIP() As String
Get
Return _LocalIP
End Get
End Property
''' <summary>
''' 本地計算機端口
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property LocalPort() As String
Get
Return _LocalPort
End Get
End Property
''' <summary>
''' 遠程計算機IP
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property RemoteIP() As String
Get
Return _RemoteIP
End Get
End Property
''' <summary>
''' 遠程計算機端口
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property RemotePort() As String
Get
Return _RemotePort
End Get
End Property
''' <summary>
''' 遠程計算機名稱
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property RemoteHostName() As String
Get
Return _RemoteHostName
End Get
End Property
#End Region
#Region "方法"
''' <summary>
''' 实例 TCPServer
''' </summary>
''' <param name="RemoteIPOrHostName">需要連接服務的IP地址或計算機名稱</param>
''' <param name="Port">侦听客户端联接的端口号</param>
''' <param name="RecvMax">接收缓冲区大小</param>
''' <param name="RecvSleep">接收线程睡眠时间</param>
''' <remarks></remarks>
Sub New(ByVal RemoteIPOrHostName As String, ByVal Port As String, ByVal RecvMax As Integer, ByVal RecvSleep As Integer)
Try
_LocalHostName = Dns.GetHostName()
'_RemoteIP = Dns.GetHostAddresses(RemoteIPOrHostName)(0).ToString
_RemotePort = Port
_RecvMax = RecvMax
_RemoteIPOrHostName = RemoteIPOrHostName
_RemotePort = Port
'Dim strServerHost As New IPEndPoint(IPAddress.Any, Int32.Parse(_ListenPort))
'建立TCP侦听
_LocationClientSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
autoEvent = New AutoResetEvent(False)
Dim cThread As New Thread(New ThreadStart(AddressOf ConnectHost))
cThread.Start()
autoEvent.WaitOne(1000, False)
cThread.Abort()
Catch ex As Exception
RaiseEvent Exception(ex)
End Try
End Sub
Public Sub ConnectHost()
Try
Dim remoteIP As Net.IPAddress = Nothing
If IPAddress.TryParse(_RemoteIPOrHostName, remoteIP) Then
'_LocationClientSocket.BeginConnect()
_LocationClientSocket.Connect(remoteIP, _RemotePort)
'_RemoteIP = RemoteHostName
Else
_LocationClientSocket.Connect(_RemoteIPOrHostName, _RemotePort)
_RemoteHostName = RemoteHostName
End If
If _LocationClientSocket.Connected Then
_LocationClientSocket.SendBufferSize = _RecvMax
_LocationClientSocket.ReceiveBufferSize = _RecvMax
Dim clientInfoT As IPEndPoint
clientInfoT = CType(_LocationClientSocket.RemoteEndPoint, IPEndPoint)
_RemoteIP = clientInfoT.Address.ToString
'Dim remoteHost As Net.IPHostEntry
_RemoteHostName = Dns.GetHostEntry(_RemoteIP).HostName
clientInfoT = CType(_LocationClientSocket.LocalEndPoint, IPEndPoint)
_LocalIP = clientInfoT.Address.ToString
_LocalPort = clientInfoT.Port.ToString
IsStop = False
RaiseEvent ClientConnected()
ClientThread = New Thread(New ThreadStart(AddressOf ClientListen))
ClientThread.Start()
autoEvent.Set()
End If
Catch ex As Exception
End Try
End Sub
''' <summary>
''' 關閉客戶端連接
''' </summary>
''' <remarks></remarks>
Public Sub Close()
Try
If _LocationClientSocket Is Nothing Then Exit Sub
IsStop = True
If Not ClientThread Is Nothing Then
Thread.Sleep(5)
ClientThread.Abort()
End If
_LocationClientSocket.Close()
_LocationClientSocket = Nothing
ClientThread = Nothing
RaiseEvent ClientClosed()
Catch ex As Exception
RaiseEvent Exception(ex)
End Try
End Sub
''' <summary>
''' 实例 TCPServer
''' </summary>
''' <param name="value">發送的資料,二進制數組</param>
''' <remarks></remarks>
Public Function SendData(ByVal value As Byte()) As Boolean
Try
_LocationClientSocket.Send(value)
Catch ex As Exception
RaiseEvent Exception(ex)
End Try
End Function
Private Sub ClientListen()
Dim tmpByt(8192) As Byte
Dim recData() As Byte
Dim R As Integer
While Not IsStop
Try
If _LocationClientSocket.Poll(50, SelectMode.SelectWrite) Then
R = _LocationClientSocket.Receive(tmpByt)
If R > 0 Then
ReDim recData(R - 1)
Array.Copy(tmpByt, recData, R)
RaiseEvent DataArrived(recData, recData.Length)
Else
If (Not _LocationClientSocket Is Nothing) Then
_LocationClientSocket.Close()
_LocationClientSocket = Nothing
IsStop = True
RaiseEvent ClientClosed()
End If
End If
End If
Catch sex As SocketException
If sex.ErrorCode = 10054 Then
If (Not _LocationClientSocket Is Nothing) Then
_LocationClientSocket.Close()
_LocationClientSocket = Nothing
IsStop = True
RaiseEvent ClientClosed()
End If
Else
RaiseEvent Exception(sex)
End If
Catch ex As Exception
RaiseEvent Exception(ex)
End Try
End While
End Sub
#End Region
End Class
窗体调用TCP 类如下
服务器端:
[vb]
view plaincopyprint?
Public WithEvents MyClient As TCPServer
客户机端:
[vb]
view plaincopyprint?
Public WithEvents MyClient As TCPClient
的突然意外中断连接的事件,于是本人基于他人的源码基础上进行了修改,可以触发这一事件,可使TCP连接的另一端触发对方已经终止TCP连接事件。
以下,奉上本人修改后的源码类:
1)TCP 服务器TCP 侦听类。
[vb]
view plaincopyprint?
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Imports System.Text
'**********************************************************************************************************
'''''' 类名:TCPServer
'''''' 说明:监听主线程,用于监听客户端联接,并记录客户端联接,接收和发送数据
'''''' 与客户端的联接采用TCP联接
'**********************************************************************************************************
''' <summary>
''' 侦听客户端联接
''' </summary>
Public Class TCPServer
#Region "私有成员"
Private _LocationListenSocket As Socket '本地侦听服务
Private _ListenPort As String '服务器侦听客户端联接的端口
Private _MaxClient As Integer '最大客户端连接数
Private _Clients As New SortedList '客户端队列
Private _ListenThread As Thread = Nothing '侦听线程
Private _ServerStart As Boolean = False '服务器是否已经启动
Private _RecvMax As Integer '接收缓冲区大小
#End Region
#Region "事件"
''' <summary>
''' 客户端联接事件
''' </summary>
''' <param name="IP">客户端联接IP</param>
''' <param name="Port">客户端联接端口号</param>
''' <remarks></remarks>
Public Event ClientConnected(ByVal IP As String, ByVal Port As String)
''' <summary>
''' 客户端断开事件
''' </summary>
''' <param name="IP">客户端联接IP</param>
''' <param name="Port">客户端联接端口号</param>
''' <remarks></remarks>
Public Event ClientClose(ByVal IP As String, ByVal Port As String)
''' <summary>
''' 接收到客户端的数据
''' </summary>
''' <param name="value">数据</param>
''' <param name="IPAddress">数据来源IP</param>
''' <param name="Port">数据来源端口</param>
''' <remarks></remarks>
Public Event DataArrived(ByVal value As Byte(), ByVal Len As Integer, ByVal IPAddress As String, ByVal Port As String)
''' <summary>
''' 异常数据
''' </summary>
''' <param name="ex"></param>
''' <remarks></remarks>
Public Event Exception(ByVal ex As Exception)
#End Region
#Region "属性"
''' <summary>
''' 侦听服务是否已经启动
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property IsServerStart() As Boolean
Get
Return _ServerStart
End Get
End Property
#End Region
#Region "方法"
''' <summary>
''' 实例 TCPServer
''' </summary>
''' <param name="Port">侦听客户端联接的端口号</param>
''' <param name="MaxClient">最大可以联接的客户端数量</param>
''' <param name="RecvMax">接收缓冲区大小</param>
''' <param name="RecvSleep">接收线程睡眠时间</param>
''' <remarks></remarks>
Sub New(ByVal Port As String, ByVal MaxClient As Integer, ByVal RecvMax As Integer, ByVal RecvSleep As Integer)
Try
Dim strHostName As String = Dns.GetHostName()
_ListenPort = Port
_MaxClient = MaxClient
_RecvMax = RecvMax
Dim strServerHost As New IPEndPoint(IPAddress.Any, Int32.Parse(_ListenPort))
'建立TCP侦听
_LocationListenSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
_LocationListenSocket.Bind(strServerHost)
_LocationListenSocket.Listen(_MaxClient)
_LocationListenSocket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.AcceptConnection, 1)
Catch ex As Exception
RaiseEvent Exception(ex)
End Try
End Sub
''' <summary>
''' 开始侦听服务
''' </summary>
''' <remarks></remarks>
Public Sub StartServer()
_ServerStart = True
Try
_ListenThread = New Thread(New ThreadStart(AddressOf ListenClient))
_ListenThread.Name = "监听客户端主线程"
_ListenThread.Start()
Catch ex As Exception
If (Not _LocationListenSocket Is Nothing) Then
If _LocationListenSocket.Connected Then
_LocationListenSocket.Close()
End If
End If
RaiseEvent Exception(ex)
End Try
End Sub
''' <summary>
''' 关闭侦听
''' </summary>
''' <remarks></remarks>
Public Sub Close()
Try
_ServerStart = False
'CloseAllClient()
Thread.Sleep(5)
_ListenThread.Abort()
_LocationListenSocket.Close()
_ListenThread = Nothing
Catch ex As Exception
RaiseEvent Exception(ex)
End Try
End Sub
''' <summary>
''' 客户端侦听线程
''' </summary>
''' <remarks></remarks>
Private Sub ListenClient()
Dim sKey As String
While (_ServerStart)
Try
If Not _LocationListenSocket Is Nothing Then
Dim clientSocket As System.Net.Sockets.Socket
clientSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
clientSocket = _LocationListenSocket.Accept()
If Not clientSocket Is Nothing Then
Dim clientInfoT As IPEndPoint = CType(clientSocket.RemoteEndPoint, IPEndPoint)
sKey = clientInfoT.Address.ToString & "\&" & clientInfoT.Port.ToString
_Clients.Add(sKey, clientSocket)
RaiseEvent ClientConnected(clientInfoT.Address.ToString, clientInfoT.Port.ToString) '举起有客户端联接的事件
'启动客户端接收主线程,开始侦听并接收客户端上传的数据
Dim lb As New ClientCommunication(_LocationListenSocket, clientSocket, Me)
AddHandler lb.Exception, AddressOf WriteErrorEvent_ClientCommunication
Dim thrClient As New Thread(New ThreadStart(AddressOf lb.serverThreadProc))
thrClient.Name = "客户端接收线程,客户端" & clientInfoT.Address.ToString & ":" & clientInfoT.Port.ToString
thrClient.Start()
End If
End If
Catch ex As Exception
RaiseEvent Exception(ex)
End Try
End While
End Sub
Private Sub WriteErrorEvent_ClientCommunication(ByVal ex As Exception)
RaiseEvent Exception(ex)
End Sub
Public Sub CloseClient(ByVal IP As String, ByVal Port As String)
GetClientSocket(IP, Port).Close()
GetClientClose(IP, Port)
End Sub
'Public Sub AlertNoticeClientAll(ByVal DepartmentName As String, ByVal LineName As String, ByVal ErrorCode As Integer)
' '#DepartmentName,LineName,AlertCodeValue.
' ' ''Dim mStr As String
' ' ''mStr = "#" & DepartmentName & "," & LineName & "," & ErrorCode
' ' ''Dim SendByte() As Byte = System.Text.UTF8Encoding.Default.GetBytes(mStr)
' ' ''For Each sc As System.Net.Sockets.Socket In _ClientComputers.Values
' ' '' sc.Send(SendByte, SendByte.Length(), SocketFlags.None)
' ' ''Next
'End Sub
Public Sub CloseAllClient()
For Each sc As System.Net.Sockets.Socket In _Clients.Values
'断开所有工作站的Socket连接。
Dim clientInfoT As IPEndPoint = CType(sc.RemoteEndPoint, IPEndPoint)
CloseClient(clientInfoT.Address.ToString, clientInfoT.Port.ToString)
Next
End Sub
#Region "接收客户端的数据"
''' <summary>
''' 接收到客户端的数据-字节数组
''' </summary>
''' <param name="value">数据内容</param>
''' <param name="Len">字节长度</param>
''' <param name="IPAddress">发送该数据的IP地址</param>
''' <param name="Port">发送该数据的端口号</param>
''' <remarks></remarks>
Private Sub GetData_Byte(ByVal value As Byte(), ByVal Len As Integer, ByVal IPAddress As String, ByVal Port As String)
Try
RaiseEvent DataArrived(value, Len, IPAddress, Port)
'Catch exx As Sockets.SocketException
' CloseClient(IPAddress, Port)
Catch ex As Exception
RaiseEvent Exception(ex)
End Try
End Sub
''' <summary>
''' 得到客户端断开或失去客户端联连事件
''' </summary>
''' <param name="IP">客户端联接IP</param>
''' <param name="Port">客户端联接端口号</param>
''' <remarks></remarks>
Private Sub GetClientClose(ByVal IP As String, ByVal Port As String)
Try
If _Clients.ContainsKey(IP & "\&" & Port) Then
SyncLock _Clients.SyncRoot
'_Clients.Item(IP & "\&" & Port)
_Clients.Remove(IP & "\&" & Port)
End SyncLock
End If
RaiseEvent ClientClose(IP, Port)
Catch ex As Exception
RaiseEvent Exception(ex)
End Try
End Sub
#End Region
#Region "向客户端发送数据"
''' <summary>
''' 向客户端发送信息
''' </summary>
''' <param name="value">发送的内容</param>
''' <param name="IPAddress">IP地址</param>
''' <param name="Port">端口号</param>
''' <returns> Boolean</returns>
''' <remarks></remarks>
Public Function SendData(ByVal value As Byte(), ByVal IPAddress As String, ByVal Port As String) As Boolean
Try
Dim clientSocket As System.Net.Sockets.Socket
clientSocket = _Clients.Item(IPAddress & "\&" & Port)
clientSocket.Send(value, value.Length, SocketFlags.None)
Return True
Catch ex As Exception
RaiseEvent Exception(ex)
Return False
End Try
End Function
Public Function SendFile(ByVal value As String, ByVal IPAddress As String, ByVal Port As String) As Boolean
Try
Dim clientSocket As System.Net.Sockets.Socket
clientSocket = _Clients.Item(IPAddress & "\&" & Port)
clientSocket.SendFile(value)
Return True
Catch ex As Exception
RaiseEvent Exception(ex)
Return False
End Try
End Function
Public Function SendDataToAllClient(ByVal value As Byte()) As Boolean
Try
For Each clientSocket As System.Net.Sockets.Socket In _Clients.Values
clientSocket.Send(value, value.Length, SocketFlags.None)
Next
Return True
Catch ex As Exception
RaiseEvent Exception(ex)
Return False
End Try
End Function
#End Region
''' <summary>
''' 得到客户端的Socket联接
''' </summary>
''' <param name="IPAddress">客户端的IP</param>
''' <param name="Port">客户端的端口号</param>
''' <returns>Socket联接</returns>
''' <remarks></remarks>
Private Function GetClientSocket(ByVal IPAddress As String, ByVal Port As String) As Socket
Try
Dim ClientSocket As Socket
ClientSocket = _Clients.Item(IPAddress & "\&" & Port)
Return ClientSocket
Catch ex As Exception
RaiseEvent Exception(ex)
Return Nothing
End Try
End Function
#End Region
Private Class ClientCommunication
Public Event Exception(ByVal ex As Exception)
Private ServerSocket As New System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
Private myClientSocket As New System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
Private myParentObject As TCPServer
Private oldbytes() As Byte
Private _IPAddress, _Port As String
Private NclientInfoT As IPEndPoint = Nothing
Private iLen As Integer
Private allDone As New ManualResetEvent(False)
''' <summary>
''' 实例ClientCommunication类
''' </summary>
''' <param name="ServerSocket"></param>
''' <param name="ClientSocket"></param>
''' <param name="ParentObject"></param>
''' <remarks></remarks>
Public Sub New(ByVal ServerSocket As Socket, ByVal ClientSocket As Socket, ByVal ParentObject As TCPServer)
Me.ServerSocket = ServerSocket
myClientSocket = ClientSocket
myParentObject = ParentObject
NclientInfoT = CType(myClientSocket.RemoteEndPoint, IPEndPoint)
_IPAddress = NclientInfoT.Address.ToString
_Port = NclientInfoT.Port.ToString
End Sub
''' <summary>
''' 客户端通讯主线程
''' </summary>
''' <remarks></remarks>
Public Sub serverThreadProc()
Try
Dim sb As New SocketAndBuffer
sb.Socket = myClientSocket
sb.Socket.BeginReceive(sb.Buffer, 0, sb.Buffer.Length, SocketFlags.None, AddressOf ReceiveCallBack, sb)
'allDone.WaitOne()
Catch ex As Exception
RaiseEvent Exception(ex)
End Try
End Sub
''' <summary>
''' socket异步接收回调函数
''' </summary>
''' <param name="ar"></param>
''' <remarks></remarks>
Private Sub ReceiveCallBack(ByVal ar As IAsyncResult)
Dim sb As SocketAndBuffer
allDone.Set()
sb = CType(ar.AsyncState, SocketAndBuffer)
Try
If sb.Socket.Connected Then
iLen = sb.Socket.EndReceive(ar)
If iLen > 0 Then
ReDim oldbytes(iLen - 1)
Array.Copy(sb.Buffer, 0, oldbytes, 0, iLen)
myParentObject.GetData_Byte(oldbytes, oldbytes.Length, _IPAddress, _Port)
sb.Socket.BeginReceive(sb.Buffer, 0, sb.Buffer.Length, SocketFlags.None, AddressOf ReceiveCallBack, sb)
Else
If (Not myClientSocket Is Nothing) Then
If myClientSocket.Connected Then
myClientSocket.Close()
Else
myClientSocket.Close()
End If
myClientSocket = Nothing
If Not NclientInfoT Is Nothing Then
myParentObject._Clients.Remove(_IPAddress & "\&" & _Port)
myParentObject.GetClientClose(_IPAddress, _Port)
End If
End If
End If
End If
Catch ex As Exception
If (Not myClientSocket Is Nothing) Then
If myClientSocket.Connected Then
myClientSocket.Close()
Else
myClientSocket.Close()
End If
myClientSocket = Nothing
If Not NclientInfoT Is Nothing Then
myParentObject._Clients.Remove(_IPAddress & "\&" & _Port)
myParentObject.GetClientClose(_IPAddress, _Port)
End If
End If
RaiseEvent Exception(ex)
End Try
End Sub
''' <summary>
''' 异步操作socket缓冲类
''' </summary>
''' <remarks></remarks>
Private Class SocketAndBuffer
Public Socket As System.Net.Sockets.Socket
Public Buffer(8192) As Byte
End Class
End Class
End Class
Imports System.Net Imports System.Net.Sockets Imports System.Threading Imports System.Text '********************************************************************************************************** '''''' 类名:TCPServer '''''' 说明:监听主线程,用于监听客户端联接,并记录客户端联接,接收和发送数据 '''''' 与客户端的联接采用TCP联接 '********************************************************************************************************** ''' <summary> ''' 侦听客户端联接 ''' </summary> Public Class TCPServer #Region "私有成员" Private _LocationListenSocket As Socket '本地侦听服务 Private _ListenPort As String '服务器侦听客户端联接的端口 Private _MaxClient As Integer '最大客户端连接数 Private _Clients As New SortedList '客户端队列 Private _ListenThread As Thread = Nothing '侦听线程 Private _ServerStart As Boolean = False '服务器是否已经启动 Private _RecvMax As Integer '接收缓冲区大小 #End Region #Region "事件" ''' <summary> ''' 客户端联接事件 ''' </summary> ''' <param name="IP">客户端联接IP</param> ''' <param name="Port">客户端联接端口号</param> ''' <remarks></remarks> Public Event ClientConnected(ByVal IP As String, ByVal Port As String) ''' <summary> ''' 客户端断开事件 ''' </summary> ''' <param name="IP">客户端联接IP</param> ''' <param name="Port">客户端联接端口号</param> ''' <remarks></remarks> Public Event ClientClose(ByVal IP As String, ByVal Port As String) ''' <summary> ''' 接收到客户端的数据 ''' </summary> ''' <param name="value">数据</param> ''' <param name="IPAddress">数据来源IP</param> ''' <param name="Port">数据来源端口</param> ''' <remarks></remarks> Public Event DataArrived(ByVal value As Byte(), ByVal Len As Integer, ByVal IPAddress As String, ByVal Port As String) ''' <summary> ''' 异常数据 ''' </summary> ''' <param name="ex"></param> ''' <remarks></remarks> Public Event Exception(ByVal ex As Exception) #End Region #Region "属性" ''' <summary> ''' 侦听服务是否已经启动 ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Public ReadOnly Property IsServerStart() As Boolean Get Return _ServerStart End Get End Property #End Region #Region "方法" ''' <summary> ''' 实例 TCPServer ''' </summary> ''' <param name="Port">侦听客户端联接的端口号</param> ''' <param name="MaxClient">最大可以联接的客户端数量</param> ''' <param name="RecvMax">接收缓冲区大小</param> ''' <param name="RecvSleep">接收线程睡眠时间</param> ''' <remarks></remarks> Sub New(ByVal Port As String, ByVal MaxClient As Integer, ByVal RecvMax As Integer, ByVal RecvSleep As Integer) Try Dim strHostName As String = Dns.GetHostName() _ListenPort = Port _MaxClient = MaxClient _RecvMax = RecvMax Dim strServerHost As New IPEndPoint(IPAddress.Any, Int32.Parse(_ListenPort)) '建立TCP侦听 _LocationListenSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) _LocationListenSocket.Bind(strServerHost) _LocationListenSocket.Listen(_MaxClient) _LocationListenSocket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.AcceptConnection, 1) Catch ex As Exception RaiseEvent Exception(ex) End Try End Sub ''' <summary> ''' 开始侦听服务 ''' </summary> ''' <remarks></remarks> Public Sub StartServer() _ServerStart = True Try _ListenThread = New Thread(New ThreadStart(AddressOf ListenClient)) _ListenThread.Name = "监听客户端主线程" _ListenThread.Start() Catch ex As Exception If (Not _LocationListenSocket Is Nothing) Then If _LocationListenSocket.Connected Then _LocationListenSocket.Close() End If End If RaiseEvent Exception(ex) End Try End Sub ''' <summary> ''' 关闭侦听 ''' </summary> ''' <remarks></remarks> Public Sub Close() Try _ServerStart = False 'CloseAllClient() Thread.Sleep(5) _ListenThread.Abort() _LocationListenSocket.Close() _ListenThread = Nothing Catch ex As Exception RaiseEvent Exception(ex) End Try End Sub ''' <summary> ''' 客户端侦听线程 ''' </summary> ''' <remarks></remarks> Private Sub ListenClient() Dim sKey As String While (_ServerStart) Try If Not _LocationListenSocket Is Nothing Then Dim clientSocket As System.Net.Sockets.Socket clientSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) clientSocket = _LocationListenSocket.Accept() If Not clientSocket Is Nothing Then Dim clientInfoT As IPEndPoint = CType(clientSocket.RemoteEndPoint, IPEndPoint) sKey = clientInfoT.Address.ToString & "\&" & clientInfoT.Port.ToString _Clients.Add(sKey, clientSocket) RaiseEvent ClientConnected(clientInfoT.Address.ToString, clientInfoT.Port.ToString) '举起有客户端联接的事件 '启动客户端接收主线程,开始侦听并接收客户端上传的数据 Dim lb As New ClientCommunication(_LocationListenSocket, clientSocket, Me) AddHandler lb.Exception, AddressOf WriteErrorEvent_ClientCommunication Dim thrClient As New Thread(New ThreadStart(AddressOf lb.serverThreadProc)) thrClient.Name = "客户端接收线程,客户端" & clientInfoT.Address.ToString & ":" & clientInfoT.Port.ToString thrClient.Start() End If End If Catch ex As Exception RaiseEvent Exception(ex) End Try End While End Sub Private Sub WriteErrorEvent_ClientCommunication(ByVal ex As Exception) RaiseEvent Exception(ex) End Sub Public Sub CloseClient(ByVal IP As String, ByVal Port As String) GetClientSocket(IP, Port).Close() GetClientClose(IP, Port) End Sub 'Public Sub AlertNoticeClientAll(ByVal DepartmentName As String, ByVal LineName As String, ByVal ErrorCode As Integer) ' '#DepartmentName,LineName,AlertCodeValue. ' ' ''Dim mStr As String ' ' ''mStr = "#" & DepartmentName & "," & LineName & "," & ErrorCode ' ' ''Dim SendByte() As Byte = System.Text.UTF8Encoding.Default.GetBytes(mStr) ' ' ''For Each sc As System.Net.Sockets.Socket In _ClientComputers.Values ' ' '' sc.Send(SendByte, SendByte.Length(), SocketFlags.None) ' ' ''Next 'End Sub Public Sub CloseAllClient() For Each sc As System.Net.Sockets.Socket In _Clients.Values '断开所有工作站的Socket连接。 Dim clientInfoT As IPEndPoint = CType(sc.RemoteEndPoint, IPEndPoint) CloseClient(clientInfoT.Address.ToString, clientInfoT.Port.ToString) Next End Sub #Region "接收客户端的数据" ''' <summary> ''' 接收到客户端的数据-字节数组 ''' </summary> ''' <param name="value">数据内容</param> ''' <param name="Len">字节长度</param> ''' <param name="IPAddress">发送该数据的IP地址</param> ''' <param name="Port">发送该数据的端口号</param> ''' <remarks></remarks> Private Sub GetData_Byte(ByVal value As Byte(), ByVal Len As Integer, ByVal IPAddress As String, ByVal Port As String) Try RaiseEvent DataArrived(value, Len, IPAddress, Port) 'Catch exx As Sockets.SocketException ' CloseClient(IPAddress, Port) Catch ex As Exception RaiseEvent Exception(ex) End Try End Sub ''' <summary> ''' 得到客户端断开或失去客户端联连事件 ''' </summary> ''' <param name="IP">客户端联接IP</param> ''' <param name="Port">客户端联接端口号</param> ''' <remarks></remarks> Private Sub GetClientClose(ByVal IP As String, ByVal Port As String) Try If _Clients.ContainsKey(IP & "\&" & Port) Then SyncLock _Clients.SyncRoot '_Clients.Item(IP & "\&" & Port) _Clients.Remove(IP & "\&" & Port) End SyncLock End If RaiseEvent ClientClose(IP, Port) Catch ex As Exception RaiseEvent Exception(ex) End Try End Sub #End Region #Region "向客户端发送数据" ''' <summary> ''' 向客户端发送信息 ''' </summary> ''' <param name="value">发送的内容</param> ''' <param name="IPAddress">IP地址</param> ''' <param name="Port">端口号</param> ''' <returns> Boolean</returns> ''' <remarks></remarks> Public Function SendData(ByVal value As Byte(), ByVal IPAddress As String, ByVal Port As String) As Boolean Try Dim clientSocket As System.Net.Sockets.Socket clientSocket = _Clients.Item(IPAddress & "\&" & Port) clientSocket.Send(value, value.Length, SocketFlags.None) Return True Catch ex As Exception RaiseEvent Exception(ex) Return False End Try End Function Public Function SendFile(ByVal value As String, ByVal IPAddress As String, ByVal Port As String) As Boolean Try Dim clientSocket As System.Net.Sockets.Socket clientSocket = _Clients.Item(IPAddress & "\&" & Port) clientSocket.SendFile(value) Return True Catch ex As Exception RaiseEvent Exception(ex) Return False End Try End Function Public Function SendDataToAllClient(ByVal value As Byte()) As Boolean Try For Each clientSocket As System.Net.Sockets.Socket In _Clients.Values clientSocket.Send(value, value.Length, SocketFlags.None) Next Return True Catch ex As Exception RaiseEvent Exception(ex) Return False End Try End Function #End Region ''' <summary> ''' 得到客户端的Socket联接 ''' </summary> ''' <param name="IPAddress">客户端的IP</param> ''' <param name="Port">客户端的端口号</param> ''' <returns>Socket联接</returns> ''' <remarks></remarks> Private Function GetClientSocket(ByVal IPAddress As String, ByVal Port As String) As Socket Try Dim ClientSocket As Socket ClientSocket = _Clients.Item(IPAddress & "\&" & Port) Return ClientSocket Catch ex As Exception RaiseEvent Exception(ex) Return Nothing End Try End Function #End Region Private Class ClientCommunication Public Event Exception(ByVal ex As Exception) Private ServerSocket As New System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) Private myClientSocket As New System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) Private myParentObject As TCPServer Private oldbytes() As Byte Private _IPAddress, _Port As String Private NclientInfoT As IPEndPoint = Nothing Private iLen As Integer Private allDone As New ManualResetEvent(False) ''' <summary> ''' 实例ClientCommunication类 ''' </summary> ''' <param name="ServerSocket"></param> ''' <param name="ClientSocket"></param> ''' <param name="ParentObject"></param> ''' <remarks></remarks> Public Sub New(ByVal ServerSocket As Socket, ByVal ClientSocket As Socket, ByVal ParentObject As TCPServer) Me.ServerSocket = ServerSocket myClientSocket = ClientSocket myParentObject = ParentObject NclientInfoT = CType(myClientSocket.RemoteEndPoint, IPEndPoint) _IPAddress = NclientInfoT.Address.ToString _Port = NclientInfoT.Port.ToString End Sub ''' <summary> ''' 客户端通讯主线程 ''' </summary> ''' <remarks></remarks> Public Sub serverThreadProc() Try Dim sb As New SocketAndBuffer sb.Socket = myClientSocket sb.Socket.BeginReceive(sb.Buffer, 0, sb.Buffer.Length, SocketFlags.None, AddressOf ReceiveCallBack, sb) 'allDone.WaitOne() Catch ex As Exception RaiseEvent Exception(ex) End Try End Sub ''' <summary> ''' socket异步接收回调函数 ''' </summary> ''' <param name="ar"></param> ''' <remarks></remarks> Private Sub ReceiveCallBack(ByVal ar As IAsyncResult) Dim sb As SocketAndBuffer allDone.Set() sb = CType(ar.AsyncState, SocketAndBuffer) Try If sb.Socket.Connected Then iLen = sb.Socket.EndReceive(ar) If iLen > 0 Then ReDim oldbytes(iLen - 1) Array.Copy(sb.Buffer, 0, oldbytes, 0, iLen) myParentObject.GetData_Byte(oldbytes, oldbytes.Length, _IPAddress, _Port) sb.Socket.BeginReceive(sb.Buffer, 0, sb.Buffer.Length, SocketFlags.None, AddressOf ReceiveCallBack, sb) Else If (Not myClientSocket Is Nothing) Then If myClientSocket.Connected Then myClientSocket.Close() Else myClientSocket.Close() End If myClientSocket = Nothing If Not NclientInfoT Is Nothing Then myParentObject._Clients.Remove(_IPAddress & "\&" & _Port) myParentObject.GetClientClose(_IPAddress, _Port) End If End If End If End If Catch ex As Exception If (Not myClientSocket Is Nothing) Then If myClientSocket.Connected Then myClientSocket.Close() Else myClientSocket.Close() End If myClientSocket = Nothing If Not NclientInfoT Is Nothing Then myParentObject._Clients.Remove(_IPAddress & "\&" & _Port) myParentObject.GetClientClose(_IPAddress, _Port) End If End If RaiseEvent Exception(ex) End Try End Sub ''' <summary> ''' 异步操作socket缓冲类 ''' </summary> ''' <remarks></remarks> Private Class SocketAndBuffer Public Socket As System.Net.Sockets.Socket Public Buffer(8192) As Byte End Class End Class End Class
2)TCP 客户端连接通信类
[vb]
view plaincopyprint?
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Public Class TCPClient
#Region "私有成员"
Private _LocationClientSocket As Socket '本地侦听服务
Private _LocalPort As String '本地端口
Private _LocalHostName As String
Private _LocalIP As String
Private autoEvent As AutoResetEvent
Private _RemoteHostName As String '遠程端計算機名
Private _RemoteIP As String '遠程端計算機IP
Private _RemotePort As String '遠程端計算機Port
Private _RemoteIPOrHostName As String
'Private _MaxClient As Integer '最大客户端连接数
'Private _Clients As New SortedList '客户端队列
'Private _ListenThread As Thread = Nothing '侦听线程
'Private _ServerStart As Boolean = False '服务器是否已经启动
Private _RecvMax As Integer '接收缓冲区大小
Private ClientThread As Thread
'Private ClitenStream As NetworkStream
Private IsStop As Boolean = False
#End Region
#Region "事件"
''' <summary>
''' 客户端联接事件
''' </summary>
''' <remarks></remarks>
Public Event ClientConnected()
''' <summary>
''' 客户端断开事件
''' </summary>
''' <remarks></remarks>
Public Event ClientClosed()
''' <summary>
''' 接收到客户端的数据
''' </summary>
''' <param name="value">数据</param>
''' <remarks></remarks>
Public Event DataArrived(ByVal value As Byte(), ByVal Len As Integer)
''' <summary>
''' 异常数据
''' </summary>
''' <param name="ex"></param>
''' <remarks></remarks>
Public Event Exception(ByVal ex As Exception)
#End Region
#Region "属性"
''' <summary>
''' 是否已經連接
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property Connected() As Boolean
Get
Return _LocationClientSocket.Connected
End Get
End Property
''' <summary>
''' 本地計算機名稱
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property LocalHostName() As String
Get
Return _LocalHostName
End Get
End Property
''' <summary>
''' 本地計算IP
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property LocalIP() As String
Get
Return _LocalIP
End Get
End Property
''' <summary>
''' 本地計算機端口
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property LocalPort() As String
Get
Return _LocalPort
End Get
End Property
''' <summary>
''' 遠程計算機IP
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property RemoteIP() As String
Get
Return _RemoteIP
End Get
End Property
''' <summary>
''' 遠程計算機端口
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property RemotePort() As String
Get
Return _RemotePort
End Get
End Property
''' <summary>
''' 遠程計算機名稱
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property RemoteHostName() As String
Get
Return _RemoteHostName
End Get
End Property
#End Region
#Region "方法"
''' <summary>
''' 实例 TCPServer
''' </summary>
''' <param name="RemoteIPOrHostName">需要連接服務的IP地址或計算機名稱</param>
''' <param name="Port">侦听客户端联接的端口号</param>
''' <param name="RecvMax">接收缓冲区大小</param>
''' <param name="RecvSleep">接收线程睡眠时间</param>
''' <remarks></remarks>
Sub New(ByVal RemoteIPOrHostName As String, ByVal Port As String, ByVal RecvMax As Integer, ByVal RecvSleep As Integer)
Try
_LocalHostName = Dns.GetHostName()
'_RemoteIP = Dns.GetHostAddresses(RemoteIPOrHostName)(0).ToString
_RemotePort = Port
_RecvMax = RecvMax
_RemoteIPOrHostName = RemoteIPOrHostName
_RemotePort = Port
'Dim strServerHost As New IPEndPoint(IPAddress.Any, Int32.Parse(_ListenPort))
'建立TCP侦听
_LocationClientSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
autoEvent = New AutoResetEvent(False)
Dim cThread As New Thread(New ThreadStart(AddressOf ConnectHost))
cThread.Start()
autoEvent.WaitOne(1000, False)
cThread.Abort()
Catch ex As Exception
RaiseEvent Exception(ex)
End Try
End Sub
Public Sub ConnectHost()
Try
Dim remoteIP As Net.IPAddress = Nothing
If IPAddress.TryParse(_RemoteIPOrHostName, remoteIP) Then
'_LocationClientSocket.BeginConnect()
_LocationClientSocket.Connect(remoteIP, _RemotePort)
'_RemoteIP = RemoteHostName
Else
_LocationClientSocket.Connect(_RemoteIPOrHostName, _RemotePort)
_RemoteHostName = RemoteHostName
End If
If _LocationClientSocket.Connected Then
_LocationClientSocket.SendBufferSize = _RecvMax
_LocationClientSocket.ReceiveBufferSize = _RecvMax
Dim clientInfoT As IPEndPoint
clientInfoT = CType(_LocationClientSocket.RemoteEndPoint, IPEndPoint)
_RemoteIP = clientInfoT.Address.ToString
'Dim remoteHost As Net.IPHostEntry
_RemoteHostName = Dns.GetHostEntry(_RemoteIP).HostName
clientInfoT = CType(_LocationClientSocket.LocalEndPoint, IPEndPoint)
_LocalIP = clientInfoT.Address.ToString
_LocalPort = clientInfoT.Port.ToString
IsStop = False
RaiseEvent ClientConnected()
ClientThread = New Thread(New ThreadStart(AddressOf ClientListen))
ClientThread.Start()
autoEvent.Set()
End If
Catch ex As Exception
End Try
End Sub
''' <summary>
''' 關閉客戶端連接
''' </summary>
''' <remarks></remarks>
Public Sub Close()
Try
If _LocationClientSocket Is Nothing Then Exit Sub
IsStop = True
If Not ClientThread Is Nothing Then
Thread.Sleep(5)
ClientThread.Abort()
End If
_LocationClientSocket.Close()
_LocationClientSocket = Nothing
ClientThread = Nothing
RaiseEvent ClientClosed()
Catch ex As Exception
RaiseEvent Exception(ex)
End Try
End Sub
''' <summary>
''' 实例 TCPServer
''' </summary>
''' <param name="value">發送的資料,二進制數組</param>
''' <remarks></remarks>
Public Function SendData(ByVal value As Byte()) As Boolean
Try
_LocationClientSocket.Send(value)
Catch ex As Exception
RaiseEvent Exception(ex)
End Try
End Function
Private Sub ClientListen()
Dim tmpByt(8192) As Byte
Dim recData() As Byte
Dim R As Integer
While Not IsStop
Try
If _LocationClientSocket.Poll(50, SelectMode.SelectWrite) Then
R = _LocationClientSocket.Receive(tmpByt)
If R > 0 Then
ReDim recData(R - 1)
Array.Copy(tmpByt, recData, R)
RaiseEvent DataArrived(recData, recData.Length)
Else
If (Not _LocationClientSocket Is Nothing) Then
_LocationClientSocket.Close()
_LocationClientSocket = Nothing
IsStop = True
RaiseEvent ClientClosed()
End If
End If
End If
Catch sex As SocketException
If sex.ErrorCode = 10054 Then
If (Not _LocationClientSocket Is Nothing) Then
_LocationClientSocket.Close()
_LocationClientSocket = Nothing
IsStop = True
RaiseEvent ClientClosed()
End If
Else
RaiseEvent Exception(sex)
End If
Catch ex As Exception
RaiseEvent Exception(ex)
End Try
End While
End Sub
#End Region
End Class
Imports System.Net Imports System.Net.Sockets Imports System.Threading Public Class TCPClient #Region "私有成员" Private _LocationClientSocket As Socket '本地侦听服务 Private _LocalPort As String '本地端口 Private _LocalHostName As String Private _LocalIP As String Private autoEvent As AutoResetEvent Private _RemoteHostName As String '遠程端計算機名 Private _RemoteIP As String '遠程端計算機IP Private _RemotePort As String '遠程端計算機Port Private _RemoteIPOrHostName As String 'Private _MaxClient As Integer '最大客户端连接数 'Private _Clients As New SortedList '客户端队列 'Private _ListenThread As Thread = Nothing '侦听线程 'Private _ServerStart As Boolean = False '服务器是否已经启动 Private _RecvMax As Integer '接收缓冲区大小 Private ClientThread As Thread 'Private ClitenStream As NetworkStream Private IsStop As Boolean = False #End Region #Region "事件" ''' <summary> ''' 客户端联接事件 ''' </summary> ''' <remarks></remarks> Public Event ClientConnected() ''' <summary> ''' 客户端断开事件 ''' </summary> ''' <remarks></remarks> Public Event ClientClosed() ''' <summary> ''' 接收到客户端的数据 ''' </summary> ''' <param name="value">数据</param> ''' <remarks></remarks> Public Event DataArrived(ByVal value As Byte(), ByVal Len As Integer) ''' <summary> ''' 异常数据 ''' </summary> ''' <param name="ex"></param> ''' <remarks></remarks> Public Event Exception(ByVal ex As Exception) #End Region #Region "属性" ''' <summary> ''' 是否已經連接 ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Public ReadOnly Property Connected() As Boolean Get Return _LocationClientSocket.Connected End Get End Property ''' <summary> ''' 本地計算機名稱 ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Public ReadOnly Property LocalHostName() As String Get Return _LocalHostName End Get End Property ''' <summary> ''' 本地計算IP ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Public ReadOnly Property LocalIP() As String Get Return _LocalIP End Get End Property ''' <summary> ''' 本地計算機端口 ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Public ReadOnly Property LocalPort() As String Get Return _LocalPort End Get End Property ''' <summary> ''' 遠程計算機IP ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Public ReadOnly Property RemoteIP() As String Get Return _RemoteIP End Get End Property ''' <summary> ''' 遠程計算機端口 ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Public ReadOnly Property RemotePort() As String Get Return _RemotePort End Get End Property ''' <summary> ''' 遠程計算機名稱 ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Public ReadOnly Property RemoteHostName() As String Get Return _RemoteHostName End Get End Property #End Region #Region "方法" ''' <summary> ''' 实例 TCPServer ''' </summary> ''' <param name="RemoteIPOrHostName">需要連接服務的IP地址或計算機名稱</param> ''' <param name="Port">侦听客户端联接的端口号</param> ''' <param name="RecvMax">接收缓冲区大小</param> ''' <param name="RecvSleep">接收线程睡眠时间</param> ''' <remarks></remarks> Sub New(ByVal RemoteIPOrHostName As String, ByVal Port As String, ByVal RecvMax As Integer, ByVal RecvSleep As Integer) Try _LocalHostName = Dns.GetHostName() '_RemoteIP = Dns.GetHostAddresses(RemoteIPOrHostName)(0).ToString _RemotePort = Port _RecvMax = RecvMax _RemoteIPOrHostName = RemoteIPOrHostName _RemotePort = Port 'Dim strServerHost As New IPEndPoint(IPAddress.Any, Int32.Parse(_ListenPort)) '建立TCP侦听 _LocationClientSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) autoEvent = New AutoResetEvent(False) Dim cThread As New Thread(New ThreadStart(AddressOf ConnectHost)) cThread.Start() autoEvent.WaitOne(1000, False) cThread.Abort() Catch ex As Exception RaiseEvent Exception(ex) End Try End Sub Public Sub ConnectHost() Try Dim remoteIP As Net.IPAddress = Nothing If IPAddress.TryParse(_RemoteIPOrHostName, remoteIP) Then '_LocationClientSocket.BeginConnect() _LocationClientSocket.Connect(remoteIP, _RemotePort) '_RemoteIP = RemoteHostName Else _LocationClientSocket.Connect(_RemoteIPOrHostName, _RemotePort) _RemoteHostName = RemoteHostName End If If _LocationClientSocket.Connected Then _LocationClientSocket.SendBufferSize = _RecvMax _LocationClientSocket.ReceiveBufferSize = _RecvMax Dim clientInfoT As IPEndPoint clientInfoT = CType(_LocationClientSocket.RemoteEndPoint, IPEndPoint) _RemoteIP = clientInfoT.Address.ToString 'Dim remoteHost As Net.IPHostEntry _RemoteHostName = Dns.GetHostEntry(_RemoteIP).HostName clientInfoT = CType(_LocationClientSocket.LocalEndPoint, IPEndPoint) _LocalIP = clientInfoT.Address.ToString _LocalPort = clientInfoT.Port.ToString IsStop = False RaiseEvent ClientConnected() ClientThread = New Thread(New ThreadStart(AddressOf ClientListen)) ClientThread.Start() autoEvent.Set() End If Catch ex As Exception End Try End Sub ''' <summary> ''' 關閉客戶端連接 ''' </summary> ''' <remarks></remarks> Public Sub Close() Try If _LocationClientSocket Is Nothing Then Exit Sub IsStop = True If Not ClientThread Is Nothing Then Thread.Sleep(5) ClientThread.Abort() End If _LocationClientSocket.Close() _LocationClientSocket = Nothing ClientThread = Nothing RaiseEvent ClientClosed() Catch ex As Exception RaiseEvent Exception(ex) End Try End Sub ''' <summary> ''' 实例 TCPServer ''' </summary> ''' <param name="value">發送的資料,二進制數組</param> ''' <remarks></remarks> Public Function SendData(ByVal value As Byte()) As Boolean Try _LocationClientSocket.Send(value) Catch ex As Exception RaiseEvent Exception(ex) End Try End Function Private Sub ClientListen() Dim tmpByt(8192) As Byte Dim recData() As Byte Dim R As Integer While Not IsStop Try If _LocationClientSocket.Poll(50, SelectMode.SelectWrite) Then R = _LocationClientSocket.Receive(tmpByt) If R > 0 Then ReDim recData(R - 1) Array.Copy(tmpByt, recData, R) RaiseEvent DataArrived(recData, recData.Length) Else If (Not _LocationClientSocket Is Nothing) Then _LocationClientSocket.Close() _LocationClientSocket = Nothing IsStop = True RaiseEvent ClientClosed() End If End If End If Catch sex As SocketException If sex.ErrorCode = 10054 Then If (Not _LocationClientSocket Is Nothing) Then _LocationClientSocket.Close() _LocationClientSocket = Nothing IsStop = True RaiseEvent ClientClosed() End If Else RaiseEvent Exception(sex) End If Catch ex As Exception RaiseEvent Exception(ex) End Try End While End Sub #End Region End Class
窗体调用TCP 类如下
服务器端:
[vb]
view plaincopyprint?
Public WithEvents MyClient As TCPServer
Public WithEvents MyClient As TCPServer
客户机端:
[vb]
view plaincopyprint?
Public WithEvents MyClient As TCPClient
Public WithEvents MyClient As TCPClient
相关文章推荐
- [Unity通信]一个基于socket的3DARPG网络游戏(一):建立连接和事件分发
- 基于事件的异步Socket(TCP连接方式)
- 【socket编程】 一个简单的基于TCP连接的客户端、服务端用例
- [转] 基于事件的异步Socket(TCP连接方式)
- socket 网络编程快速入门(二)教你编写基于UDP/TCP的服务端多线程通信
- 超基础的网络编程02:基于TCP的Socket通信
- 基于TCP网络通信的自动升级程序源码分析-客户端连接服务器
- Python网络通信之socket模块(四)基于Tcp/Ip的TCP交互通信serve/client的编写过程
- socket 网络编程高速入门(一)教你编写基于UDP/TCP的服务(client)通信
- 网络通信——socket(TCP/IP).Http,同步和异步的区别
- 分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载
- Linux网络编程之[基于socket通信的tcp协议的编程模型]
- CocoaAsyncSocket网络通信使用之tcp连接(一)
- CocoaAsyncSocket网络通信使用之tcp连接
- java学习之路——基于TCP的Socket网络通信实例
- 基于事件的异步Socket(TCP连接方式)
- socket 网络编程快速入门(一)教你编写基于UDP/TCP的服务(客户端)通信
- 分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载 推荐
- Unity(C#.net)网络通信问题解决(服务器开启失败,Socket下的“由于目标机器积极拒绝,无法连接”异常)
- WSAAsyncSelect基于异步通知的网络socket通信案例一