Probleme mit TCP/IP-Verbindung

  • VB.NET

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von elmsrock.

    Probleme mit TCP/IP-Verbindung

    ausgelagert aus TCP/IP Verbindung ~VaporiZed

    Habe ein ähnliches Problem. Mein gewünschter TCP-Partner heißt Denon DN700C (denon-professional.de/dn-700c).
    Das Gerät ist schlichtweg unbedienable. Wenn es einen Track abspielt, kann man nicht mal einen anderen vorwählen (Press Stop) oder einen zum Programm hinzufügen. Professional eben.
    Das hat in mir den Wunsch ausgelöst, einmalig die ganzen vorhandenen Tracks einzulesen und von meiner VB-Anwendung aus zu steuern.
    Play, Stop, On und Off sprich senden funktioniert auch einwandfrei, nur bekomme ich keine Antworten rein.
    Der hier aus dem Forum zusammengesammelte Code wird scheinbar nur bis zur Zeile "client = Server.AcceptTcpClient" ausgeführt.
    Kann mir jemand sagen, woran es hapert?
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Net.Sockets
    2. Imports System.Net
    3. Imports System.IO
    4. Imports System.Text
    5. Public Class Form1
    6. '######################################################################## Denon MIDI Codes
    7. Dim PowerOn As Byte() = {&H11, &H1, &H0, &H1, &H1, &H0, &H31, &H34}
    8. Dim PowerOff As Byte() = {&H11, &H1, &H0, &H1, &H2, &H0, &H31, &H35}
    9. Dim PlayTrack As Byte() = {&H11, &H1, &H0, &H0, &H2, &H0, &H31, &H34}
    10. Dim StopTrack As Byte() = {&H11, &H1, &H0, &H0, &H1, &H0, &H31, &H33}
    11. Dim getTransportStatus As Byte() = {&H11, &H1, &H0, &H9, &H1, &H0, &H31, &H43}
    12. '######################################################################## Server
    13. Dim stream As NetworkStream
    14. Dim Server As TcpListener
    15. Dim client As New TcpClient
    16. Dim ipendpoint As IPEndPoint = New IPEndPoint(IPAddress.Any, 23)
    17. Dim mainthread As Threading.Thread
    18. '########################################################################
    19. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    20. client.Connect("192.168.178.58", 23) ' Denon-IP, Telnet, Exception wenn schon verbunden oder Gerät nicht vorhanden!!!
    21. If client.Connected Then
    22. ToolStripStatusLabel1.Text = "Verbindung hergestellt!"
    23. stream = client.GetStream
    24. mainthread = New Threading.Thread(AddressOf mainserver)
    25. Control.CheckForIllegalCrossThreadCalls = False
    26. mainthread.Start()
    27. Else
    28. ToolStripStatusLabel1.Text = "Verbindung konnte nicht hergestellt werden!"
    29. End If
    30. End Sub
    31. '########################################################################
    32. Sub mainserver() ' thread
    33. Try
    34. Server = New TcpListener(ipendpoint)
    35. Server.Start()
    36. client = Server.AcceptTcpClient
    37. stream.ReadTimeout = 10000
    38. While True
    39. ListBox1.Items.Add("Listening...")
    40. Dim ReceiveBytesVb(client.ReceiveBufferSize) As Byte
    41. stream.Read(ReceiveBytesVb, 0, CInt(client.ReceiveBufferSize))
    42. Dim ReturnDataVb As String = Encoding.ASCII.GetString(ReceiveBytesVb)
    43. ListBox1.Items.Add(ReturnDataVb)
    44. End While
    45. Catch ex As Exception
    46. MsgBox("Catch: " & ex.Message)
    47. End Try
    48. End Sub
    49. '########################################################################
    50. Private Sub Form1__close(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.FormClosing
    51. Server.Stop()
    52. Try
    53. mainthread.Abort()
    54. Catch
    55. End Try
    56. End Sub
    57. '########################################################################
    58. Sub client_send(ByRef bytes As Array)
    59. Dim pre As Byte() = {&HF0, &H0, &H40, &H3}
    60. Dim post As Byte() = {&HF7}
    61. Dim send As Byte() = pre.Concat(bytes).ToArray.Concat(post).ToArray
    62. stream.Write(send, 0, send.Length)
    63. End Sub
    64. Private Sub ButtonAus_Click(sender As Object, e As EventArgs) Handles ButtonAus.Click
    65. client_send(PowerOff)
    66. End Sub
    67. Private Sub ButtonEin_Click(sender As Object, e As EventArgs) Handles ButtonEin.Click
    68. client_send(PowerOn)
    69. End Sub
    70. Private Sub ButtonPlay_Click(sender As Object, e As EventArgs) Handles ButtonPlay.Click
    71. client_send(PlayTrack)
    72. End Sub
    73. Private Sub ButtonStop_Click(sender As Object, e As EventArgs) Handles ButtonStop.Click
    74. client_send(StopTrack)
    75. End Sub
    76. Private Sub ButtonGetTransportStatus_Click(sender As Object, e As EventArgs) Handles ButtonGetTransportStatus.Click
    77. client_send(getTransportStatus)
    78. End Sub
    79. '########################################################################
    80. End Class


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

    @elmsrock Leider lässt sich das ohne die Gegenstelle schlecht nachvollziehen.
    Ich würde das Verbinden aus der Form_Load rausnehmen, weil da Exceptions ggf. verschluckt werden.
    Pack das mal in eine Button_Click und stell sicher, dass wirklich eine Verbindung zustande kommt.
    Steppe den Code dann zeilenweise durch und überzeuge Dich, dass er das tut, was er soll.
    Debuggen, Fehler finden und beseitigen
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hi Rod!
    Mit dem Button habe ich auch schon probiert. ist das Gleiche.
    Die Verbindung wird ja auch hergestellt, denn ich kann ja senden und das Gerät reagiert einwandfrei.
    Ich empfange nur keine Antworten, keine ACKs wie im Handbuch
    (elmsrock.de/download/DN700CEM_ethernet_control_addendum.pdf
    und
    elmsrock.de/download/DN700C_DN501C_MIDICommandGuide_v1.0.pdf )
    beschrieben, kein gar nix.
    Ist denn der Code grundsätzlich richtig?
    Merkwürdig finde ich auch, dass wenn ich den Code wie im Spoiler erweitere um den Debugmodus auch noch zu umgehen, dass nur die 1 und die 2 ausgegeben wird.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Sub mainserver() ' thread
    2. Try
    3. Server = New TcpListener(ipendpoint)
    4. ListBox1.Items.Add("1")
    5. Server.Start()
    6. ListBox1.Items.Add("2")
    7. client = Server.AcceptTcpClient
    8. ListBox1.Items.Add("3")
    9. stream.ReadTimeout = 10000
    10. ListBox1.Items.Add("4")

    elmsrock schrieb:

    Ist denn der Code grundsätzlich richtig?
    Nö.
    Das

    elmsrock schrieb:

    VB.NET-Quellcode

    1. Control.CheckForIllegalCrossThreadCalls = False
    solltest Du rausnehmen.
    Statt Ausgaben in einer ListBox zu protokollieren, schreib sie besser nach Console.WriteLine(...).
    Diese Ausgaben landen dann während des Debuggens im Ausgabe-Fenster des Studios.
    Wenn Du an Dein Programm eine Console anhängst, gehen diese Ausgaben dort hinein und das geht wesentlich schneller.
    Die einfachste Lösung geht so: Kommunikation zwischen Console und Form
    allerdings darfst Du die Console nicht schließen, sonst wird das Programm auch geschlossen.
    Ansonsten nimm dies hier:
    Angehängte Console kann nicht direkt geschlossen werden.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Warum machst du denn selber einen Liestener auf und wartest auf eine Verbindung? Der TCP-Client ist duplex, geht also direkt in beide Richtungen, sobald du verbunden bist. Nach dem ​client.Connect("192.168.178.58", 23) steht die Verbindung und du kannst in den ​client schreiben und auch aus diesem lesen.
    @elmsrock Dann kann es sein, dass das Senden auch nicht funktioniert.
    Sieh Dir mal die Einstellungen Deiner Firewall an.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Den CheckForIllegalCrossThreadCalls will ich später rausnehmen, wenn es denn mal laufen sollte.

    Also wenn ich mit Telnet 192.168.178.58 eine Verbindung herstelle und am Denon Play, Stop und dergleichen drücke, kommen in der Telnet-Box die gewünschten Daten an.
    Die Verbindung ist also möglich, zumal ich die Firewall testweise auch schon abgeschaltet habe.
    Von meinem Programm aus kann ich ja auch Play und Stop und dergleichen senden und es passiert das Gewünschte, ich bekomme nur keine Antworten.
    Das Programm bleibt schlichtweg bei der Zeile " client = Server.AcceptTcpClient" hängen.
    Das ist laut "https://docs.microsoft.com/de-de/dotnet/api/system.net.sockets.tcplistener.pending?view=netcore-3.1"
    ja auch eine blockierende Methode ist, wobei mittels "Pending" vorher abgefragt werden kann, ob da was kommt.
    Das habe ich jetzt probiert (siehe Spoiler), es kommt aber gar nicht bei "ListBox1.Items.Add(Now)" an.
    Das Problem muss also irgendwo anders liegen. Nur wo?

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Sub mainserver() ' thread
    2. stream = client.GetStream
    3. Server = New TcpListener(ipendpoint)
    4. Server.Start()
    5. stream.ReadTimeout = 10000
    6. ListBox1.Items.Add("Listening...")
    7. Try
    8. While True
    9. If Server.Pending() Then
    10. ListBox1.Items.Add(Now)
    11. client = Server.AcceptTcpClient
    12. Dim ReceiveBytesVb(client.ReceiveBufferSize) As Byte
    13. stream.Read(ReceiveBytesVb, 0, CInt(client.ReceiveBufferSize))
    14. Dim ReturnDataVb As String = Encoding.ASCII.GetString(ReceiveBytesVb)
    15. ListBox1.Items.Add(ReturnDataVb)
    16. End If
    17. End While
    18. Catch ex As Exception
    19. MsgBox("Catch: " & ex.Message)
    20. End Try
    21. End Sub
    @elmsrock Kann es sein, dass Du eine zweite TCP-Verbindung für den Rück-Teil der Kommunikation aufmachen musst?
    Was sagt die Beschreibung?
    Was sagt der Hersteller?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hi,

    ich verstehe deinen Aufbau nicht. Es ist völlig klar das es bei AcceptTcpClient nicht weiter geht denn er wartet solange bis sich jemand dann darauf verbindet.
    Les dir dazu mal das hier durch dann verstehst du warum: docs.microsoft.com/de-de/dotne…cpclient?view=netcore-3.1

    Du deklarierst hier einen Listener und einen Client warum? Du willst doch nur senden und deine Antwort empfangen. Also brauchst du einen TCPClient
    dieser sendet deinen Befehl und liest direkt den Stream aus den du vorliegen hast für deine Antwort.

    Dein Listener ist ein Server, woher soll dein DNC wissen das er dahin verbinden soll? Das geht nicht.
    Bau dein Zeug mal so um das du EINEN Client hast der sich verbindet, deinen Befehl sendet und dann den Stream per ReadLine / Read / ReadBlock oder dergleichen ausliest.
    Grüße , xChRoNiKx

    Nützliche Links:
    Visual Studio Empfohlene Einstellungen | Try-Catch heißes Eisen
    @xChRoNiKx & Bluespide:
    Ah, jez jah!
    Irgendwie habe ich wohl Ausführliches TCP und UDP Tutorial falsch verstanden, nämlich, dass ich, um Daten zu empfangen, auch einen Server anlegen muss.
    Der TCP-Partner würde dann, wie er es jetzt ja auch tut, an die Adresse zurück senden, von wo die Anfrage kam, nur dass da ein Server laufen müsste.
    Ich empfange zumindest Daten. Allerdings muss ich noch rauskriegen, wie ich mit der Denon-Antwort {&HF0,&H00,&H40,&H03,&H11,&H01,&H00,&H09,&H3C,&H02,&H30,&H31,&H42,&H41,&HF7} bei der Frage nach dem Namen des ersten Files im ersten Ordner auf diesen komme, aber das steht in einem anderen Buch.
    @Rod:
    Nein, keine zweite nötig. Beschreibung sagt "Telnet" und damit konnte ich ja auch bereits empfangen.

    Danke nochmal an alle und hier das jetzt korrekt arbeitende Codegerüst:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Net.Sockets
    2. Public Class Form1
    3. '######################################################################## Denon MIDI Codes
    4. Dim PowerOn As Byte() = {&H11, &H1, &H0, &H1, &H1, &H0, &H31, &H34}
    5. Dim PowerOff As Byte() = {&H11, &H1, &H0, &H1, &H2, &H0, &H31, &H35}
    6. Dim PlayTrack As Byte() = {&H11, &H1, &H0, &H0, &H2, &H0, &H31, &H34}
    7. Dim StopTrack As Byte() = {&H11, &H1, &H0, &H0, &H1, &H0, &H31, &H33}
    8. Dim getTransportStatus As Byte() = {&H11, &H1, &H0, &H9, &H1, &H0, &H31, &H43}
    9. Dim getNameOfFirstFileInFolder1 As Byte() = {&H11, &H1, &H0, &HD, &HC, &H8, &H30, &H30, &H30, &H31, &H30, &H30, &H30, &H31, &H42, &H35}
    10. '######################################################################## Server
    11. Dim stream As NetworkStream
    12. Dim client As New TcpClient
    13. '########################################################################
    14. Private Sub ButtonConnect_Click(sender As Object, e As EventArgs) Handles ButtonConnect.Click
    15. client.Connect("192.168.178.58", 23) ' Denon-IP, Telnet, Exception wenn schon verbunden oder Gerät nicht vorhanden!!!
    16. If client.Connected Then
    17. ToolStripStatusLabel1.Text = "Verbindung hergestellt!"
    18. Else
    19. ToolStripStatusLabel1.Text = "Verbindung konnte nicht hergestellt werden!"
    20. End If
    21. End Sub
    22. Sub client_comm(ByRef bytes As Array)
    23. Dim pre As Byte() = {&HF0, &H0, &H40, &H3}
    24. Dim post As Byte() = {&HF7}
    25. Dim send As Byte() = pre.Concat(bytes).ToArray.Concat(post).ToArray
    26. stream = client.GetStream
    27. stream.Write(send, 0, send.Length)
    28. '#########
    29. Dim ReceiveBytesVb(client.ReceiveBufferSize) As Byte
    30. Dim c As Int32 = stream.Read(ReceiveBytesVb, 0, CInt(client.ReceiveBufferSize))
    31. 'ReceiveBytesVB = Antwort, c=Stringlänge
    32. End Sub
    33. '########################################################################
    34. Private Sub ButtonAus_Click(sender As Object, e As EventArgs) Handles ButtonAus.Click
    35. client_comm(PowerOff)
    36. End Sub
    37. Private Sub ButtonEin_Click(sender As Object, e As EventArgs) Handles ButtonEin.Click
    38. client_comm(PowerOn)
    39. End Sub
    40. Private Sub ButtonPlay_Click(sender As Object, e As EventArgs) Handles ButtonPlay.Click
    41. client_comm(PlayTrack)
    42. End Sub
    43. Private Sub ButtonStop_Click(sender As Object, e As EventArgs) Handles ButtonStop.Click
    44. client_comm(StopTrack)
    45. End Sub
    46. Private Sub ButtonGetTransportStatus_Click(sender As Object, e As EventArgs) Handles ButtonGetTransportStatus.Click
    47. client_comm(getTransportStatus)
    48. End Sub
    49. Private Sub ButtonGetNameOfFirstFileInFolder1_Click(sender As Object, e As EventArgs) Handles ButtonGetNameOfFirstFileInFolder1.Click
    50. client_comm(getNameOfFirstFileInFolder1)
    51. End Sub
    52. '########################################################################
    53. End Class