Multiserver (TCP)

    • VB.NET

    Es gibt 854 Antworten in diesem Thema. Der letzte Beitrag () ist von ClonkAndre.

      Jup aber da er Hier gepostet hat dachte ich mir das er das vielleicht mit einen
      eigenen Server machen will, aber es kann jeder so machen wie er will :)
      MFG 0x426c61636b4e6574776f726b426974
      InOffical VB-Paradise IRC-Server
      webchat.freenode.net/
      Channel : ##vbparadise
      Wie hier schon erkannt schließt sich der Client nicht richtig und der Server erkennt nicht das der Client eigentlich gar nicht mehr aktiv ist, der lösugsvorschlag hier war ja alles zu schließen, aber weil im Listen Sub noch eine Schleife aktiv ist ergeben sich beim schleißen viele Messageboxen, weiß jemmand wie man die Schleife vorher beendet und dann den client schließt ?
      MFG VBWorld
      Mathe ist für alle die, die nicht mit dem Taschenrechner umgehen können :D
      Aber die Schleife geht ja solange wie der Client mit dem server verbunden ist, d.h. die schleife endet erst bis die Verbindung zum Server getrennt wurde. Also würde es nichts bringen das schließen hinter der Schleife zusetzen. Und der Client ist nicht in der Schleife deklariert. Ich spreche über diesen Abschnitt:


      VB.NET-Quellcode

      1. Private Sub Listen()
      2. While Client.Connected
      3. Try
      4. Me.Invoke(New DAddItem(AddressOf AddItem), streamread.ReadLine)
      5. Catch
      6. MessageBox.Show("Verbindung nicht möglich!")
      7. Application.Exit()
      8. End Try
      9. End While
      10. End Sub
      MFG VBWorld
      Mathe ist für alle die, die nicht mit dem Taschenrechner umgehen können :D

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

      Hallo allerseits, habe ein Problem mit dem Server Code der hier im 1 Post ist. und zwar wenn ich den Server starte tritt ein merkwürdiges verhalten auf. Wenn ich mit 2 Clients verbinde und was schreibe kommt am Server nix an aber wenn ich eines der beiden Clients schließe bekomme ich im anderen Client die Letzte Nachricht und etliche Zeilenabsätze. Kann mir das jemand erklären? mfg.
      Hätte auch ein Problem undzwar ich kann denn Server perfekt neustarten und auch beenden, aber die Clients hängen sich auf und "sagen" das im millisekunden Takt leere Narichten ankommen, hätte da einer ne Idee ? Wenn ich dann nen frischen Client starte geht alles Problemlos.

      Konsole:

      VB.NET-Quellcode

      1. Imports System.Net
      2. Imports System.Text
      3. Imports System.Net.Sockets
      4. Module Module1
      5. Dim WithEvents myclient As New Client
      6. Sub Main()
      7. myclient.start("127.0.0.1", 4843)
      8. While True
      9. System.Threading.Thread.Sleep(1000) 'Damit sich die Konsole nicht schließt
      10. End While
      11. End Sub
      12. Private Sub myclient_connected() Handles myclient.connected
      13. Console.WriteLine("Verbindung erfolgreich")
      14. End Sub
      15. Private Sub myclient_newMessage(ByVal stext As String) Handles myclient.newMessage
      16. Console.WriteLine("Naricht : " & stext)
      17. End Sub
      18. Private Sub myclient_reconnected() Handles myclient.reconnected
      19. Console.WriteLine("Reconnecting")
      20. End Sub
      21. End Module


      Client-Klasse

      VB.NET-Quellcode

      1. Imports System.IO
      2. Imports System.Threading
      3. Imports System.Net.Sockets
      4. Imports System.Net
      5. Public Class Client
      6. Dim mytcpclient As TcpClient
      7. Dim mystreamreader As StreamReader
      8. Dim mystreamwriter As StreamWriter
      9. Dim connect As Boolean = False
      10. Private IpAdress As String
      11. Private Port As Integer
      12. Public Event connected()
      13. Public Event reconnected()
      14. Public Event newMessage(ByVal stext As String)
      15. Sub start(ByVal IpAdress As String, ByVal port As Integer)
      16. Me.IpAdress = IpAdress
      17. Me.Port = port
      18. verbinden()
      19. End Sub
      20. Private Sub verbinden()
      21. Try
      22. Me.mytcpclient = New TcpClient
      23. Me.mytcpclient.Connect(Me.IpAdress, Me.Port)
      24. If Me.mytcpclient.Connected = True Then
      25. Me.connect = True
      26. RaiseEvent connected()
      27. Me.mystreamreader = New StreamReader(Me.mytcpclient.GetStream)
      28. Me.mystreamwriter = New StreamWriter(Me.mytcpclient.GetStream)
      29. mystreamwriter.writeline("Username")
      30. Dim t As New Thread(AddressOf receiveText)
      31. t.IsBackground = True
      32. t.Start()
      33. Else
      34. Me.connect = False
      35. reconnect()
      36. End If
      37. Catch ex As Exception
      38. Me.connect = False
      39. reconnect()
      40. End Try
      41. End Sub
      42. Private Sub reconnect()
      43. RaiseEvent reconnected()
      44. Me.mytcpclient.Close()
      45. Thread.Sleep(5000)
      46. verbinden()
      47. End Sub
      48. Public Sub sendText(ByVal stext As String)
      49. Try
      50. Me.mystreamwriter.WriteLine(stext)
      51. Me.mystreamwriter.Flush()
      52. Catch ex As Exception
      53. Me.connect = False
      54. reconnect()
      55. End Try
      56. End Sub
      57. Private Sub receiveText()
      58. Try
      59. While Me.connect
      60. Dim stext As String
      61. stext = Me.mystreamreader.ReadLine
      62. RaiseEvent newMessage(stext)
      63. End While
      64. Catch ex As Exception
      65. Me.connect = False
      66. reconnect()
      67. End Try
      68. End Sub
      69. End Class


      MfG^
      Naja er wird ja anscheinend mit Narichten zugebombt und das hindert in wahrscheinlich "produktiv" weiter nach nem Server zu suchen, auch wenn er sie halbwegs ignoriert.
      Im normalfall hat der Client ja keine Autoreconnectsub aber ich finde wenn ich sowas code sollte wirklich alles gehen auch das Neustarten des Servers ohne Neustart aller Clients.

      Hier mal die Disconnect Sub vom Server

      VB.NET-Quellcode

      1. Public Sub [stop]()
      2. listen = False 'While listen neue Clients empfangen
      3. t.Suspend() 'Listen thread
      4. For i As Integer = clientlist.Count - 1 To 0 Step -1
      5. clientlist(i).disconnect()
      6. Next
      7. mytcplistener.Stop()
      8. mytcplistener = Nothing
      9. RaiseEvent ServerStopped(Me)
      10. End Sub


      Serverclient disconnect Sub

      VB.NET-Quellcode

      1. Public Sub disconnect()
      2. t.Suspend() 'Empfange-Text Thread
      3. Me.connected = False 'While Me.connected : empfange Text
      4. Me.mystreamreader.Close()
      5. Me.mystreamwriter.Close()
      6. Me.mytcpclient.Close()
      7. Me.mytcpclient = Nothing
      8. RaiseEvent disconnected(Me)
      9. End Sub



      MfG
      Ich habe zwar keine Ahnund ob es bei ihnen Funktioniert/Funktionieren wird, aber bei mir tut es dass. Folgender forschlags Code:
      *Anmerkung: Ich habe nicht sehr sauber (eig. gar nicht sauber) godet, da ich in eile war und einfach nur ein Problem besgen wollte, hoffe aber dass man es versteht.
      - Realclose und Closingnow (die Variable) wird auf True gesetzt wenn man den Schließen Button drückt, andernfalls ist die Variable FALSE.

      Code vom Clienten:

      VB.NET-Quellcode

      1. Private Sub Listen()
      2. Do
      3. If Closingnow = True Then
      4. Application.Exit()
      5. Else
      6. While client.Connected
      7. Try
      8. Dim Response As String = streamr.ReadLine
      9. Me.Invoke(New DAddItem(AddressOf AddItem), Response)
      10. Catch
      11. Exit While
      12. End Try
      13. End While
      14. If Realclose = False Then
      15. Try
      16. client = New Net.Sockets.TcpClient
      17. 'client.Connect(ConnIPAd, 25565)
      18. client.Connect(tbConnectToIP.Text, 25565)
      19. stream = client.GetStream
      20. streamr = New StreamReader(stream)
      21. streamw = New StreamWriter(stream)
      22. streamw.WriteLine(nick)
      23. streamw.Flush()
      24. Catch
      25. Try
      26. Me.Invoke(New DConn(AddressOf TryConn))
      27. Catch
      28. MsgBox("Das Programm wird nun geschloßen.", MsgBoxStyle.Information, "Programm schließt sich")
      29. Application.Exit()
      30. End Try
      31. 'Else
      32. ' Application.Exit()
      33. 'End If
      34. End Try
      35. End If
      36. End If
      37. Loop Until Realclose = True
      38. End Sub


      Quellcode

      1. Me.Invoke(New DConn(AddressOf TryConn))

      In dieser Zeile (27) wird ein Sub aufgerufen, welcher nur den String: "Verbinde zum Server..." ausgibt.


      TryConn Sub:

      VB.NET-Quellcode

      1. Private Sub TryConn()
      2. quicksave = tbMessages.Text
      3. tbMessages.Text = quicksave & vbCrLf & "Verbinde zum Server..."
      4. Exit Sub
      5. End Sub


      Dann einfach mal wärend der Client und der Server laufen, den Server schließe und Reaktion abwarten ^^

      Ich hoffe geholfen zu haben und Wünsche noch schöne Grüße :D


      EDIT Nr4. Wichtigen verständniss Punkt hinzugefügt. :whistling:
      Bellum et Pax.
      Omne initium est difficile.
      -KenJy ;D

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

      Massen Spam Nachrichten

      Hallo,

      habe ziemlich das selbe Problem wie schockerjo. Beim Disconnecten bzw. beim Verlassen des Clients bekommt der Server sowie alle Clients massenhaft leere Nachrichten.

      Mein Server:

      VB.NET-Quellcode

      1. Imports System.Net.Sockets
      2. Imports System.IO
      3. Imports System.Net
      4. ' TCP-MultiServer
      5. ' C 2009 - Vincent Casser
      6. Module Module1
      7. Private server As TcpListener
      8. Private client As New TcpClient
      9. Private ipendpoint As IPEndPoint = New IPEndPoint(IPAddress.Any, 8000) ' eingestellt ist port 8000. dieser muss ggf. freigegeben sein!
      10. Private list As New List(Of Connection)
      11. Private Structure Connection
      12. Dim stream As NetworkStream
      13. Dim streamw As StreamWriter
      14. Dim streamr As StreamReader
      15. Dim nick As String ' natürlich optional, aber für die identifikation des clients empfehlenswert.
      16. End Structure
      17. Private Sub SendToAllClients(ByVal s As String)
      18. For Each c As Connection In list ' an alle clients weitersenden.
      19. Try
      20. If s = Nothing Then
      21. Exit Sub
      22. Else
      23. c.streamw.WriteLine(s)
      24. c.streamw.Flush()
      25. End If
      26. Catch
      27. End Try
      28. Next
      29. End Sub
      30. Private Sub Sendtoperson(ByVal s As String, ByVal Nick As String)
      31. For Each Connection In list
      32. Try
      33. If Connection.nick = Nick Then
      34. If s = Nothing Then
      35. Exit Sub
      36. Else
      37. Connection.streamw.WriteLine(s)
      38. Connection.streamw.Flush()
      39. End If
      40. End If
      41. Catch
      42. End Try
      43. Next
      44. End Sub
      45. Sub Main()
      46. Console.WriteLine("Der Server läuft!")
      47. server = New TcpListener(ipendpoint)
      48. server.Start()
      49. While True ' wir warten auf eine neue verbindung...
      50. client = server.AcceptTcpClient
      51. Dim c As New Connection ' und erstellen für die neue verbindung eine neue connection...
      52. c.stream = client.GetStream
      53. c.streamr = New StreamReader(c.stream)
      54. c.streamw = New StreamWriter(c.stream)
      55. c.nick = c.streamr.ReadLine ' falls das mit dem nick nicht gewünscht, auch diese zeile entfernen.
      56. list.Add(c) ' und fügen sie der liste der clients hinzu.
      57. Console.WriteLine(c.nick & " has joined.")
      58. SendToAllClients(c.nick & "<-- Hat den Chat betreten!")
      59. ' falls alle anderen das auch lesen sollen können, an alle clients weiterleiten. siehe SendToAllClients
      60. Dim t As New Threading.Thread(AddressOf ListenToConnection)
      61. t.Start(c)
      62. End While
      63. End Sub
      64. Private Sub ListenToConnection(ByVal con As Connection)
      65. Do
      66. Try
      67. Dim tmp As String = con.streamr.ReadLine ' warten, bis etwas empfangen wird...
      68. Console.WriteLine(con.nick & ": " & tmp)
      69. SendToAllClients(con.nick & ": " & tmp) ' an alle clients weitersenden.
      70. Catch ' die aktuelle überwachte verbindung hat sich wohl verabschiedet.
      71. SendToAllClients(con.nick & "<-- Hat den Chat verlassen!")
      72. Console.WriteLine(con.nick & " has exit.")
      73. list.Remove(con)
      74. Exit Do
      75. End Try
      76. Loop
      77. End Sub
      78. End Module


      Mein Client:

      VB.NET-Quellcode

      1. Imports System.Net.Sockets
      2. Imports System.IO
      3. Public Class frm_Main
      4. Private stream As NetworkStream
      5. Private streamw As StreamWriter
      6. Private streamr As StreamReader
      7. Private client As New TcpClient
      8. Private ActiveConnection As Boolean = True
      9. Private t As New Threading.Thread(AddressOf Listen)
      10. Private Delegate Sub DAddItem(ByVal s As String)
      11. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
      12. If My.Settings.benutzernick = "unknown" Then
      13. frm_Options.Show()
      14. End If
      15. Me.Location = New Point(My.Computer.Screen.WorkingArea.Width - Me.Width, My.Computer.Screen.WorkingArea.Height - Me.Height)
      16. End Sub
      17. Private Sub OptionenToolStripMenuItem1_Click(sender As Object, e As EventArgs) Handles OptionenToolStripMenuItem1.Click
      18. frm_Options.Show()
      19. End Sub
      20. Private Sub Listen()
      21. While client.Connected
      22. Try
      23. Me.Invoke(New DAddItem(AddressOf AddItem), streamr.ReadLine)
      24. Catch
      25. If ActiveConnection Then ' Abfrage
      26. MessageBox.Show("Keine Verbindung zum Server." & vbNewLine & "Das Programm wird nun beendet.")
      27. End If
      28. CloseConnection()
      29. End Try
      30. End While
      31. End Sub
      32. Public Sub CloseConnection()
      33. Try
      34. ActiveConnection = False
      35. streamr.Close()
      36. stream.Close()
      37. client.Close()
      38. streamw.Close()
      39. Catch
      40. End Try
      41. End Sub
      42. Private Sub AddItem(ByVal s As String)
      43. If s = Nothing Then
      44. Exit Sub
      45. Else
      46. If RichTextBox1.Text = Nothing Then
      47. RichTextBox1.AppendText(s)
      48. Else
      49. If s = Nothing Then
      50. Exit Sub
      51. Else
      52. RichTextBox1.AppendText(vbNewLine & s)
      53. End If
      54. End If
      55. RichTextBox1.ScrollToCaret()
      56. If s.StartsWith(My.Settings.benutzernick) Then
      57. Else
      58. NotifyIcon1.ShowBalloonTip(1)
      59. End If
      60. End If
      61. End Sub
      62. Private Sub RichTextBox1_LinkClicked(ByVal sender As Object, _
      63. ByVal e As System.Windows.Forms.LinkClickedEventArgs) _
      64. Handles RichTextBox1.LinkClicked
      65. System.Diagnostics.Process.Start(e.LinkText)
      66. End Sub
      67. Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles MyBase.FormClosed
      68. CloseConnection()
      69. End Sub
      70. Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress
      71. If TypeOf ActiveControl Is TextBox Then
      72. If e.KeyChar = Convert.ToChar(13) Then
      73. Button1.PerformClick()
      74. e.Handled = True
      75. End If
      76. End If
      77. End Sub
      78. Private Sub DisconnectToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles DisconnectToolStripMenuItem.Click
      79. ConnectToolStripMenuItem.Enabled = False
      80. DisconnectToolStripMenuItem.Enabled = False
      81. Try
      82. CloseConnection()
      83. Catch
      84. End Try
      85. If MsgBox("Um neu mit dem Server zu verbinden bitte Programm Neustarten!" & vbNewLine & "Bei Klick auf OK schließt das Programm automatisch!", MsgBoxStyle.Information, "Neustart") = MsgBoxResult.Ok Then
      86. Application.Exit()
      87. End If
      88. End Sub
      89. Private Sub Verbinden()
      90. Dim nick As String = My.Settings.benutzernick
      91. Try
      92. client.Connect(My.Settings.ipadresse, 8000) ' hier die ip des servers eintragen.
      93. ' da dieser beim testen wohl lokal läuft, hier die loopback-ip 127.0.0.1.
      94. If client.Connected Then
      95. stream = client.GetStream
      96. streamw = New StreamWriter(stream)
      97. streamr = New StreamReader(stream)
      98. streamw.WriteLine(nick) ' das ist optional.
      99. streamw.Flush()
      100. t.Start()
      101. Else
      102. MessageBox.Show("Verbindung zum Server nicht möglich!")
      103. Application.Exit()
      104. End If
      105. Catch ex As Exception
      106. MessageBox.Show("Verbindung zum Server nicht möglich!")
      107. Application.Exit()
      108. End Try
      109. End Sub
      110. Private Sub ConnectToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ConnectToolStripMenuItem.Click
      111. Verbinden()
      112. ConnectToolStripMenuItem.Enabled = False
      113. DisconnectToolStripMenuItem.Enabled = True
      114. End Sub
      115. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
      116. Try
      117. If TextBox1.Text = Nothing Then
      118. Exit Sub
      119. End If
      120. streamw.WriteLine(TextBox1.Text)
      121. streamw.Flush()
      122. TextBox1.Clear()
      123. Catch
      124. End Try
      125. End Sub
      126. Private Sub HilfeToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles HilfeToolStripMenuItem.Click
      127. frm_Help.Show()
      128. End Sub
      129. End Class


      Hoffe ihr habt eine Idee und könnt mir diesbezüglich Helfen.

      Mit freundlichen Grüßen
      Nevs08
      Zeile 24 (und auch 40):

      Nevs08 schrieb:

      VB.NET-Quellcode

      1. If s = Nothing Then

      s ist vom Typ String und somit ein Wertetyp. Wertetypen können aber nicht Nothing sein, sondern bei String halt leer (bei Integer = 0, Boolean = False etc.). Also --> If String.IsNullOrEmpty(s)


      BTW: Beim client Zeile 88-98 soll wahrschienlich bewirken, dass Enter = Button1.Click ist oder ? Dazu kannst du auch in der Form die Property AcceptButton gleich Button1 setzen ^^
      »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ThePlexian“ () aus folgendem Grund: Konnte nicht denken

      F*** an das mit dem String hab ich nicht gedacht -.-

      Habs jetzt mal verbessert aber hat sich nichts geändert.


      Und das mit dem Button hatte ich am Anfang so aber scheinbar hat mein Kollege das heute Mittag noch verändert warum auch immer.
      Dann übergib nicht s als Parameter sondern s.Replace(" ", "") dass ist zwar nur eine indirekte Lösung und keine richtige , aber es sollte klappen.
      »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais
      String kann Nothing sein, denn es ist kein Wertetyp. Es ist an sich auch kein primitiver Datentyp. Die korrekte Abfrage ist demnach bla Is Nothing nicht =. Ich bin jetzt zu faul drüber zu schauen, könnte mir aber einen Fehler beim Server vorstellen (z.B. Endlosschleife wegen Try-Catch).

      Try-Catch ohne sinnvolle Catch-Blöcke sind übrigens zu vermeiden.
      Ich meine btw. mich daran zu erinnern, dass das bereits irgendwo im Thread gelöst wurde und es gibt auch noch andere Chat-Sourcecodes hier im Forum.

      Gruß
      ~blaze~

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

      ~blaze~ schrieb:

      String kann Nothing sein, denn es ist kein Wertetyp
      Um Gottes Willen ich weiß auch nicht was da in meinem Kopf falsch war. Schließlich würde die Function sonst ja auch nicht <String.IsNullOrEmpty> heißen.

      Dennoch würde ich bei der Function bleiben, da sie ja scheinbar auf beides prüft.
      »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais