TizzyT

TZ_Server_Incomplete -TizzyT

Oct 7th, 2015
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VB.NET 14.92 KB | None | 0 0
  1. Imports System.Net
  2. Imports System.Net.Sockets
  3. Imports System.Text
  4. Imports System.Threading
  5. Imports System.Collections.Concurrent
  6. Imports System.IO
  7.  
  8. Public Class Server
  9.     Public Event ServerStarted(ByVal Port As UShort)
  10.     Public Event NewClientConnected(ByVal SessionID As String, ByVal Time As Date)
  11.     Public Event ClientDisconnected(ByVal SessionID As String, ByVal Time As Date)
  12.     Public Event DataRecieved(ByVal Data() As Byte, ByVal SessionID As String, ByVal Time As Date)
  13.     Public Event ServerStoping(ByVal StopTime As Date, ByVal Time As TimeSpan)
  14.     Public Event ServerDebug(ByVal Ex As ServerException)
  15.     Private Shared ValidIdChars As String = "0123456789ABCDEF"
  16.     Private Shared Rnd As New Random
  17.     Private Clients As New ConcurrentDictionary(Of String, ConnectedClient)
  18.     Private _UpTime As New Stopwatch
  19.     Private _PreviousUpTime As TimeSpan
  20.     Private ListeningThread As Threading.Thread
  21.     Private NewTCP As TcpListener = Nothing
  22.     Private _Port As UShort
  23.  
  24.     Public ReadOnly Property UpTime() As TimeSpan
  25.         Get
  26.             If _UpTime.IsRunning Then Return _UpTime.Elapsed Else Return New TimeSpan(0)
  27.         End Get
  28.     End Property
  29.  
  30.     Public ReadOnly Property Count() As UInteger
  31.         Get
  32.             SyncLock Clients
  33.                 Return Clients.Count
  34.             End SyncLock
  35.         End Get
  36.     End Property
  37.  
  38.     Public Sub Start(ByVal Port As UShort)
  39.         If NewTCP Is Nothing Then
  40.             _Port = Port
  41.             ListeningThread = New Threading.Thread(AddressOf Listen)
  42.             ListeningThread.Start()
  43.         Else
  44.             RaiseEvent ServerDebug(New ServerException(ServerExceptions.AlreadyRunning))
  45.         End If
  46.     End Sub
  47.  
  48.     Public Sub EndSession(ByVal SessionID As String)
  49.         If Clients.ContainsKey(SessionID) Then
  50.             If Clients(SessionID).Close() = False Then
  51.                 Dim EndThread As New Threading.Thread(Sub()
  52.                                                           If Clients(SessionID).Close() = False Then
  53.  
  54.                                                           End If
  55.                                                       End Sub)
  56.                 EndThread.Start()
  57.             End If
  58.         Else
  59.             RaiseEvent ServerDebug(New ServerException(ServerExceptions.DisconnectFailed, {SessionID}))
  60.         End If
  61.     End Sub
  62.  
  63.     Public Sub Purge()
  64.         For Each K As String In Clients.Keys
  65.             EndSession(K)
  66.         Next
  67.     End Sub
  68.  
  69.     Public Sub [Stop]()
  70.         If NewTCP IsNot Nothing Then
  71.             _UpTime.Stop()
  72.             NewTCP.Stop()
  73.             ListeningThread.Abort()
  74.             For Each K As String In Clients.Keys
  75.                 EndSession(K)
  76.             Next
  77.             _PreviousUpTime = _UpTime.Elapsed
  78.             RaiseEvent ServerStoping(DateTime.Now, _PreviousUpTime)
  79.             NewTCP = Nothing
  80.         Else
  81.             RaiseEvent ServerDebug(New ServerException(ServerExceptions.NotRunning, {}))
  82.         End If
  83.     End Sub
  84.  
  85.     Private Sub EstablishedNewClient(ByVal Client As ConnectedClient, ByVal Time As Date)
  86.         Dim NewID As String
  87.         Do
  88.             NewID = String.Empty
  89.             For i = 1 To 24
  90.                 NewID &= ValidIdChars(Rnd.Next(0, 16))
  91.             Next
  92.         Loop Until Clients.TryAdd(NewID, Client)
  93.         Client.AssignID(NewID)
  94.         RaiseEvent NewClientConnected(NewID, Time)
  95.         Client.BeginReceive()
  96.     End Sub
  97.  
  98.     Private Sub DisconnectedClient(ByVal SessionID As String, ByVal Time As Date)
  99.         Try
  100.             Dim CC As ConnectedClient = Clients(SessionID)
  101.             If Clients.TryRemove(SessionID, CC) Then
  102.                 RaiseEvent ClientDisconnected(SessionID, Time)
  103.             Else
  104.                 RaiseEvent ServerDebug(New ServerException(ServerExceptions.DisconnectFailed, {SessionID}))
  105.             End If
  106.         Catch ex As Exception
  107.             RaiseEvent ServerDebug(New ServerException(ex))
  108.         End Try
  109.     End Sub
  110.  
  111.     Private Sub RecievedData(ByVal SessionID As String, ByVal Data() As Byte, ByVal Time As Date)
  112.         RaiseEvent DataRecieved(Data, SessionID, Time)
  113.     End Sub
  114.  
  115.     Public Sub Send(ByVal SessionID As String, ByVal Data() As Byte)
  116.         Try
  117.             Clients(SessionID).Send(Data)
  118.         Catch ex As Exception
  119.             RaiseEvent ServerDebug(New ServerException(ServerExceptions.FailedToSend, {SessionID}))
  120.         End Try
  121.     End Sub
  122.  
  123.     Public Sub Broadcast(ByVal Data() As Byte)
  124.         Dim Failed As New List(Of String)
  125.         For Each K As ConnectedClient In Clients.Values
  126.             Try
  127.                 K.Send(Data)
  128.             Catch ex As Exception
  129.                 Failed.Add(K.SessionID)
  130.             End Try
  131.         Next
  132.         If Failed.Count > 0 Then _
  133.             RaiseEvent ServerDebug(New ServerException(ServerExceptions.IncompleteBroadcast, Failed.ToArray))
  134.     End Sub
  135.  
  136.     Public Sub Broadcast(ByVal SessionIDs() As String, ByVal Data() As Byte, _
  137.                          Optional ByVal BroadcastType As BroadcastType = BroadcastType.BlackList)
  138.         Dim Failed As New List(Of String)
  139.         For Each K As ConnectedClient In Clients.Values
  140.             Try
  141.                 If BroadcastType = Server.BroadcastType.WhiteList _
  142.                     Then If SessionIDs.Contains(K.SessionID) Then K.Send(Data) _
  143.                     Else If SessionIDs.Contains(K.SessionID) Then Continue For Else K.Send(Data)
  144.             Catch ex As Exception
  145.                 Failed.Add(K.SessionID)
  146.             End Try
  147.         Next
  148.         If Failed.Count > 0 Then
  149.             If BroadcastType = Server.BroadcastType.WhiteList _
  150.                 Then RaiseEvent ServerDebug( _
  151.                     New ServerException(ServerExceptions.IncompleteWhiteListBroadcast, Failed.ToArray)) _
  152.                 Else RaiseEvent ServerDebug( _
  153.                     New ServerException(ServerExceptions.IncompleteBlackListBroadcast, Failed.ToArray))
  154.         End If
  155.     End Sub
  156.  
  157.     Private Sub Listen()
  158.         NewTCP = New TcpListener(IPAddress.Any, _Port)
  159.         NewTCP.Start()
  160.         RaiseEvent ServerStarted(_Port)
  161.         _UpTime.Restart()
  162.         While True
  163.             Try
  164.                 Dim NewClient As New ConnectedClient(NewTCP.AcceptTcpClient)
  165.                 AddHandler NewClient.Established, AddressOf EstablishedNewClient
  166.                 AddHandler NewClient.Disconnected, AddressOf DisconnectedClient
  167.                 AddHandler NewClient.DataReceived, AddressOf RecievedData
  168.                 NewClient.ProcessClientConnected()
  169.             Catch ex As Exception
  170.             End Try
  171.         End While
  172.     End Sub
  173.  
  174.     Public Enum BroadcastType
  175.         WhiteList
  176.         BlackList
  177.     End Enum
  178.  
  179.     Public Enum ServerExceptions
  180.         InvalidSession
  181.         AlreadyRunning
  182.         NotRunning
  183.         IncompleteBroadcast
  184.         IncompleteWhiteListBroadcast
  185.         IncompleteBlackListBroadcast
  186.         FailedToSend
  187.         DisconnectFailed
  188.         [Default]
  189.     End Enum
  190.  
  191.     Public Class ServerException
  192.         Inherits Exception
  193.         Private Msg As String = String.Empty
  194.         Private SessionID() As String
  195.         Private Type As ServerExceptions
  196.         Public ReadOnly Property Sessions() As String()
  197.             Get
  198.                 Return SessionID
  199.             End Get
  200.         End Property
  201.         Public Sub New(ByVal Ex As Exception)
  202.             Type = ServerExceptions.Default
  203.             MyBase.HResult = Ex.HResult
  204.             Msg = Ex.Message
  205.         End Sub
  206.         Public Sub New(ByVal ExceptionType As ServerExceptions, Optional ByVal SessionID() As String = Nothing)
  207.             Type = ExceptionType
  208.             Select Case ExceptionType
  209.                 Case ServerExceptions.AlreadyRunning
  210.                     Msg = "Server is already running"
  211.                 Case ServerExceptions.NotRunning
  212.                     Msg = "Server isn't running"
  213.                 Case ServerExceptions.InvalidSession
  214.                     Me.SessionID = SessionID
  215.                     Msg = "Server does not contain these sessions: " & SessionID(0)
  216.                     For i = 1 To SessionID.Length - 1
  217.                         Msg &= ", " & SessionID(i)
  218.                     Next
  219.                 Case ServerExceptions.DisconnectFailed
  220.                     Me.SessionID = SessionID
  221.                     If SessionID.Length > 0 Then
  222.                         Msg = "Server was unable to close these sessions: " & SessionID(0)
  223.                         If Msg.Length > 1 Then
  224.                             For i = 1 To SessionID.Length - 1
  225.                                 Msg &= ", " & SessionID(i)
  226.                             Next
  227.                         End If
  228.                     End If
  229.                 Case ServerExceptions.FailedToSend
  230.                     Me.SessionID = SessionID
  231.                     If SessionID.Length > 0 Then
  232.                         Msg = "Server was unable to send to session: " & SessionID(0)
  233.                         If Msg.Length > 1 Then
  234.                             For i = 1 To SessionID.Length - 1
  235.                                 Msg &= ", " & SessionID(i)
  236.                             Next
  237.                         End If
  238.                     End If
  239.                 Case ServerExceptions.IncompleteBlackListBroadcast
  240.                     Me.SessionID = SessionID
  241.                     If SessionID.Length > 0 Then
  242.                         Msg = "Server was unable to complete blacklist broadcast: " & SessionID(0)
  243.                         If Msg.Length > 1 Then
  244.                             For i = 1 To SessionID.Length - 1
  245.                                 Msg &= ", " & SessionID(i)
  246.                             Next
  247.                         End If
  248.                     End If
  249.                 Case ServerExceptions.IncompleteWhiteListBroadcast
  250.                     Me.SessionID = SessionID
  251.                     If SessionID.Length > 0 Then
  252.                         Msg = "Server was unable to complete whitelist broadcast: " & SessionID(0)
  253.                         If Msg.Length > 1 Then
  254.                             For i = 1 To SessionID.Length - 1
  255.                                 Msg &= ", " & SessionID(i)
  256.                             Next
  257.                         End If
  258.                     End If
  259.                 Case ServerExceptions.IncompleteBroadcast
  260.                     Me.SessionID = SessionID
  261.                     If SessionID.Length > 0 Then
  262.                         Msg = "Server was unable to complete broadcast: " & SessionID(0)
  263.                         If Msg.Length > 1 Then
  264.                             For i = 1 To SessionID.Length - 1
  265.                                 Msg &= ", " & SessionID(i)
  266.                             Next
  267.                         End If
  268.                     End If
  269.             End Select
  270.         End Sub
  271.         Public Overrides ReadOnly Property Message As String
  272.             Get
  273.                 Return Msg
  274.             End Get
  275.         End Property
  276.     End Class
  277.  
  278.     Public Class ConnectedClient
  279.         Public Event Established(ByVal Client As ConnectedClient, ByVal Time As Date)
  280.         Public Event Disconnected(ByVal SessionID As String, ByVal DateTime As Date)
  281.         Public Event DataReceived(ByVal SessionID As String, ByVal Data() As Byte, ByVal DateTime As Date)
  282.         Private _SessionID As String = String.Empty
  283.         Private ReceiveThread As Threading.Thread
  284.         Private _Client As Socket
  285.         Private Buffer() As Byte
  286.  
  287.         Public ReadOnly Property SessionID() As String
  288.             Get
  289.                 Return _SessionID
  290.             End Get
  291.         End Property
  292.  
  293.         Public Sub New(ByVal Client As TcpClient)
  294.             _Client = Client.Client
  295.             Buffer = New Byte(_Client.ReceiveBufferSize - 1) {}
  296.         End Sub
  297.  
  298.         Private Sub _DataReceived(ByVal Data() As Byte, ByVal Time As Date)
  299.             RaiseEvent DataReceived(SessionID, Data, Time)
  300.             SyncLock _Client
  301.                 If _Client.Connected Then BeginReceive()
  302.             End SyncLock
  303.         End Sub
  304.  
  305.         Public Sub ProcessClientConnected()
  306.             RaiseEvent Established(Me, DateTime.Now)
  307.         End Sub
  308.  
  309.         Public Sub AssignID(ByVal SessionID As String)
  310.             _SessionID = SessionID
  311.         End Sub
  312.  
  313.         Public Sub Send(ByVal Data() As Byte)
  314.             Try
  315.                 _Client.BeginSend(Data, 0, Data.Length, SocketFlags.None, New AsyncCallback(AddressOf OnSend), _Client)
  316.             Catch ex As Exception
  317.             End Try
  318.         End Sub
  319.  
  320.         Private Sub OnSend(ByVal ar As IAsyncResult)
  321.             Try
  322.                 Dim client As Socket = ar.AsyncState
  323.                 client.EndSend(ar)
  324.             Catch ex As Exception
  325.             End Try
  326.         End Sub
  327.  
  328.         Public Function Close() As Boolean
  329.             Try
  330.                 ReceiveThread.Abort()
  331.                 _Client.Close()
  332.                 _Client.Dispose()
  333.                 RaiseEvent Disconnected(SessionID, DateTime.Now)
  334.                 Return True
  335.             Catch ex As Exception
  336.                 Return False
  337.             End Try
  338.         End Function
  339.  
  340.         Public Sub BeginReceive()
  341.             If _Client.Connected Then
  342.                 ReceiveThread = New Threading.Thread(Sub()
  343.                                                          Dim Failed As Boolean = False
  344.                                                          Dim Count As Integer
  345.                                                          Dim R() As Byte
  346.                                                          Using MS As New MemoryStream()
  347.                                                              Do
  348.                                                                  Try
  349.                                                                      Count = _Client.Receive(Buffer)
  350.                                                                      MS.Write(Buffer, 0, Count)
  351.                                                                  Catch ex As Exception
  352.                                                                      Failed = True
  353.                                                                  End Try
  354.                                                              Loop Until Count < Buffer.Length
  355.                                                              R = MS.ToArray
  356.                                                              MS.Close()
  357.                                                          End Using
  358.                                                          If Failed OrElse R.Length = 0 Then
  359.                                                              RaiseEvent Disconnected(SessionID, DateTime.Now)
  360.                                                          Else
  361.                                                              _DataReceived(R, DateTime.Now)
  362.                                                          End If
  363.                                                      End Sub)
  364.                 ReceiveThread.Start()
  365.             End If
  366.         End Sub
  367.     End Class
  368. End Class
Advertisement
Add Comment
Please, Sign In to add comment