(Managed Multi) -TCP Server

    • VB.NET

    Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von Krissel095.

      (Managed Multi) -TCP Server

      Also ich habe mir einen kleinen TCP Server geschrieben..:)
      Vielleicht kann ihn einer brauchen.

      Server.vb
      Spoiler anzeigen

      VB.NET-Quellcode

      1. Public Class Server(Of Client As VirtualClient)
      2. Private _BannedIPs As Net.IPAddress()
      3. Public ReadOnly Property BannedIPs As Net.IPAddress()
      4. Get
      5. Return Me._BannedIPs
      6. End Get
      7. End Property
      8. Public Sub AddBan(ByVal IPAddress As String)
      9. If Array.IndexOf(Me._BannedIPs, Net.IPAddress.Parse(IPAddress)) = -1 Then
      10. Array.Resize(Me._BannedIPs, Me._BannedIPs.Length + 1)
      11. Me._BannedIPs(Me._BannedIPs.Length - 1) = Net.IPAddress.Parse(IPAddress)
      12. End If
      13. End Sub
      14. Public Sub RemoveBan(ByVal IPAddress As String)
      15. If Array.IndexOf(Me._BannedIPs, Net.IPAddress.Parse(IPAddress)) = -1 Then
      16. Array.Resize(Me._BannedIPs, Me._BannedIPs.Length + 1)
      17. Me._BannedIPs(Me._BannedIPs.Length - 1) = Net.IPAddress.Parse(IPAddress)
      18. End If
      19. End Sub
      20. Public Sub ClearBans()
      21. Array.Resize(Me._BannedIPs, 0)
      22. End Sub
      23. Private _Clients As List(Of Client)
      24. Public ReadOnly Property Clients As Client()
      25. Get
      26. Return Me._Clients.ToArray()
      27. End Get
      28. End Property
      29. Private _Socket As Net.Sockets.Socket
      30. Public ReadOnly Property Socket As Net.Sockets.Socket
      31. Get
      32. Return Me._Socket
      33. End Get
      34. End Property
      35. Private _LocalEndPoint As Net.IPEndPoint
      36. Public ReadOnly Property LocalEndPoint As Net.IPEndPoint
      37. Get
      38. Return Me._LocalEndPoint
      39. End Get
      40. End Property
      41. Private _Backlog As Integer
      42. Public ReadOnly Property Backlog As Integer
      43. Get
      44. Return Me._Backlog
      45. End Get
      46. End Property
      47. Sub New(ByVal _Port As UShort, Optional ByVal _Backlog As Integer = 32)
      48. Me._LocalEndPoint = New Net.IPEndPoint(Net.IPAddress.Any, _Port)
      49. Me._Backlog = _Backlog
      50. Me._BannedIPs = New Net.IPAddress() {}
      51. Me._Clients = New List(Of Client)
      52. End Sub
      53. Public Sub Start()
      54. If Me._Socket Is Nothing Then
      55. Me._Socket = New Net.Sockets.Socket(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp)
      56. Me._Socket.Bind(Me._LocalEndPoint)
      57. Me._Socket.Listen(Me._Backlog)
      58. Me._Socket.BeginAccept(AddressOf OnAccept, Me._Socket)
      59. End If
      60. End Sub
      61. Public Sub [Stop]()
      62. If Not Me._Socket Is Nothing Then
      63. Me._Socket.Shutdown(Net.Sockets.SocketShutdown.Both)
      64. Me._Socket.Close()
      65. End If
      66. End Sub
      67. Protected Sub OnAccept(ByVal ar As IAsyncResult)
      68. Dim myServer As Net.Sockets.Socket = ar.AsyncState
      69. Dim client As Net.Sockets.Socket = myServer.EndAccept(ar)
      70. If Array.IndexOf(Me._BannedIPs, DirectCast(client.RemoteEndPoint, Net.IPEndPoint).Address) <> -1 Then
      71. client.Disconnect(False) 'Client is banned
      72. RaiseEvent OnIpBlocked(Me, client.RemoteEndPoint)
      73. Else
      74. Dim myClient As Client = GetType(Client).GetConstructor(New System.Type() {GetType(Net.Sockets.Socket)}).Invoke(New Object() {client})
      75. Me._Clients.Add(myClient)
      76. RaiseEvent ClientAccepted(Me, New ClientConnectedEventArgs(Of Client)(myClient))
      77. AddHandler myClient.OnDisconnected, Sub(sender As VirtualClient, ErrorCode As Net.Sockets.SocketError)
      78. RaiseEvent ClientDisconnected(Me, New ClientDisconnectedEventArgs(Of Client)(sender, ErrorCode))
      79. Me._Clients.Remove(sender)
      80. End Sub
      81. AddHandler myClient.OnDataReceived, Sub(sender As VirtualClient, data As Byte())
      82. RaiseEvent DataReceived(Me, New ClientDataReceivedEventArgs(Of Client)(sender, data))
      83. End Sub
      84. myClient.BeginListen()
      85. End If
      86. myServer.BeginAccept(AddressOf OnAccept, myServer)
      87. End Sub
      88. Public Event OnIpBlocked(ByVal sender As Server(Of Client), ByVal e As Net.IPEndPoint)
      89. Public Event ClientAccepted(ByVal sender As Server(Of Client), ByVal e As ClientConnectedEventArgs(Of Client))
      90. Public Event ClientDisconnected(ByVal sender As Server(Of Client), ByVal e As ClientDisconnectedEventArgs(Of Client))
      91. Public Event DataReceived(ByVal sender As Server(Of Client), ByVal e As ClientDataReceivedEventArgs(Of Client))
      92. End Class


      VirtualClient.vb
      Spoiler anzeigen

      VB.NET-Quellcode

      1. Public Class VirtualClient
      2. Private _Socket As Net.Sockets.Socket
      3. Public ReadOnly Property Socket As Net.Sockets.Socket
      4. Get
      5. Return Me._Socket
      6. End Get
      7. End Property
      8. Private _ReceiveBuffer As Byte()
      9. Private _ReceiveError As Net.Sockets.SocketError
      10. Sub New(ByVal _Socket As Net.Sockets.Socket)
      11. Me._Socket = _Socket
      12. Me._ReceiveBuffer = New Byte(2047) {}
      13. End Sub
      14. Friend Sub BeginListen()
      15. If Me._Socket.Connected Then
      16. Me._Socket.BeginReceive(Me._ReceiveBuffer, 0, 2047, Net.Sockets.SocketFlags.None, Me._ReceiveError, AddressOf OnReceive, Me._Socket)
      17. End If
      18. End Sub
      19. Protected Sub OnReceive(ByVal ar As IAsyncResult)
      20. Dim myClient As Net.Sockets.Socket = ar.AsyncState
      21. If myClient.Connected() Then
      22. Dim Received As Integer = myClient.EndReceive(ar)
      23. If Received > 0 Then
      24. Dim myBytes As Byte() = New Byte(Received) {}
      25. Array.Copy(Me._ReceiveBuffer, myBytes, Received)
      26. Array.Clear(Me._ReceiveBuffer, 0, Me._ReceiveBuffer.Length)
      27. RaiseEvent OnDataReceived(Me, myBytes)
      28. Me._Socket.BeginReceive(Me._ReceiveBuffer, 0, 2047, Net.Sockets.SocketFlags.None, Me._ReceiveError, AddressOf OnReceive, myClient)
      29. Exit Sub
      30. End If
      31. End If
      32. RaiseEvent OnDisconnected(Me, Me._ReceiveError)
      33. End Sub
      34. Public Event OnDisconnected(ByVal sender As VirtualClient, ByVal ErrorCode As Net.Sockets.SocketError)
      35. Public Event OnDataReceived(ByVal sender As VirtualClient, ByVal data As Byte())
      36. End Class


      ClientDisconnectedEventArgs.vb
      Spoiler anzeigen

      VB.NET-Quellcode

      1. Public Class ClientDisconnectedEventArgs
      2. Inherits EventArgs
      3. Private _Client As VirtualClient
      4. Public ReadOnly Property Client As VirtualClient
      5. Get
      6. Return Me._Client
      7. End Get
      8. End Property
      9. Private _ErrorCode As Net.Sockets.SocketError
      10. Public ReadOnly Property ErrorCode As Net.Sockets.SocketError
      11. Get
      12. Return Me._ErrorCode
      13. End Get
      14. End Property
      15. Sub New(ByVal _Client As VirtualClient, ByVal _ErrorCode As Net.Sockets.SocketError)
      16. Me._Client = _Client
      17. Me._ErrorCode = _ErrorCode
      18. End Sub
      19. End Class


      ClientDataReceivedEventArgs.vb
      Spoiler anzeigen

      VB.NET-Quellcode

      1. Public Class ClientDataReceivedEventArgs
      2. Inherits EventArgs
      3. Private _Client As VirtualClient
      4. Public ReadOnly Property Client As VirtualClient
      5. Get
      6. Return Me._Client
      7. End Get
      8. End Property
      9. Private _Data As Byte()
      10. Public ReadOnly Property Data As Byte()
      11. Get
      12. Return Me._Data
      13. End Get
      14. End Property
      15. Sub New(ByVal _Client As VirtualClient, ByVal _Data As Byte())
      16. Me._Client = _Client
      17. Me._Data = _Data
      18. End Sub
      19. End Class


      ClientConnectedEventArgs.vb
      Spoiler anzeigen

      VB.NET-Quellcode

      1. Public Class ClientConnectedEventArgs
      2. Inherits EventArgs
      3. Private _Client As VirtualClient
      4. Public ReadOnly Property Client As VirtualClient
      5. Get
      6. Return Me._Client
      7. End Get
      8. End Property
      9. Sub New(ByVal _Client As VirtualClient)
      10. Me._Client = _Client
      11. End Sub
      12. End Class


      Viel Spaß damit (alles selbst geschrieben ;p)

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „BeefyX“ ()



      Warum keine List? So wie du es implementiert hast ist es doch wesentlich umständlicher und unperformanter, als die von Haus aus im Framework enthaltene List(Of T).

      MfG
      Die Performance wird wohl kaum beeinträchtigt, schließlich arbeitet eine List intern auch nur mit nem Array. Aber es wäre einfacher zu benutzen.
      Das stimmt nicht ganz. Die List arbeitet zwar intern mit einem Array, allerdings wird das Resizing wesentlich intelligenter gelöst und ist damit schneller, als seine Implementierung. ;) In dem Anwendungsfall wird es ihm wahrscheinlich auch weniger um die Performance gehen, unschön ist die Implementierung trotzdem.

      MfG
      Naja, er nutzt Array.Resize, und im Framework wird ein neues Array erstellt, und dann mit Array.Copy gefüllt. Wobei ich auch nicht genau weiß, warum sie nicht die Resize Funktion nutzen... Denn das Ergebnis ist das gleiche. Und wenn der Ansatz mit Copy schneller sein sollte, dann wäre die Array.Resize Funktion ein Fail, und sehr schlecht implementiert. Naja, aber es stimmt: die Implementierung ist wirklich unschön. Warum Dinge selber implementieren, die es schon fertig im Framework gibt?
      Es ging mir eher um den Fakt, dass im Framework die Größe jeweils verdoppelt wird, wenn das Array droht überzulaufen und daher der Performanceverlust wesentlich geringer ist, als das Array bei jedem neuen Eintrag zu vergrößern ;)

      MfG