Junior Spellweaver
- Joined
- Feb 11, 2011
- Messages
- 103
- Reaction score
- 3
Hey guys,
writing the update for BinHabbo I've decided to remake the old socket class I was using,it worked pretty well but it wasn't that good :S
So here's the new class,basically it allows you to manage your sockets in a easier way using thread safe events.
It is fully commented and it's not so big,hope this helps:
writing the update for BinHabbo I've decided to remake the old socket class I was using,it worked pretty well but it wasn't that good :S
So here's the new class,basically it allows you to manage your sockets in a easier way using thread safe events.
It is fully commented and it's not so big,hope this helps:
PHP:
Class VMSocket
#Region "Declarations and Condition property"
'sockets tcp/ip, data stream
Private tcpClient As Net.Sockets.TcpClient, tcpListener As Net.Sockets.TcpListener, NetStream As Net.Sockets.NetworkStream
' socket status, thread for data and disconnection checking
Private _Condition As Status = Status.Disconnected, TData As Threading.Thread
'events
Public Event Connected As EventHandler
Public Event ConnectionRequest As System.ComponentModel.CancelEventHandler
Public Event DataArrival(ByVal Data() As Byte)
Public Event ConnectionLost As EventHandler
'socket's statuses
Public Enum Status
Connected
Disconnected
Listening
Connecting
End Enum
'return the current socket's status
Public ReadOnly Property Condition As Status
Get
Return _Condition
End Get
End Property
#End Region
#Region "Connect"
Public Sub BeginConnect(ByVal Host As String, ByVal Port As Int32)
'if the socket is not disconnected throw the right exception
If _Condition = Status.Disconnected Then
tcpClient = New Net.Sockets.TcpClient
'set the status start the operation on another thread
_Condition = Status.Connecting
tcpClient.BeginConnect(Host, Port, AddressOf SubConnected, Nothing)
Else : Throw New Net.Sockets.SocketException(10037)
End If
End Sub
Private Sub SubConnected(ByVal ar As IAsyncResult)
'close the connection request
tcpClient.EndConnect(ar)
If tcpClient.Connected Then
'get the stream, set the status and raise the event in a thread safe way
NetStream = tcpClient.GetStream
_Condition = Status.Connected
SafeEvent(ConnectedEvent, {Me, New EventArgs})
'start getting data
TData = New Threading.Thread(AddressOf GetData) : TData.Start()
Else : _Condition = Status.Disconnected
End If
End Sub
#End Region
#Region "Listen"
Public Sub BeginListen(ByVal Port As Int32)
'if the socket is not disconnected throw the right exception
If _Condition = Status.Disconnected Then
'get the local ip and set the listener to the specified port
tcpListener = New Net.Sockets.TcpListener(Net.IPAddress.Any, Port)
'start listening and set the socket status
tcpListener.Start()
_Condition = Status.Listening
'start the aynchronous operation
tcpListener.BeginAcceptTcpClient(AddressOf ListenComplete, Nothing)
Else : Throw New Net.Sockets.SocketException(10037)
End If
End Sub
'asynchronous operation finished
Private Sub ListenComplete(ByVal ar As IAsyncResult)
Dim Cancel As New System.ComponentModel.CancelEventArgs
SafeEvent(ConnectionRequestEvent, {Me, Cancel})
'if the user has not rejected the connection then accept it
If Not Cancel.Cancel AndAlso tcpListener IsNot Nothing Then
tcpClient = tcpListener.EndAcceptTcpClient(ar)
'stop listening,set the status and raise safely the connected event
tcpListener.Stop()
NetStream = tcpClient.GetStream
_Condition = Status.Connected
'start getting data
TData = New Threading.Thread(AddressOf GetData) : TData.Start()
SafeEvent(ConnectedEvent, {Me, New EventArgs})
End If
End Sub
#End Region
#Region "Data"
Private Sub GetData()
'check if the socket is still connected
Do Until tcpClient.Client.Poll(0, Net.Sockets.SelectMode.SelectRead) AndAlso tcpClient.Available = 0
'check for new data,if it's available then get it and raise ina thread safe way the DataArrival event
If tcpClient.Available > 0 Then
Dim Buffer(tcpClient.Available - 1) As Byte
NetStream.Read(Buffer, 0, Buffer.Length)
SafeEvent(DataArrivalEvent, {Buffer})
End If
Loop
'destroy listener,client and networkstream
If tcpListener IsNot Nothing Then tcpListener.Server.Dispose() : tcpListener = Nothing
If tcpClient IsNot Nothing Then tcpClient.Close() : tcpClient = Nothing
If NetStream IsNot Nothing Then NetStream.Dispose() : NetStream = Nothing
'the socket is now disconnected
_Condition = Status.Disconnected
SafeEvent(ConnectionLostEvent, {Me, New EventArgs})
End Sub
'write the byte data (send a packet)
Public Sub SendData(ByVal Data() As Byte)
'if the socket is connected then send the data else just throw the right socket exception
If _Condition = Status.Connected Then
tcpClient.Client.Send(Data, 0, Data.Length, Net.Sockets.SocketFlags.None)
Else : Throw New Net.Sockets.SocketException(10057)
End If
End Sub
'overloads with string data
Public Sub SendData(ByVal Data As String)
If _Condition = Status.Connected Then
'get bytes from the data string and send them
Dim ByteData() As Byte = System.Text.UTF8Encoding.UTF8.GetBytes(Data)
tcpClient.Client.Send(ByteData, 0, ByteData.Length, Net.Sockets.SocketFlags.None)
Else : Throw New Net.Sockets.SocketException(10057)
End If
End Sub
#End Region
#Region "Close and SafeEvent"
Public Sub Close()
On Error Resume Next
'stop getting data
If TData IsNot Nothing Then TData.Abort()
'destroy listener and client
If tcpListener IsNot Nothing Then tcpListener.Server.Dispose() : tcpListener = Nothing
If tcpClient IsNot Nothing Then tcpClient.Close() : tcpClient = Nothing
If NetStream IsNot Nothing Then NetStream.Dispose() : NetStream = Nothing
_Condition = Status.Disconnected
End Sub
'thread safe raiseevent
Private Sub SafeEvent(ByVal MyEvent As [Delegate], ByVal Parameters() As Object)
If MyEvent IsNot Nothing Then
Dim CurObj As Object
'get all the delegates
For Each MyDel As [Delegate] In MyEvent.GetInvocationList
CurObj = MyDel.Target
CurObj.BeginInvoke(MyDel, Parameters)
Next
End If
End Sub
#End Region
End Class