Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading
Public Class SocketState
#Region " Declares "
Public Socket As Socket = Nothing
Public Const PacketSize As Int32 = 1024
Public rBuff(PacketSize - 1) As Byte
Public sBuff() As Byte = Nothing
Public SB As New StringBuilder
#End Region
End Class
Public Class ClientSocket
#Region " Declares "
Private Const ServPort As Int32 = 5050
Private Const ServAddy As String = "localhost"
Private Const EOP As String = "<EOP>" 'End of Packet
Private doContinue As New ManualResetEvent(False)
Private MyState As SocketState = Nothing
#End Region
#Region " Events "
Public Event onReceive(ByVal inMsg As String)
Public Event onError(ByVal inMsg As String)
Public Event onFailedConnect(ByVal inMsg As String)
Public Event onDisconnect(ByVal inMsg As String)
Public Event onConnect()
#End Region
#Region " Methods "
Public Sub New()
'Default Constructor
End Sub
Public Sub Start()
'Start the connection on its own thread
Dim t As New Thread(AddressOf StartConnect) : t.Start()
End Sub
Private Sub StartConnect()
'Find the server endpoint
Dim ipHostEntry As IPHostEntry = Dns.GetHostByName(ServAddy)
Dim ipAddress As IPAddress = ipHostEntry.AddressList(0)
Dim ipEndPoint As New IPEndPoint(ipAddress, ServPort)
'Set up the socket
Dim Connector As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
Try
'Kill the state object just in case
MyState = Nothing
'Reset the thread pause
doContinue.Reset()
'Begin trying to connect
Connector.BeginConnect(ipEndPoint, AddressOf FinishConnect, Connector)
'Pause this thread
doContinue.WaitOne()
Catch ex As Exception
RaiseEvent onFailedConnect("A connection to the remote host could not be established.")
End Try
End Sub
Private Sub FinishConnect(ByVal ar As IAsyncResult)
Dim Handler As Socket = CType(ar.AsyncState, Socket)
Try
If Handler.Connected Then
'End the connection attempts
Handler.EndConnect(ar)
'Set up the new state
MyState = New SocketState
MyState.Socket = Handler
'Begin receiving
Handler.BeginReceive(MyState.rBuff, 0, MyState.PacketSize, SocketFlags.None, AddressOf ReceiveLock, MyState)
'Let the client know we connected
RaiseEvent onConnect()
Else
CloseSocket()
RaiseEvent onFailedConnect("A connection to the remote host could not be established.")
End If
Catch
CloseSocket()
RaiseEvent onFailedConnect("A connection to the remote host could not be established.")
Finally
'Restart the main thread
doContinue.Set()
End Try
End Sub
Private Sub ReceiveLock(ByVal ar As IAsyncResult)
Dim State As SocketState = CType(ar.AsyncState, SocketState)
Dim Handler As Socket = State.Socket
Dim ByteCount As Int32
Try 'Reteive the data
ByteCount = Handler.EndReceive(ar)
If ByteCount > 0 Then
State.SB.Append(Encoding.ASCII.GetString(State.rBuff, 0, ByteCount))
Dim Msg As String = State.SB.ToString()
If Msg.IndexOf(EOP) > -1 Then
RaiseEvent onReceive(Msg.Substring(0, Msg.IndexOf(EOP)))
State.SB.Remove(0, Msg.IndexOf(EOP) + EOP.Length)
End If
'Receive more data
Handler.BeginReceive(State.rBuff, 0, State.PacketSize, SocketFlags.None, AddressOf ReceiveLock, State)
Else
RaiseEvent onDisconnect("Connection closed by server.")
CloseSocket()
End If
Catch ex As Exception
RaiseEvent onError(ex.Message)
CloseSocket()
End Try
End Sub
Public Sub SendData(ByVal inMsg As String)
If MyState.Socket.Connected Then
'Package up the message
MyState.sBuff = Encoding.ASCII.GetBytes(inMsg.Trim)
Try 'Send the message
MyState.Socket.BeginSend(MyState.sBuff, 0, MyState.sBuff.Length, SocketFlags.None, AddressOf SendLock, MyState)
Catch ex As Exception
RaiseEvent onError(ex.Message)
End Try
End If
End Sub
Private Sub SendLock(ByVal ar As IAsyncResult)
'Stop the send request
Dim State As SocketState = CType(ar.AsyncState, SocketState)
Dim Handler As Socket = State.Socket
Dim BytesSent As Int32 = Handler.EndSend(ar)
End Sub
Public Sub CloseSocket()
'Shut down the clients socket
If (Not MyState Is Nothing) AndAlso (Not MyState.Socket Is Nothing) Then
'Ignore errors
On Error Resume Next
'Shut it down
MyState.Socket.Shutdown(SocketShutdown.Both)
MyState.Socket.Close()
MyState.Socket = Nothing
End If
'Destroy the state
MyState = Nothing
End Sub
#End Region
End Class