'********************************************************************** ' 适用于 .Net3.5版本 '********************************************************************** Imports System.Net.Sockets Imports System.Net Imports System.Collections.Generic Imports System.Linq PublicClass Socket35Class Socket35 自定义Socket结构体#Region "自定义Socket结构体" PublicClass MySocketClass MySocket Private MyWorkSocket As Socket Private MyWorkID As Int32 Private MyWorkName AsString ''' <summary> ''' 设置工作Socket ''' </summary> ''' <value>Scoket对象</value> ''' <returns></returns> ''' <remarks></remarks> PublicProperty WorkSocket()Property WorkSocket() As Socket Get Return MyWorkSocket EndGet Set(ByVal value As Socket) MyWorkSocket = value EndSet End Property ''' <summary> ''' Socket工作ID ''' </summary> ''' <value>Integer值</value> ''' <returns></returns> ''' <remarks></remarks> PublicProperty WorkID()Property WorkID() As Int32 Get Return MyWorkID EndGet Set(ByVal value As Int32) MyWorkID = value EndSet End Property ''' <summary> ''' Socket工作名称 ''' </summary> ''' <value>String值</value> ''' <returns></returns> ''' <remarks></remarks> PublicProperty WorkName()Property WorkName() AsString Get Return MyWorkName EndGet Set(ByVal value AsString) MyWorkName = value EndSet End Property End Class #End Region Socket协义类型#Region "Socket协义类型" PublicEnum SocketTypeEnum SocketType TCP UDP End Enum #End Region Private SocketID As Int32 Private Server As Socket Private ServerHas AsNew HashSet(Of MySocket) Private MyReceiveBuff(), MySendBuff() AsByte PublicDelegateSub EventHandler()Sub EventHandler(ByRef Sender As MySocket, ByVal e As SocketAsyncEventArgs) '------------------------------------------------------------------------------------------------------------- PublicEvent OnAccept As EventHandler '客户端连接事件 PublicEvent OnReceive As EventHandler '客户端传入数据事件 PublicEvent OnDisconnected As EventHandler '客户端断开事件 PublicEvent OnSent As EventHandler '数据发送完毕 '********************************************************************** ' Socket对象定义、接收数据、发送数据、外部事件引发 '********************************************************************** 构造函数#Region "构造函数" ''' <summary> ''' 初始化Socket35 ''' </summary> ''' <param name="ProtocolType">协议类型</param> ''' <remarks></remarks> Sub New()SubNew(ByVal ProtocolType As SocketType) '复位SocketID值 SocketID =1 SelectCase ProtocolType Case SocketType.TCP Server =New Socket(AddressFamily.InterNetwork, Sockets.SocketType.Stream, Sockets.ProtocolType.Tcp) Case SocketType.UDP Server =New Socket(AddressFamily.InterNetwork, Sockets.SocketType.Dgram, Sockets.ProtocolType.Udp) EndSelect End Sub ''' <summary> ''' 初始化Socket35 ''' </summary> ''' <param name="ProtocolType">协议类型</param> ''' <param name="ReceiveBuffLength">接收缓冲区长度</param> ''' <param name="SendBuffLength">发送缓冲区长度</param> ''' <remarks></remarks> Sub New()SubNew(ByVal ProtocolType As SocketType, ByVal ReceiveBuffLength As Int32, ByVal SendBuffLength As Int32) '复位SocketID值 SocketID =1 If ReceiveBuffLength <1OrElse SendBuffLength <1Then ThrowNew Exception("缓冲区大小必须大于0", New OverflowException) Exit Sub EndIf SelectCase ProtocolType Case SocketType.TCP Server =New Socket(AddressFamily.InterNetwork, Sockets.SocketType.Stream, Sockets.ProtocolType.Tcp) Case SocketType.UDP Server =New Socket(AddressFamily.InterNetwork, Sockets.SocketType.Dgram, Sockets.ProtocolType.Udp) EndSelect ReceiveBuff = ReceiveBuffLength SendBuff = SendBuffLength End Sub #End Region 连接服务器#Region "连接服务器" ''' <summary> ''' 连接到服务器端 ''' </summary> ''' <param name="Ip">IP地址</param> ''' <param name="Port">端口</param> ''' <returns>MySocket对象</returns> ''' <remarks></remarks> PublicFunction Connect()Function Connect(ByVal Ip AsString, ByVal Port As Int32) As MySocket Dim MS AsNew MySocket '复位SocketID值 SocketID =1 Server.Connect(Ip, Port) MS.WorkID = SocketID MS.WorkSocket = Server ServerHas.Add(MS) Return MS End Function ''' <summary> ''' 连接到服务器端 ''' </summary> ''' <param name="RemotoEndPoint">远程服务器节点</param> ''' <returns>MySocket对象</returns> ''' <remarks></remarks> PublicFunction Connect()Function Connect(ByVal RemotoEndPoint As IPEndPoint) As MySocket Dim MS AsNew MySocket '复位SocketID值 SocketID =1 Server.Connect(RemotoEndPoint) MS.WorkID = SocketID MS.WorkSocket = Server ServerHas.Add(MS) Return MS End Function #End Region 接收缓冲区大小#Region "接收缓冲区大小" ''' <summary> ''' 读取或设置接收缓冲区大小 ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> PublicProperty ReceiveBuff()Property ReceiveBuff() As Int32 Get Return MyReceiveBuff.Length EndGet Set(ByVal value As Int32) ReDim MyReceiveBuff(value) EndSet End Property #End Region 发送缓冲区大小#Region "发送缓冲区大小" ''' <summary> ''' 读取或设置发送缓冲区大小 ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> PublicProperty SendBuff()Property SendBuff() As Int32 Get Return MySendBuff.Length EndGet Set(ByVal value As Int32) ReDim MySendBuff(value) EndSet End Property #End Region 绑定地址和端口#Region "绑定地址和端口" ''' <summary> ''' 绑定地址和端口 ''' </summary> ''' <param name="Ip">Ip地址</param> ''' <param name="Port">端口</param> ''' <remarks></remarks> PublicOverloadsSub Bind()Sub Bind(ByVal Ip AsString, ByVal Port As Int32) Server.Bind(New IPEndPoint(IPAddress.Parse(Ip), Port)) End Sub ''' <summary> ''' 绑定地址和端口 ''' </summary> ''' <param name="IpEndPoint">Ip地址和端口的节点</param> ''' <remarks></remarks> PublicOverloadsSub Bind()Sub Bind(ByVal IpEndPoint As IPEndPoint) Server.Bind(IpEndPoint) End Sub #End Region 侦听数#Region "侦听数" ''' <summary> ''' 设置侦听数 ''' </summary> ''' <param name="val">侦听数</param> ''' <remarks></remarks> PublicSub Listen()Sub Listen(ByValvalAs Int32) Server.Listen(val) End Sub #End Region 开始侦听#Region "开始侦听" ''' <summary> ''' 开始侦听客户端连接 ''' </summary> ''' <remarks></remarks> PublicSub Start()Sub Start() SelectCase Server.ProtocolType Case ProtocolType.Tcp StartForTcp() Case ProtocolType.Udp StartForUdp() EndSelect End Sub PrivateSub StartForTcp()Sub StartForTcp() Dim acc AsNew SocketAsyncEventArgs AddHandler acc.Completed, AddressOf Accept_Completed Server.AcceptAsync(acc) End Sub PrivateSub StartForUdp()Sub StartForUdp() Dim acc AsNew SocketAsyncEventArgs AddHandler acc.Completed, AddressOf UDP_Receive_Completed acc.RemoteEndPoint = Server.LocalEndPoint acc.SetBuffer(MyReceiveBuff, 0, MyReceiveBuff.Length) Server.ReceiveFromAsync(acc) End Sub #End Region 客户端连接#Region "客户端连接" PrivateSub Accept_Completed()Sub Accept_Completed(ByVal Sender AsObject, ByVal e As SocketAsyncEventArgs) '事件进入 Dim MS AsNew MySocket Dim Client As Socket Client = e.AcceptSocket MS.WorkID = SocketID MS.WorkSocket = Client RaiseEvent OnAccept(MS, e) IfIsNothing(Client) OrElseNot Client.Connected Then IfNotIsNothing(ServerHas) Then ServerHas.Remove(MS) EndIf Exit Sub Else ServerHas.Add(MS) EndIf '接收数据 RemoveHandler e.Completed, AddressOf Accept_Completed AddHandler e.Completed, AddressOf TCP_Receive_Completed e.SetBuffer(MyReceiveBuff, 0, MyReceiveBuff.Length) Client.ReceiveAsync(e) SocketID +=1 Start() End Sub #End Region 客户端传入数据(TCP)#Region "客户端传入数据(TCP)" PrivateSub TCP_Receive_Completed()Sub TCP_Receive_Completed(ByVal Sender AsObject, ByVal e As SocketAsyncEventArgs) Dim MS As MySocket Dim Client As Socket Client = Sender MS = GetMySocketBySocket(Client) If e.BytesTransferred =0Then OnErrorResumeNext ServerHas.Remove(MS) '引发客户端断开事件 RaiseEvent OnDisconnected(MS, e) '执行断开操作 Client.Close() Client =Nothing Exit Sub EndIf '事件进入 RaiseEvent OnReceive(MS, e) IfIsNothing(Client) OrElse Client.Connected =FalseThen IfNotIsNothing(ServerHas) Then ServerHas.Remove(MS) EndIf Exit Sub EndIf '清理缓冲数据 Array.Clear(e.Buffer, 0, e.Buffer.Length) '接收数据 Client.ReceiveAsync(e) End Sub #End Region 客户端传入数据(UDP)#Region "客户端传入数据(UDP)" PublicSub UDP_Receive_Completed()Sub UDP_Receive_Completed(ByVal Sender AsObject, ByVal e As SocketAsyncEventArgs) Dim MS AsNew MySocket Dim Client As Socket Client = Sender MS.WorkSocket = Client '事件进入 RaiseEvent OnReceive(MS, e) IfIsNothing(Client) OrElse Client.Connected =FalseThen IfNotIsNothing(ServerHas) Then ServerHas.Remove(MS) EndIf Exit Sub EndIf '清理缓冲数据 Array.Clear(e.Buffer, 0, e.Buffer.Length) '接收数据 Client.ReceiveFromAsync(e) End Sub #End Region 发送数据#Region "发送数据" ''' <summary> ''' 发送Socket数据 ''' </summary> ''' <param name="SocketID">Socket ID值</param> ''' <param name="DataBuff">Byte数组</param> ''' <returns>True:发送成功 False:发送失败</returns> ''' <remarks></remarks> PublicOverloadsFunction Send()Function Send(ByVal SocketID As Int32, ByVal DataBuff() AsByte) AsBoolean Dim MS As MySocket Dim SD AsNew SocketAsyncEventArgs MS = GetMySocketByID(SocketID) IfIsNothing(MS) OrElseIsNothing(MS.WorkSocket) OrElse MS.WorkSocket.Connected =FalseThen ReturnFalse EndIf SD.SetBuffer(DataBuff, 0, DataBuff.Length) SD.UserToken = MS.WorkSocket AddHandler SD.Completed, AddressOf Send_Completed MS.WorkSocket.SendAsync(SD) '进入接收数据异步 Call ReceiveAfterSent(MS.WorkSocket) ReturnTrue End Function ''' <summary> ''' 发送Socket数据 ''' </summary> ''' <param name="SocketName">Socket 名称</param> ''' <param name="DataBuff">Byte数组</param> ''' <returns>True:发送成功 False:发送失败</returns> ''' <remarks></remarks> PublicOverloadsFunction Send()Function Send(ByVal SocketName AsString, ByVal DataBuff() AsByte) AsBoolean Dim MS As MySocket Dim SD AsNew SocketAsyncEventArgs MS = GetMySocketByName(SocketName) IfIsNothing(MS) OrElseIsNothing(MS.WorkSocket) OrElse MS.WorkSocket.Connected =FalseThen ReturnFalse EndIf SD.SetBuffer(DataBuff, 0, DataBuff.Length) SD.UserToken = MS.WorkSocket AddHandler SD.Completed, AddressOf Send_Completed MS.WorkSocket.SendAsync(SD) '进入接收数据异步 Call ReceiveAfterSent(MS.WorkSocket) ReturnTrue End Function ''' <summary> ''' 发送Socket数据 ''' </summary> ''' <param name="Socket">Socket名称</param> ''' <param name="DataBuff">Byte数组</param> ''' <returns>True:发送成功 False:发送失败</returns> ''' <remarks></remarks> PublicOverloadsFunction Send()Function Send(ByVal Socket As Socket, ByVal DataBuff() AsByte) AsBoolean Dim SD AsNew SocketAsyncEventArgs IfIsNothing(Socket) OrElse Socket.Connected =FalseThen ReturnFalse EndIf SD.SetBuffer(DataBuff, 0, DataBuff.Length) SD.UserToken = Socket AddHandler SD.Completed, AddressOf Send_Completed Socket.SendAsync(SD) '进入接收数据异步 Call ReceiveAfterSent(Socket) ReturnTrue End Function PrivateSub Send_Completed()Sub Send_Completed(ByVal Sender As Socket, ByVal e As SocketAsyncEventArgs) '异步发送完成操作 Dim MS As MySocket MS = GetMySocketBySocket(Sender) RaiseEvent OnSent(MS, e) IfIsNothing(Sender) OrElse Sender.Connected =FalseThen IfNotIsNothing(ServerHas) Then ServerHas.Remove(MS) EndIf EndIf End Sub PrivateSub ReceiveAfterSent()Sub ReceiveAfterSent(ByVal Socket As Socket) '发送数据后开始接收 Dim SA AsNew SocketAsyncEventArgs SA.SetBuffer(MyReceiveBuff, 0, MyReceiveBuff.Length) SelectCase Server.ProtocolType Case ProtocolType.Tcp 'TCP接收 AddHandler SA.Completed, AddressOf TCP_Receive_Completed Socket.ReceiveAsync(SA) Case ProtocolType.Udp 'UDP接收 AddHandler SA.Completed, AddressOf UDP_Receive_Completed SA.RemoteEndPoint = Socket.LocalEndPoint Socket.ReceiveFromAsync(SA) EndSelect End Sub #End Region 得到ServerHas数据信息#Region "得到ServerHas数据信息" ''' <summary> ''' 得到当前Socket列表 ''' </summary> ''' <returns>String(,1)一维数组。0:Socket的ID 1:Socket的名称</returns> ''' <remarks></remarks> PublicFunction GetServerList()Function GetServerList() AsString(,) IfIsNothing(ServerHas) Then ThrowNew Exception("未初始化本类") Exit Function EndIf Dim Result(,) AsString Dim Count As Int32 Dim i As Int32 i =0 Count = ServerHas.Count ReDim Result(Count -1, 1) Dim Data = From s In ServerHas _ Select s.WorkID, s.WorkName ForEach item In Data Result(i, 0) = item.WorkID.ToString Result(i, 1) = item.WorkName i +=1 Next Return Result End Function #End Region 清除Socket对象#Region "清除Socket对象" ''' <summary> ''' 清除Socket对象 ''' </summary> ''' <param name="SocketID">Socket的ID值</param> ''' <remarks></remarks> PublicSub Close()Sub Close(ByVal SocketID As Int32) OnErrorResumeNext Dim CS As MySocket CS = GetMySocketByID(SocketID) CS.WorkSocket.Close() CS.WorkSocket =Nothing CS =Nothing ServerHas.Remove(CS) End Sub ''' <summary> ''' 清除Socket对象 ''' </summary> ''' <param name="SocketName">Socket的名称</param> ''' <remarks></remarks> PublicSub Close()Sub Close(ByVal SocketName AsString) OnErrorResumeNext Dim CS As MySocket CS = GetMySocketByName(SocketName) CS.WorkSocket.Close() CS.WorkSocket =Nothing CS =Nothing ServerHas.Remove(CS) End Sub ''' <summary> ''' 清除Socket对象 ''' </summary> ''' <param name="Socket">Socket对象</param> ''' <remarks></remarks> PublicSub Close()Sub Close(ByVal Socket As Socket) OnErrorResumeNext Dim CS As MySocket CS = GetMySocketBySocket(Socket) Socket.Close() Socket =Nothing CS =Nothing ServerHas.Remove(CS) End Sub ''' <summary> ''' 清除Socket对象 ''' </summary> ''' <param name="MySocket">MySocket对象</param> ''' <remarks></remarks> PublicSub Close()Sub Close(ByVal MySocket As MySocket) OnErrorResumeNext MySocket.WorkSocket.Close() MySocket.WorkSocket =Nothing ServerHas.Remove(MySocket) End Sub #End Region '********************************************************************** ' LinQ 查询 MySocket结构体 '********************************************************************** 得到MySocket对象#Region "得到MySocket对象" ''' <summary> ''' 以Socket的ID值得到MySocket对象 ''' </summary> ''' <param name="ID">SocketID值</param> ''' <returns></returns> ''' <remarks></remarks> PublicFunction GetMySocketByID()Function GetMySocketByID(ByVal ID As Int32) As MySocket IfIsNothing(ServerHas) Then ReturnNothing EndIf Dim Result = From s In ServerHas _ Where s.WorkID = ID If Result.Count =0Then ReturnNothing EndIf Return Result.First End Function ''' <summary> ''' 以Socket的名称值得到MySocket对象 ''' </summary> ''' <param name="Name"></param> ''' <returns></returns> ''' <remarks></remarks> PublicFunction GetMySocketByName()Function GetMySocketByName(ByVal Name AsString) As MySocket IfIsNothing(ServerHas) Then ReturnNothing EndIf Dim Result = From s In ServerHas _ Where s.WorkName = Name If Result.Count =0Then ReturnNothing EndIf Return Result.First End Function ''' <summary> ''' 以Socket对象得到MySocket对象 ''' </summary> ''' <param name="Socket">Socket对象</param> ''' <returns></returns> ''' <remarks></remarks> PublicFunction GetMySocketBySocket()Function GetMySocketBySocket(ByVal Socket As Socket) As MySocket Dim SocketHandle As Int32 SocketHandle = Socket.Handle IfIsNothing(Socket) OrElseIsNothing(ServerHas) Then ReturnNothing EndIf Dim Result = From s In ServerHas _ Where s.WorkSocket.Handle = SocketHandle If Result.Count =0Then ReturnNothing EndIf Return Result.First End Function #End Region 释放对象#Region "释放对象" PublicSub Dispose()Sub Dispose() OnErrorResumeNext Server.Close() Server =Nothing ForEach item In ServerHas item.WorkSocket.LingerState.Enabled =False item.WorkSocket.Shutdown(SocketShutdown.Both) item.WorkSocket.Close() item.WorkSocket =Nothing Next ServerHas.Clear() ServerHas =Nothing End Sub #End Region End Class
调用示例:
TCP:
Dim Server As Socket35 Server =New Socket35(Socket35.SocketType.TCP, 1024, 1024) Server.Bind(New IPEndPoint(IPAddress.Any, 5614)) Server.Listen(100) 'Socket事件 AddHandler server.OnAccept, AddressOf accept AddHandler server.OnReceive, AddressOf received AddHandler server.OnSent, AddressOf sent AddHandler server.OnDisconnected, AddressOf disconnect '开始监听 Server.Start() 'Socket连接进入 PrivateSub accept()Sub accept(ByRef Sender As Socket35.MySocket, ByVal e As SocketAsyncEventArgs) Sender.WorkName = Now.ToString Debug.Write(Sender.WorkID) End Sub 'Socket接收入数 PrivateSub received()Sub received(ByRef Sender As Socket35.MySocket, ByVal e As SocketAsyncEventArgs) Dim Content AsString Dim SendBuff() AsByte Content = System.Text.Encoding.GetEncoding("gb2312").GetString(e.Buffer) server.Send(Sender.WorkSocket, SendBuff) End Sub '查看当前Socket活动连接信息(二维数组) Dim SocketList(,) AsString SocketList = Socket35.GetServerList()
UDP:
Dim Server As Socket35 Server =New Socket35(Socket35.SocketType.UDP, 1024, 1024) Server.Bind(New IPEndPoint(IPAddress.Any, 5614)) AddHandler server.OnAccept, AddressOf accept AddHandler server.OnReceive, AddressOf received AddHandler server.OnSent, AddressOf sent AddHandler server.OnDisconnected, AddressOf disconnect Server.Start() '接收UDP传来的数据 PrivateSub received()Sub received(ByRef Sender As Socket35.MySocket, ByVal e As SocketAsyncEventArgs) Dim Content AsString Dim SendBuff() AsByte Content = System.Text.Encoding.GetEncoding("gb2312").GetString(e.Buffer) Server.Send(Sender.WorkSocket, SendBuff) End Sub