TCP Server Client

  • VB.NET

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von franky0815.

    TCP Server Client

    Moin Moin,

    ich benötige mal Hilfe

    als Anfänger versuche ich über das Netzwerk eine Art Ampelsteuerung zu erstellen Frei / Besetzt. Ich habe vier TextBoxen und möchte das jeder Client eine TextBox ansteuert. Es wäre super wenn mir einer eine Tipp geben könnte wie ich das lösen kann.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class frmServer
    2. Inherits Form
    3. Private tcpListener As TcpListener
    4. Private listenThread As Thread
    5. Private connectedClients As String 'Integer = 0
    6. Private Delegate Sub WriteMessageDelegate(ByVal msg As String)
    7. Public Sub New()
    8. InitializeComponent()
    9. Server()
    10. End Sub
    11. Private Sub Server()
    12. Me.tcpListener = New TcpListener(IPAddress.Any, 5000)
    13. Me.listenThread = New Thread(New ThreadStart(AddressOf listenforclients))
    14. Me.listenThread.Start()
    15. End Sub
    16. Private Sub listenforclients()
    17. Me.tcpListener.Start()
    18. Do
    19. Dim client As TcpClient = Me.tcpListener.AcceptTcpClient
    20. 'Dim Client = tcpListener.AcceptTcpClient
    21. Dim clientthread As New Thread(New ParameterizedThreadStart(AddressOf HandleClientComm))
    22. clientthread.Start(client)
    23.  
    24. 'MsgBox(CType(client.Client.RemoteEndPoint, IPEndPoint).Address().ToString())
    25. connectedClients = (CType(client.Client.RemoteEndPoint, IPEndPoint).Address().ToString())
    26. Loop
    27. End Sub
    28. Private Sub HandleClientComm(ByVal client As Object)
    29. Dim tcpClient As TcpClient = DirectCast(client, TcpClient)
    30. Dim clientStream As NetworkStream = tcpClient.GetStream()
    31. Dim message(4095) As Byte
    32. Dim bytesRead As Integer
    33. Do
    34. bytesRead = 0
    35. Try
    36. bytesRead = clientStream.Read(message, 0, 4096)
    37. Catch
    38. Exit Do
    39. End Try
    40. If bytesRead = 0 Then
    41. connectedClients -= 1
    42. Exit Do
    43. End If
    44. Dim encoder As New ASCIIEncoding
    45. Dim msg As String = encoder.GetString(message, 0, bytesRead)
    46. WriteMessage(msg)
    47. Loop
    48. tcpClient.Close()
    49. End Sub
    50.  
    51. Private Sub WriteMessage(ByVal msg)
    52. If rtbBuero1.InvokeRequired() Then
    53. Dim d As New WriteMessageDelegate(AddressOf WriteMessage)
    54. rtbBuero1.Invoke(d, New Object() {msg})
    55. Else
    56. rtbBuero1.Text = ""
    57. rtbBuero1.AppendText(msg)
    58. End If
    59. End Sub
    60. Private Sub frmServer_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    61. End Sub
    62. Private Sub TableLayoutPanel1_Paint(sender As Object, e As PaintEventArgs) Handles TableLayoutPanel1.Paint
    63. End Sub


    Verschoben. Code in Spoiler verpackt. ~Thunderbolt

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Thunderbolt“ ()

    Du musst dir jetzt überlegen wie sich jeder Client seinen alias mitschicken kann, über welchen du dann später die Clients seperat behandeln kannst.
    • Du könntest eine 10byte lange Kennung von jedem Client mitschicken.
    • Jeder Client muss sich erst am Server registrieren (z.B. erst Connecten dann Daten schicken).
    Du musst auch bisschen mehr sagen was du genau vorhast?

    Sind die TextBoxen bei jedem Client zu sehn oder nur auf dem Server?
    die Client Ip habe ich ja!

    ich dachte ich könnte es darüber lösen.
    das finde ich gut >>>>Jeder Client muss sich erst am Server registrieren (z.B. erst Connecten dann Daten schicken).
    Wie bekomme ich das hin?

    Ich versuche noch mal zu erklären was ich möchte: ich habe 4 PC jeder meldet sich an dem Server mit einer festen IP an soweit funktioniert es. In meinem Server Formular habe ich 4 Textboxen jeder Client soll in eine TextBox den Status ob frei oder besetzt ist reinschreiben. im Augenblick ist ja beim Server nur eine rtbbox bei write message drin die kann ich mit allen Clints steuern aber ich weiß nicht wie ich das auf "rtbox2" und "rtbox3" machen soll.
    Hier noch mal den Code vom Client

    VB.NET-Quellcode

    1. ublic Class AmpelClient
    2. Private client As New TcpClient()
    3. Private serverEndPoint As New IPEndPoint(IPAddress.Parse("192.168.2.1"), 5000) ' (IPAddress.Parse("192.168.2.1"), 5000)
    4. Public Sub New()
    5. Try
    6. InitializeComponent()
    7. client.Connect(serverEndPoint)
    8. Catch ex As Exception
    9.  
    10. MsgBox(ex.ToString)
    11. End Try
    12.  
    13. End Sub
    14.  
    15. Private Sub sendmessage(ByVal msg As String)
    16.  
    17. Dim clientstream As networkstream = client.getstream()
    18. Dim encoder As New asciiencoding()
    19. Dim buffer() As Byte = encoder.GetBytes(msg)
    20. clientstream.write(buffer, 0, buffer.length)
    21. clientstream.Flush()
    22. End Sub
    23.  
    24. Private Sub btnNB_Click(sender As Object, e As EventArgs) Handles btnNB.Click
    25. sendmessage("nicht besetzt")
    26. btnStatus.BackColor = Color.White
    27. End Sub
    28. Private Sub btnStatus_Click(sender As Object, e As EventArgs) Handles btnStatus.Click
    29. If btnStatus.BackColor = Color.Red Then
    30. sendmessage("FREI")
    31. btnStatus.BackColor = Color.GreenYellow
    32. btnStatus.Text = "FREI"
    33. Else
    34. btnStatus.BackColor = Color.Red
    35. sendmessage("BESETZT")
    36. btnStatus.Text = "BESETZT"
    37. End If
    38. End Sub
    39. End Class

    Und wo is jetzt dein Problem?

    Du erstellst am Server ne List(of Clients) wo der Alias und die IP des Clients drinsteht. (Hierfür muss natürlich der Client beim anmelden einen Alias mitschicken (z.B. die ersten 10Byte))

    Beim anmelden wird gecheckt welches die nächste Freie TextBox is (musst dir halt überlegen wie du das handeln willst (z.B. ein Boolean textbox1Frei etc.) und die wird dann auf den Client registriert. Wenn der Client nun sein Status ändert brauchst du nur abfragen welches die TextBox is (geht ja über den Alias ganz simpel) und den Status aktualisieren.

    ...
    Fertig :)
    Danke erst mal für die Antwort, so richtig verstehe ich das nicht, wie gesagt ich fange erst mit VB an.
    Ich werde morgen mal versuchen ob ich etwas hinbekomme. Hast du vielleicht ein Beispiel um den Alias mit zu senden und wie ich eine liste der Clients erstelle.
    Soweit ich es gerade mitverfolge habe, könnte dir vielleicht Regex (Regular Expressions) weiter helfen.

    VB.NET-Quellcode

    1. Dim GetStream As String = "<127.0.0.1>Frei"
    2. Dim RX_m As Match = Regex.Match(GetStream, "<(.+?)>(.+?)", RegexOptions.IgnoreCase)
    3. If RX_m.Success Then
    4. Dim ip As String = RX_m.Groups(1).ToString()
    5. Dim Status As String = RX_m.Groups(2).ToString()
    6. Else
    7. End If

    • Der String GetStream steht, für die Nachricht vom Clienten. Was du nun beim Clienten verändern sollst, wäre, dass du denn Benutzernamen (oder was auch immer) mit verschickst.
    • Regex kann ansich nicht, wissen, was du möchtest, sondern er brauch einen Pattern. Der Pattern bei String GetStream sieht so aus <(.+?)>(.+?) nartürlich könntest du, dass noch verbessern indem du, einen bestimmten Pattern für die IP nimmst und einen Bestimmten Pattern für denn Status, aber es würde für dein Wunsch reichen.
    • Falls, der Match erfolgreich war, fragst du so gesagt "denn Regex nach Gruppen nach". Eine Gruppe erstellt man mit ()
    • ​So würde es dann aussehen:
    1. Groups(1) = 127.0.0.1
    2. Groups(2) = Frei
    ​Viel Glück. :thumbsup:
    Moin Moin,

    vielen Dank für die Antworten, ich werde mich heute mit den Vorschlägen mal beschäftigen und vielleicht finde ich den richtigen weg:)
    Die Clients melden sich alle mit ihrer Ip am Server an, die Steuerung der 1. rtbbox funktioniert auch allerdings steuern alle die rtbbox1

    VB.NET-Quellcode

    1. Private Sub WriteMessage(ByVal msg)
    2. If rtbBuero1.InvokeRequired() And connectedClients = "192.168.2.2" Then
    3. Dim d As New WriteMessageDelegate(AddressOf WriteMessage)
    4. rtbBuero1.Invoke(d, New Object() {msg})
    5. Else
    6. rtbBuero1.Text = ""
    7. rtbBuero1.AppendText(msg)
    8. End If
    9. If rtbBuero2.InvokeRequired() And connectedClients = "192.168.2.1" Then
    10. Dim d As New WriteMessageDelegate(AddressOf WriteMessage)
    11. rtbBuero2.Invoke(d, New Object() {msg})
    12. Else
    13. rtbBuero2.Text = ""
    14. rtbBuero2.AppendText(msg)
    15. End If
    16. End Sub


    das funktioniert so nicht! Hier muss ich irgendwie umbauen damit ich die Zuordnung bekomme, ich habe keine Ahnung wie ich das machen soll.

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „franky0815“ ()

    Lass die Clients doch den Büronamen mitsenden.

    Zum Beispiel b1:besetzt bzw. b1:nbesetzt.
    Im Server kannst du dann den Text am : splitten und anhand der Büronummer der jeweiligen Textbox zuweisen.

    VB.NET-Quellcode

    1. Dim Identifier As String = "Dein Empfanger String hier".Split(":"c)(0)
    2. Select Case Identifier
    3. Case "b1"
    4. 'alles für Textbox 1
    5. Case "b2"
    6. 'alles für Textbox 2
    7. 'usw.
    8. End Select