Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Imports System.Net.Sockets
- Imports System.Net
- Namespace MultiClientTCPServerSocket
- 'Author: LaPanthere
- 'Date: 4th of June, 2013
- 'Desc: A simple class with event calling that will run multiple clients. Store the clients in a list of sockets if you wish to do stuff with them.
- 'Credits: None, based off my own work with async sockets.
- Public Class MultiClientTCPSeverSocket
- Public Event MessageReceived As MessageReceivedEventHandler
- Public Event ClientConnected As ClientConnectedEventHandler
- Public Event ClientDisconnected As ClientDisconnectedEventHandler
- Dim clientSocket As Socket
- Dim serverSocket As Socket
- Dim port As String
- Dim byteSize(66291456) As Byte
- Dim IpEndPoint As Net.IPEndPoint
- Public Delegate Sub MessageReceivedEventHandler(ByVal sender As Object, ByVal e As MessageReceivedEventArgs)
- Public Delegate Sub ClientConnectedEventHandler(ByVal sender As Object, ByVal e As ClientConnectedEventArgs)
- Public Delegate Sub ClientDisconnectedEventHandler(ByVal sender As Object, ByVal e As ClientDisconnectedEventArgs)
- ''' <summary>
- ''' Creates a new Multiple client server socket
- ''' </summary>
- ''' <param name="port">The port to listen for clients</param>
- ''' <param name="buffer">The buffer for messages</param>
- ''' <remarks></remarks>
- Public Sub New(ByVal port As String, Optional ByVal buffer() As Byte = Nothing)
- 'General defining of existing strings/related
- Me.port = port
- If Not IsNothing(buffer) Then
- Me.byteSize = buffer
- End If
- End Sub
- ''' <summary>
- ''' Starts the server with the specified data (define a new instance to use this method)
- ''' </summary>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Function StartServer() As Boolean
- Try
- 'Define what the server socket really is
- serverSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
- 'Create a local IP endpoint
- IpEndPoint = New Net.IPEndPoint(IPAddress.Any, Me.port)
- 'Create the local endpoint ip bind
- serverSocket.Bind(IpEndPoint)
- 'Allow several thousand clients to be backlogged
- serverSocket.Listen(500000)
- 'Start accepting clients through the socket
- serverSocket.BeginAccept(New AsyncCallback(AddressOf OnClientAccept), Nothing)
- Return True
- Catch
- Return False
- End Try
- End Function
- ''' <summary>
- ''' Attempts to close the server socket and end all connecting clients
- ''' </summary>
- ''' <param name="timeout">The time before closing the socket</param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Function CloseServer(Optional ByVal timeout As Integer = 1) As Boolean
- Try
- serverSocket.Close(timeout)
- Return True
- Catch
- Return False
- End Try
- End Function
- Public Function DisconnectClient(ByVal client As Socket) As Boolean
- Try
- 'Begin disconnecting a client and assign its async call back to OnClientDisconnect
- client.BeginDisconnect(False, New AsyncCallback(AddressOf OnClientDisconnect), client)
- Return True
- Catch
- Return False
- End Try
- End Function
- ''' <summary>
- ''' Sends a message asynchronously to the client socket specified
- ''' </summary>
- ''' <param name="message">The message you wish to send</param>
- ''' <param name="client">The socket that you wish to send the message to, can be grabbed from most events</param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Function SendMessage(ByVal message As String, ByVal client As Socket) As Boolean
- Try
- 'Define bytes to send by getting the bytes from the message string
- Dim sendBytes As Byte() = System.Text.ASCIIEncoding.ASCII.GetBytes(message)
- 'Begin sending data and assign the async callback to OnMesssageSent
- client.BeginSend(sendBytes, 0, sendBytes.Length, SocketFlags.None, New AsyncCallback(AddressOf OnMessageSent), client)
- Return True
- Catch
- Return False
- End Try
- End Function
- Private Sub OnClientAccept(ByVal asyncres As IAsyncResult)
- Try
- 'End accepting client and restart client acceptance
- clientSocket = serverSocket.EndAccept(asyncres)
- serverSocket.BeginAccept(New AsyncCallback(AddressOf OnClientAccept), Nothing)
- 'Raise a new event letting the user know that a client has connected
- Dim e As New ClientConnectedEventArgs
- e.clientID = clientSocket.Handle.ToString
- e.clientSocket = clientSocket
- RaiseEvent ClientConnected(Me, e)
- 'Start receiving messages from the client
- clientSocket.BeginReceive(byteSize, 0, byteSize.Length, SocketFlags.None, New AsyncCallback(AddressOf OnMessageReceive), clientSocket)
- 'Begin constant check to see whether the client is still connected
- Catch ex As Exception
- 'If error occurs, throw a new exception
- Throw New Exception("Failed to accept a client. See 'OnClientAccept' Sub. Details: " & ex.Message)
- End Try
- End Sub
- Private Sub OnMessageReceive(ByVal asyncres As IAsyncResult)
- Try
- 'Create a socket to use with events
- Dim client As Socket = asyncres.AsyncState
- 'If the client is not connected break and dispose the client
- If client.Connected = False And client.Poll(2000, SelectMode.SelectRead) Then
- Exit Sub
- End If
- 'Create a byte from the byteSize and set it to the message from the client
- Dim bytesRec As Byte() = byteSize
- Dim message As String = System.Text.ASCIIEncoding.ASCII.GetString(bytesRec).Trim()
- 'Raise the MessageReceived Event with parameters specified above
- Dim e As New MessageReceivedEventArgs
- e.Sender = client.Handle.ToString
- e.Message = message
- e.clientSocket = client
- RaiseEvent MessageReceived(Me, e)
- 'Start recieving data from the socket again
- clientSocket.BeginReceive(byteSize, 0, byteSize.Length, SocketFlags.None, New AsyncCallback(AddressOf OnMessageReceive), clientSocket)
- Catch
- 'If error occurs, throw a new exception
- Throw New Exception("Failed to receive message from client or related")
- End Try
- End Sub
- Private Sub OnMessageSent(ByVal asyncres As IAsyncResult)
- Try
- Dim client As Socket = asyncres.AsyncState
- 'Gracefully let the message sending be ended
- client.EndSend(asyncres)
- Catch
- 'If error occurs, throw a new exception
- Throw New Exception("Failed to disconnect client")
- End Try
- End Sub
- Private Sub OnClientDisconnect(ByVal asyncres As IAsyncResult)
- Try
- 'Define a socket and use it for the events, setting it to the asyncstate of the result
- Dim client As Socket = asyncres.AsyncState
- 'Raise a new clientdisconnected event
- Dim e As New ClientDisconnectedEventArgs
- e.clientID = client.Handle.ToString
- e.clientSocket = client
- RaiseEvent ClientDisconnected(Me, e)
- 'End the disconnect sequence
- client.EndDisconnect(asyncres)
- Catch
- 'If error occurs, throw a new exception
- Throw New Exception("Failed to disconnect client")
- End Try
- End Sub
- ''' <summary>
- ''' Checks whether a socket is alive by polling it
- ''' </summary>
- ''' <param name="socket">The socket you wish to check</param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Function IsConnected(ByVal socket As Socket) As Boolean
- Try
- 'Check whether socket is alive by polling it.
- Return Not (socket.Poll(1, SelectMode.SelectRead) AndAlso socket.Available = 0)
- Catch ex As SocketException
- Return False
- End Try
- End Function
- End Class
- Public Class MessageReceivedEventArgs
- Inherits EventArgs
- Public Sender As String
- Public clientSocket As Socket
- Public Message As String
- End Class
- Public Class ClientConnectedEventArgs
- Inherits EventArgs
- Public clientID As String
- Public clientSocket As Socket
- End Class
- Public Class ClientDisconnectedEventArgs
- Inherits EventArgs
- Public clientID As String
- Public clientSocket As Socket
- End Class
- End Namespace
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement