Stream auslesen

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 31 Antworten in diesem Thema. Der letzte Beitrag () ist von Luca.

    Stream auslesen

    Hallo,
    ich habe ein kleines Problem. Der Code ist aus einem Beispielprojekt von DotNetSSH und funktioniert:

    VB.NET-Quellcode

    1. Dim channel As Channel = session.openChannel("shell")
    2. channel.setInputStream(Console.OpenStandardInput())
    3. channel.setOutputStream(Console.OpenStandardOutput())
    4. channel.connect()


    Die Ausgabe von der SSH Verbindung erscheint in der Ausgabe von dem VB Programm (puu.sh/hXuSv/b37bceda68.png). Wie kann ich jetzt die Ausgabe in ein String machen?
    Mein Code:

    VB.NET-Quellcode

    1. Dim sIn As StreamWriter
    2. Dim sOut As StreamReader
    3. channel = session.openChannel("shell")
    4. sOut = New StreamReader(channel.getOutputStream)
    5. sIn = New StreamWriter(channel.getInputStream)
    6. channel.connect()


    zum Auslesen hab ich einfach sOut.ReadToEnd genommen.
    Die ganze Klasse:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports FSM.DotNetSSH.jsch
    2. Imports System.IO
    3. Imports System.Threading
    4. Public Class SSHConnection
    5. Inherits Connection
    6. Public Connected As Boolean = False
    7. Dim update As New Thread(AddressOf UpdateConsole)
    8. Event ConsoleUpdated(console As String)
    9. Dim jsch As New jsch()
    10. Dim session As Session
    11. Dim channel As Channel
    12. Dim sIn As StreamWriter
    13. Dim sOut As StreamReader
    14. Public Sub New(ip As String, port As Integer, user As User)
    15. Me.IP = ip
    16. Me.Port = port
    17. Me.User = user
    18. Me.typ = "SSH"
    19. update.IsBackground = True
    20. End Sub
    21. Public Function TestConnection() As Boolean
    22. Return False
    23. End Function
    24. Public Sub Connect()
    25. Try
    26. session = jsch.getSession(Me.User.Username, Me.IP, Me.Port)
    27. Dim ui As UserInfo = New SSH_UserInfo(Me.User.Password)
    28. session.setUserInfo(ui)
    29. session.connect()
    30. channel = session.openChannel("shell")
    31. sOut = New StreamReader(channel.getOutputStream)
    32. sIn = New StreamWriter(channel.getInputStream)
    33. channel.connect()
    34. 'update.Start()
    35. Connected = True
    36. Catch ex As Exception
    37. MsgBox("Fehler beim Verbinden: " + ex.Message)
    38. Connected = False
    39. End Try
    40. End Sub
    41. Private Sub UpdateConsole()
    42. RaiseEvent ConsoleUpdated(sOut.ReadToEnd)
    43. End Sub
    44. Public Sub Disconnect()
    45. Connected = False
    46. 'sIn.Close() : sIn = Nothing
    47. 'sOut.Close() : sOut = Nothing
    48. 'channel.disconnect() : channel = Nothing
    49. 'session.disconnect() : session = Nothing
    50. 'update.Abort() : update = Nothing
    51. End Sub
    52. Public Sub SendCommand(cmd As String)
    53. sIn.WriteLine(cmd)
    54. End Sub
    55. Public Class SSH_UserInfo
    56. 'Implements UIKeyboardInteractive
    57. Implements UserInfo
    58. Private _passwd As [String]
    59. 'Public Function promptKeyboardInteractive(destination As String, name As String, instruction As String, prompt As String(), echo As Boolean()) As String() Implements UIKeyboardInteractive.promptKeyboardInteractive
    60. ' Dim prmpt As String = If(prompt IsNot Nothing AndAlso prompt.Length > 0, prompt(0), "")
    61. ' _passwd = InputForm.GetUserInput(prmpt, True)
    62. ' Return New String() {_passwd}
    63. 'End Function
    64. Public Sub New(passwd As String)
    65. _passwd = passwd
    66. End Sub
    67. Public Function getPassword() As [String] Implements UserInfo.getPassword
    68. Return _passwd
    69. End Function
    70. Public Function promptYesNo(str As [String]) As Boolean Implements UserInfo.promptYesNo
    71. Dim result As MsgBoxResult = MsgBox(str, MsgBoxStyle.YesNo)
    72. If result = MsgBoxResult.Yes Then
    73. Return True
    74. ElseIf result = MsgBoxResult.No Then
    75. Return False
    76. End If
    77. Return False
    78. End Function
    79. Public Function getPassphrase() As [String] Implements UserInfo.getPassphrase
    80. Return Nothing
    81. End Function
    82. Public Function promptPassphrase(message As [String]) As Boolean Implements UserInfo.promptPassphrase
    83. Return True
    84. End Function
    85. Public Function promptPassword(message As [String]) As Boolean Implements UserInfo.promptPassword
    86. Return True
    87. End Function
    88. Public Sub showMessage(message As [String]) Implements UserInfo.showMessage
    89. MsgBox(message)
    90. End Sub
    91. End Class
    92. End Class


    Mein Fehler:
    puu.sh/hXtwG/2fd02e0f97.png - System.ArgumentException ich versteh das nicht :/ ...

    Ich habe schon ein Thema in diesem Forum zu einer SSH Verbindung geschrieben, aber ich würde ganz gerne diese API nutzen, weil sie im Beispielprojekt besser funktioniert und weniger Fehler hat.
    Ich hoffe, ihr könnt mir helfen :D

    MfG Luca

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Luca“ ()

    Hallo Luca,
    Der StreamReader muss den InputStream bekommen und der StreamWriter muss den OutputStream bekommen (Streamreader liest etwas ein deswegen input und der StreamWriter schreibt etwas raus deswegen output). Deshalb gibt es auch beim OutputStream (nur zum schreiben) beim StreamReader eine ArgumentException mit der Meldung "Der Datenstrom war nicht lesbar"!

    Ich hoffe, ich konnte helfen

    LG
    Twometer
    An Error 404 occurred while loading signature...
    Hi,
    Danke es gibt schon mal kein Fehler bei channel.setOutputStream(sOut) aber wie lese ich das jz aus?

    VB.NET-Quellcode

    1. Private Sub UpdateConsole()
    2. While channel.isConnected
    3. Using reader As New StreamReader(sOut)
    4. MsgBox(reader.ReadToEnd)
    5. End Using
    6. End While
    7. End Sub


    Mit einem StreamReader bekomme ich System.NullReferenceException :/

    MfG Luca
    @Twometer
    Nein der StreamReader liest aus dem Stream und der StreamWriter schreibt in den Stream.
    Es ist schon richtig das der StreamReader den Output-Stream und der StreamWiter den Input-Stream bekommt.

    Wahrscheinlich ist der Output-Stream bereits verworfen sobald du auf ihn zugreifst.
    KaskadekingDE on GitHub :)
    Bitte keine Fragen über Programmierung per PN! Dafür ist das Forum hier.

    Who cares? ¯\_(ツ)_/¯
    Das kann sein, aber bei setInputStream kommt der Fehler... d.h. er wird auch nicht gesetzt D:
    Wenn ich den Output auf die Console (von meinem Programm) setzte und den Input auf einen InputStream und danach versuche mit einem StreamWriter ein Befehl zu senden, bekomme ich einen NULL-Wert, aber wieso?

    LG Luca

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

    @KaskadekingDE Ja aber das was reinkommt (InputStream) muss immer gelesen werden, also StreamReader
    @Luca Und du musst das dann ungefähr so machen:

    VB.NET-Quellcode

    1. Dim sIn As StreamReader
    2. Dim sOut As StreamWriter With {.AutoFlush = True}
    3. channel = session.openChannel("shell")
    4. sIn = New StreamReader(channel.getInputStream)
    5. sOut = New StreamWriter(channel.getOutputStream)
    6. channel.connect()
    7. ' Schreiben
    8. sOut.WriteLine("bla")
    9. 'Lesen
    10. Dim text = sIn.ReadLine()


    Is jetz nur ausm Kopf geschriebenm, kann sein dass du noch was verbessern musst, aber ungefähr so.

    LG
    Twometer
    An Error 404 occurred while loading signature...

    Twometer schrieb:

    Ja aber das was reinkommt (InputStream) muss immer gelesen werden, also StreamReader

    Der OutputStream ist der Ausgabe-Stream welcher gelesen werden muss.
    Der Input-Stream ist der Eingabe-Stream und in den wird reingeschrieben.
    KaskadekingDE on GitHub :)
    Bitte keine Fragen über Programmierung per PN! Dafür ist das Forum hier.

    Who cares? ¯\_(ツ)_/¯

    Twometer schrieb:

    Der StreamReader muss den InputStream bekommen und der StreamWriter muss den OutputStream bekommen

    Twometer schrieb:

    sIn = New StreamReader(channel.getInputStream)
    sOut = New StreamWriter(channel.getOutputStream)


    Da fehlt doch der Input- und OutputStream, oder ?( Außerdem sollte die Ausgabe gelesen werden, weil es die Ausgabe ist und etwas ausgibt, das bedeutet, dass das Ausgegebene gelesen werden muss wie @KaskadekingDE gesagt hat...

    --------------

    Mein Fehler: puu.sh/hXHiW/3ba147b3f5.png
    Verbunden ist er ja, aber wenn ich versuche in einem Thread die Ausgabe der Shell zu lesen, ist reader plötzlich wieder auf Nothing. Ich geh davon aus, dass reader noch nie einen anderen Wert hatte, aber wozu dient dann die getOutputStream Funktion?

    Edit: @Twometer dein Code ist ähnlich wie mein erster (im ersten Post) deswegen bekomme ich den gleichen Fehler

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

    Wie wärs, wenn du das channel.Connect() vor die Zuweisungen setzt, damit die Streams auch tatsächlich vorhanden sind?
    Andernfalls werden die Objekte nämlich idR nicht gesetzt.

    Zudem:

    VB.NET-Quellcode

    1. reader = New StreamReader(channel.GetOutputChannel())
    2. writer = new StreamWriter(channel.GetInputChannel())

    AliveDevil schrieb:

    Wie wärs, wenn du das channel.Connect() vor die Zuweisungen setzt

    Hab ich schon versucht, das geht nicht...

    Den Code lade ich morgen hoch, weil ich gerade VS nicht starten kann. (installiere gerade VS Community 2015)
    Ich hätte noch einen anderen Fehler: SSH Verbindung mit Raspy geht, aber mit meiner Synology DiskStation (BusyBox) bekomme ich Algorithm negotiation failed. Aber das ist nebensächlich, weil ich das vielleicht noch durch Google rauskriege :D .
    Hallo,
    im Anhang ist das Projekt. Mein Fehler ist immer noch derselbe: System.ArgumentNullException (puu.sh/hYRDs/af30168a8a.png)

    MfG Luca

    Edit: hab das Projekt noch ein wenig verändert, aber ist nichts relevantes
    Dateien
    • SSH.zip

      (441,44 kB, 154 mal heruntergeladen, zuletzt: )

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

    KaskadekingDE schrieb:

    Anscheinend ist sOut Nothing.

    Ist immer noch der gleiche Fehler!
    Entweder hat die lib einen Fehler und gibt nie einen Stream zurück oder du machst etwas falsch.
    Aber nach einer Lösung suchen musste am besten einfach selbst. Nur die wenigsten hier werden Erfahrung mit der lib haben.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    Hallo,
    ich glaube nicht, dass die Lib einen Fehler hat, sondern das an meinem Stream liegt.

    Luca schrieb:

    Der Code ist aus einem Beispielprojekt von DotNetSSH und funktioniert:

    VB.NET-Quellcode

    1. Dim channel As Channel = session.openChannel("shell")
    2. channel.setInputStream(Console.OpenStandardInput())
    3. channel.setOutputStream(Console.OpenStandardOutput())
    4. channel.connect()


    Wie mache ich so einen StandardOutput und Input? Da die Console bestimmt nicht mit den OutputStreams aus der Lib arbeitet, müsste es doch mit einem normalen Stream auch gehen :/ .

    MfG Luca

    Edit: ich glaube ich bin weiter gekommen...

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports System.IO
    3. Imports System.Threading
    4. Imports FSM.DotNetSSH.java.io
    5. Imports FSM.DotNetSSH.jsch
    6. Public Class SSHConnection
    7. Public Port As Integer = 22
    8. Public Server As Server = Nothing
    9. Public Connected As Boolean = False
    10. Private update As New Thread(AddressOf UpdateConsole)
    11. Event ConsoleUpdated(console As String)
    12. Private session As Session
    13. Private channel As ChannelShell
    14. Dim sIn As InputStream
    15. Dim sOut As Stream
    16. Public Sub New(server As Server, port As Integer)
    17. Me.Server = server
    18. Me.Port = port
    19. update.IsBackground = True
    20. End Sub
    21. Public Overloads Sub Dispose()
    22. Disconnect()
    23. End Sub
    24. Public Sub Connect()
    25. Try
    26. Dim jsch As New JSch()
    27. session = jsch.getSession(Server.User.Username, Server.IP, Me.Port)
    28. Dim ui As UserInfo = New SSH_UserInfo(Server.User.Password)
    29. session.setUserInfo(ui)
    30. session.connect()
    31. channel = CType(session.openChannel("shell"), ChannelShell)
    32. With channel
    33. sIn = .getInputStream
    34. sOut = .getOutputStream
    35. .connect()
    36. End With
    37. Console.WriteLine("Shell is connected using the " + session.getCipher() + " cipher")
    38. Connected = True
    39. update.Start()
    40. Catch ex As Exception
    41. Throw ex
    42. End Try
    43. End Sub
    44. Public Sub Disconnect()
    45. If Connected Then
    46. sIn.close()
    47. sOut.Close()
    48. End If
    49. If channel IsNot Nothing AndAlso channel.isConnected Then channel.disconnect()
    50. If session IsNot Nothing AndAlso session.isConnected Then session.disconnect()
    51. Connected = False
    52. End Sub
    53. Public Sub UpdateConsole()
    54. Do While channel.isConnected
    55. Using sr As New StreamReader(sOut)
    56. Dim strConsole As String = sr.ReadToEnd
    57. RaiseEvent ConsoleUpdated(strConsole)
    58. Console.WriteLine(strConsole)
    59. End Using
    60. Loop
    61. End Sub
    62. Public Sub SendCommand(cmd As String)
    63. If Connected Then
    64. Using sw As New StreamWriter(sIn)
    65. sw.WriteLine(cmd)
    66. End Using
    67. End If
    68. End Sub
    69. End Class


    Mein Fehler: puu.sh/hZDvY/954908317e.png
    Der OutputStream ist aber nicht mehr Nothing :D Ich bin mir aber nicht sicher wie man den Stream ausliest, kann man den in einen normalen Stream konvertieren ?

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

    Ist die CanRead property vom Output-Stream auf false?
    Wenn ja, dann ist das das Problem. Frag mich aber nicht wie man das behebt.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    Hast Recht :D puu.sh/hZF9k/f9af8fa378.png
    ich hab auch keine Ahnung wie man das behebt...
    Edit: CanWrite True ?????
    Ich teste das nochmal:

    Twometer schrieb:

    sIn = New StreamReader(channel.getInputStream)
    sOut = New StreamWriter(channel.getOutputStream)


    Sicher, dass du da nicht was vertauscht hast? Was hat sIn? Wenn das CanRead haben sollte würde ich die tauschen. Man kann es auch so interpretieren, dass input -> für input, senden, ... steht und output -> für das was aus der session kommt steht.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.