一个基于VB.net的异步Socket网络TCP通信可防止任意一端意外终止T

之前,因为要做一个TCP通信的项目,有研究一下Socket类,但是为了快速完成任务,还是在网上找了一些源码来调试测试,发现很多源码都无法触发TCP连接的任意一端

的突然意外中断连接的事件,于是本人基于他人的源码基础上进行了修改,可以触发这一事件,,可使TCP连接的另一端触发对方已经终止TCP连接事件。

以下,奉上本人修改后的源码类:

1)TCP 服务器TCP 侦听类。

Imports System.NetImports System.Net.SocketsImports System.ThreadingImports 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 BooleanGetReturn _ServerStartEnd GetEnd 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)TryDim strHostName As String = Dns.GetHostName()_ListenPort = Port_MaxClient = MaxClient_RecvMax = RecvMaxDim 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 ExceptionRaiseEvent Exception(ex)End TryEnd Sub”’ <summary>”’ 开始侦听服务”’ </summary>”’ <remarks></remarks>Public Sub StartServer()_ServerStart = TrueTry_ListenThread = New Thread(New ThreadStart(AddressOf ListenClient))_ListenThread.Name = "监听客户端主线程"_ListenThread.Start()Catch ex As ExceptionIf (Not _LocationListenSocket Is Nothing) ThenIf _LocationListenSocket.Connected Then_LocationListenSocket.Close()End IfEnd IfRaiseEvent Exception(ex)End TryEnd Sub”’ <summary>”’ 关闭侦听”’ </summary>”’ <remarks></remarks>Public Sub Close()Try_ServerStart = False’CloseAllClient()Thread.Sleep(5)_ListenThread.Abort()_LocationListenSocket.Close()_ListenThread = NothingCatch ex As ExceptionRaiseEvent Exception(ex)End TryEnd Sub”’ <summary>”’ 客户端侦听线程”’ </summary>”’ <remarks></remarks>Private Sub ListenClient()Dim sKey As StringWhile (_ServerStart)TryIf Not _LocationListenSocket Is Nothing ThenDim clientSocket As System.Net.Sockets.SocketclientSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)clientSocket = _LocationListenSocket.Accept()If Not clientSocket Is Nothing ThenDim 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_ClientCommunicationDim thrClient As New Thread(New ThreadStart(AddressOf lb.serverThreadProc))thrClient.Name = "客户端接收线程,客户端" & clientInfoT.Address.ToString & ":" & clientInfoT.Port.ToStringthrClient.Start()End IfEnd IfCatch ex As ExceptionRaiseEvent Exception(ex)End TryEnd WhileEnd SubPrivate Sub WriteErrorEvent_ClientCommunication(ByVal ex As Exception)RaiseEvent Exception(ex)End SubPublic 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 SubPublic 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)NextEnd 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)TryRaiseEvent DataArrived(value, Len, IPAddress, Port)’Catch exx As Sockets.SocketException’ CloseClient(IPAddress, Port)Catch ex As ExceptionRaiseEvent Exception(ex)End TryEnd 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)TryIf _Clients.ContainsKey(IP & "\&;" & Port) ThenSyncLock _Clients.SyncRoot’_Clients.Item(IP & "\&;" & Port)_Clients.Remove(IP & "\&;" & Port)End SyncLockEnd IfRaiseEvent ClientClose(IP, Port)Catch ex As ExceptionRaiseEvent Exception(ex)End TryEnd 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 BooleanTryDim clientSocket As System.Net.Sockets.SocketclientSocket = _Clients.Item(IPAddress & "\&;" & Port)clientSocket.Send(value, value.Length, SocketFlags.None)Return TrueCatch ex As ExceptionRaiseEvent Exception(ex)Return FalseEnd TryEnd FunctionPublic Function SendFile(ByVal value As String, ByVal IPAddress As String, ByVal Port As String) As BooleanTryDim clientSocket As System.Net.Sockets.SocketclientSocket = _Clients.Item(IPAddress & "\&;" & Port)clientSocket.SendFile(value)Return TrueCatch ex As ExceptionRaiseEvent Exception(ex)Return FalseEnd TryEnd FunctionPublic Function SendDataToAllClient(ByVal value As Byte()) As BooleanTryFor Each clientSocket As System.Net.Sockets.Socket In _Clients.ValuesclientSocket.Send(value, value.Length, SocketFlags.None)NextReturn TrueCatch ex As ExceptionRaiseEvent Exception(ex)Return FalseEnd TryEnd 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 SocketTryDim ClientSocket As SocketClientSocket = _Clients.Item(IPAddress & "\&;" & Port)Return ClientSocketCatch ex As ExceptionRaiseEvent Exception(ex)Return NothingEnd TryEnd Function#End RegionPrivate Class ClientCommunicationPublic 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 TCPServerPrivate oldbytes() As BytePrivate _IPAddress, _Port As StringPrivate NclientInfoT As IPEndPoint = NothingPrivate iLen As IntegerPrivate 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 = ServerSocketmyClientSocket = ClientSocketmyParentObject = ParentObjectNclientInfoT = CType(myClientSocket.RemoteEndPoint, IPEndPoint)_IPAddress = NclientInfoT.Address.ToString_Port = NclientInfoT.Port.ToStringEnd Sub”’ <summary>”’ 客户端通讯主线程”’ </summary>”’ <remarks></remarks>Public Sub serverThreadProc()TryDim sb As New SocketAndBuffersb.Socket = myClientSocketsb.Socket.BeginReceive(sb.Buffer, 0, sb.Buffer.Length, SocketFlags.None, AddressOf ReceiveCallBack, sb)’allDone.WaitOne()Catch ex As ExceptionRaiseEvent Exception(ex)End TryEnd Sub”’ <summary>”’ socket异步接收回调函数”’ </summary>”’ <param name="ar"></param>”’ <remarks></remarks>Private Sub ReceiveCallBack(ByVal ar As IAsyncResult)Dim sb As SocketAndBufferallDone.Set()sb = CType(ar.AsyncState, SocketAndBuffer)TryIf sb.Socket.Connected TheniLen = sb.Socket.EndReceive(ar)If iLen > 0 ThenReDim 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)ElseIf (Not myClientSocket Is Nothing) ThenIf myClientSocket.Connected ThenmyClientSocket.Close()ElsemyClientSocket.Close()End IfmyClientSocket = NothingIf Not NclientInfoT Is Nothing ThenmyParentObject._Clients.Remove(_IPAddress & "\&;" & _Port)myParentObject.GetClientClose(_IPAddress, _Port)End IfEnd IfEnd IfEnd IfCatch ex As ExceptionIf (Not myClientSocket Is Nothing) ThenIf myClientSocket.Connected ThenmyClientSocket.Close()ElsemyClientSocket.Close()End IfmyClientSocket = NothingIf Not NclientInfoT Is Nothing ThenmyParentObject._Clients.Remove(_IPAddress & "\&;" & _Port)myParentObject.GetClientClose(_IPAddress, _Port)End IfEnd IfRaiseEvent Exception(ex)End TryEnd Sub”’ <summary>”’ 异步操作socket缓冲类”’ </summary>”’ <remarks></remarks>Private Class SocketAndBufferPublic Socket As System.Net.Sockets.SocketPublic Buffer(8192) As ByteEnd ClassEnd ClassEnd Class躲在某一地点,想念一个站在来路,

一个基于VB.net的异步Socket网络TCP通信可防止任意一端意外终止T

相关文章:

你感兴趣的文章:

标签云: