Telnet Konsole send&Read

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

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von SidezockingLP.

    Telnet Konsole send&Read

    Hey liebe Community, ich stehe mal wieder vor einem Problem dass ich trotz suchen und Tutorials im Internet nicht lösen kann, liegt auch daran dass ich tatsächlich in der Netzwerkprogrammierung noch nichts gemacht habe außer eine Pingabfrage :)

    Ok zum Problem, erstmal was will ich erreichen: Ich möchte zu einem TS3 Server eine Telnet Verbindung aufbauen und über eine Konsole, also mit einer Richtextbox o.a, befehle senden und die Antwort des Servers in der Box ausgeben.

    So sieht das ganz mit Putty aus:
    Verbinden:


    Dann schicke ich einen Login befehl an den Server: 'login serveradmin test'


    Dann bekomme ich die nachricht 'error id=0 msg=ok' ausgegeben und gebe dann den Befehl 'help' eine und bekomme eine liste an befehlen:


    So das ganze will ich jetzt auch in meinem VB-Projekt machen. Folgenden Code habe ich zusammengeschustert:

    VB.NET-Quellcode

    1. Public Sub Send()
    2. Dim TelnetClient As TcpClient
    3. Dim ThisStream As NetworkStream
    4. TelnetClient = New TcpClient("127.0.0.1", 10011)
    5. ThisStream = TelnetClient.GetStream
    6. Aktiv_Stream = ThisStream
    7. Dim log As String
    8. Dim sendBytes As [Byte]()
    9. sendBytes = Encoding.ASCII.GetBytes("login serveradmin test" + vbCrLf)
    10. Aktiv_Stream.Write(sendBytes, 0, sendBytes.Length)
    11. Aktiv_Stream.Read(sendBytes, 0, sendBytes.Length)
    12. log += vbNewLine & Encoding.ASCII.GetString(sendBytes)
    13. sendBytes = Encoding.ASCII.GetBytes("help" + vbCrLf)
    14. Aktiv_Stream.Write(sendBytes, 0, sendBytes.Length)
    15. Aktiv_Stream.Read(sendBytes, 0, sendBytes.Length)
    16. log += vbNewLine & Encoding.ASCII.GetString(sendBytes)
    17. sendBytes = Encoding.ASCII.GetBytes("sendtextmessage targetmode=3 target=7 msg=Test\shaha" + vbCrLf)
    18. Aktiv_Stream.Write(sendBytes, 0, sendBytes.Length)
    19. Aktiv_Stream.Read(sendBytes, 0, sendBytes.Length)
    20. log += vbNewLine & Encoding.ASCII.GetString(sendBytes)
    21. MsgBox(log)
    22. End Sub


    -> In der Msgbox wo ich ja eigentlich den gleichen Output erwarte wie im letzten Putty-Konsolenbild bekomme ich jetzt nur die erste Nachricht ausgegeben. ?(


    So jetzt ist meine Frage wie kann ich denn alle Zeilen auslesen? Sende und empfange ich falsch?

    Wichtig ist auch zu erwähnen dass ich das ganze mit einigen anderen Beispielcodes aus dem Internet probiert habe und auch Beispielprojekte aus dem Internet heruntergeladen habe und immer den gleichen Fehler bekomme, also immer nur die erste Zeile. ?(

    Ich hoffe ihr könnt mir helfen das Problem zu lösen :)
    Bilder
    • putty conf.PNG

      22,95 kB, 458×441, 177 mal angesehen
    • putty login.PNG

      6,97 kB, 773×181, 159 mal angesehen
    • putty help.PNG

      26,3 kB, 660×404, 174 mal angesehen
    • output.PNG

      2,95 kB, 314×156, 173 mal angesehen
    Zu dem Thema TS3 und Putty gab es schon einen Post: Telnet zu TS3
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    @Radinator Den Post habe ich bereits gelesen, leider bringt mir diese TS3 Lib nichts, da darin nur bestimmte Befehle geschickt werden können mit unterschiedlichen aufrufen. Ich möchte aber an den Server den Inhalt einer Textbox schicken.

    SidezockingLP schrieb:

    Aktiv_Stream.Write(sendBytes, 0, sendBytes.Length)
    Aktiv_Stream.Read(sendBytes, 0, sendBytes.Length)

    Dein Lesepuffer ist viel zu klein.
    Nämlich genauso lang wie dein abgeschickter Befehl.

    - Nimm einen eigenen (groß genugen) Puffer.
    - Lese asynchron und trenne das Lesen vom GUI.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    @BornToBeRoot Ja ich habe mir die Lib angeschaut und man kann mit ihr nur voreingestellte Befehle senden, also keine Textbox machen deren Inhalt man an den Server schickt

    @petaod Danke erstmal für deine Antwort. Was genau meinst du mit
    ​groß genug
    ? So, also die länge der geschickten Befehle addiert?:

    VB.NET-Quellcode

    1. Dim log As String
    2. Dim Readbuffer As Integer
    3. Dim sendBytes As [Byte]()
    4. sendBytes = Encoding.ASCII.GetBytes("login serveradmin test" + vbCrLf)
    5. Aktiv_Stream.Write(sendBytes, 0, sendBytes.Length)
    6. Readbuffer = sendBytes.Length
    7. Aktiv_Stream.ReadAsync(sendBytes, 0, Readbuffer)
    8. log += vbNewLine & Encoding.ASCII.GetString(sendBytes)
    9. sendBytes = Encoding.ASCII.GetBytes("use sid=1" + vbCrLf)
    10. Aktiv_Stream.Write(sendBytes, 0, sendBytes.Length)
    11. Readbuffer = Readbuffer + sendBytes.Length
    12. Aktiv_Stream.ReadAsync(sendBytes, 0, Readbuffer)
    13. log += vbNewLine & Encoding.ASCII.GetString(sendBytes)
    14. sendBytes = Encoding.ASCII.GetBytes("sendtextmessage targetmode=3 target=7 msg=Test\shaha" + vbCrLf)
    15. Aktiv_Stream.Write(sendBytes, 0, sendBytes.Length)
    16. Readbuffer = Readbuffer + sendBytes.Length
    17. Aktiv_Stream.ReadAsync(sendBytes, 0, Readbuffer)
    18. log += vbNewLine & Encoding.ASCII.GetString(sendBytes)
    19. MsgBox(log)


    ->Ich bekomme bei Befehl 2 auslesen die Ausnahme: System.Argumentoutofrangeexeption also das Argument liegt außerhalb des gültigen Wertebereichs. Übrigens auch wenn ich statt 'Readbuffer' eine Zahl wie 500 eingebe.

    Sry ich steige gerade nicht durch was du mit
    ​trenne das Lesen vom GUI
    meinst.
    @SidezockingLP:

    SidezockingLP schrieb:

    man kann mit ihr nur voreingestellte Befehle senden
    Schon klar, dass dir die Libary nur fertige (von der Lib definierte) Befehle anbietet. Deswegen:

    BornToBeRoot schrieb:

    schau dir den code an wie die die Verbindung aufbaut/Befehle absetzt.
    . Damit ist gemeint, wie die Lib die eigenen Befehle in Befehle an die TS3 Query API umsetzt.

    SidezockingLP schrieb:

    trenne das Lesen vom GUI
    Heißt nix anderes, als dass Du (im Falle einer UI Anwendung) die Daten nicht in den Controls speichern sollst und mit den Inhalten der Controls arbeiten sollst, sondern Du die Daten in privaten Variablen speichern und verarbeiten sollst und die Controls nur zur Anzeige da sind.
    In deinem Fall würde ich dir raten: Pack das, was sich wiederholt (Encoding, Schreiben, lesen, loggen) in eine eigene Funktion, die Du aufrufst. Diese kann dann entweder auf ein globales oder ein per ByRef übergebenes Stream-Objekt die Daten schreiben und lesen.

    Zu dem Buffer: Was mit der Aussage Dein Lesepuffer ist viel zu klein. gemeint ist, ist folgendes:
    Wenn im Input (also was Du dem Server schickst) der Befehl use sid=1 drinnen steht, dann ist der Buffer 9 Zeichen lang. Wenn dir der Server dann aber ein Ergebnis zurück schickt, was mehr als 9 Zeichen lang ist, dann kommt entweder (wie bei dir) eine Fehlermeldung oder Du erhälst nicht den ganzen Rückgabewert

    Lg Radinator
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    @Radinator @petaod
    ​Wenn dir der Server dann aber ein Ergebnis zurück schickt, was mehr als 9 Zeichen lang ist

    Bedeutet das dann ich muss vorher wissen wie lange die Antwort ist damit ich es abfragen kann? Und wie kann ich das herausfinden? Denn nehme ich eine Zahl die in jedem Fall größer ist als die Antwort sodass die Antwort immer reinpasst bekomme ich immer diesen Fehler

    @Radinator
    ​Damit ist gemeint, wie die Lib die eigenen Befehle in Befehle an die TS3 Query API umsetzt

    Puhh, hab ich rausgesucht und probiert in ein Vb.net beispiel-Form Projekt zu machen. Leider gibt es in dem Code noch einige Fehler bei denen ich nicht wirklich weiterkomme auch weil ich mit den Netzwerk Sachen wie Sockets noch nie gearbeitet habe. Ich poste mal den Code den ich bisher habe wo ich mit Kommentaren die Fehler reingeschrieben habe. Vielleicht hast du mal Zeit drüber zuschauen und mir auf die Sprünge zu helfen.

    VB.NET-Quellcode

    1. ​Imports System.Net
    2. Imports System.Net.Sockets
    3. Imports System.Text
    4. Imports System.Threading
    5. Public Class Form1
    6. Const RECEIVE_BUFFER_SIZE = 4 * 1024
    7. Sub Connect(Host As String, port As Integer)
    8. Trace.WriteLine("Starting to connect to: " & Host)
    9. Dim _receiveRepository = New StringBuilder()
    10. Dim _lastCommandResponse = Nothing
    11. Dim Socket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) With {.ReceiveBufferSize = RECEIVE_BUFFER_SIZE}
    12. Dim ipV4 As IPAddress
    13. Dim RemoteEndPoint
    14. If Not IPAddress.TryParse(Host, ipV4) Then
    15. Dim hostEntry As IPHostEntry = Dns.GetHostEntry(Host)
    16. If hostEntry.AddressList.Length = 0 Then Throw New InvalidOperationException(String.Format("Could not resolve host: {0}", Host))
    17. ipV4 = hostEntry.AddressList.FirstOrDefault(Function(ip) ip.AddressFamily = AddressFamily.InterNetwork)
    18. If ipV4 Is Nothing Then Throw New InvalidOperationException("Could not find a network device with an ip-v4-address.")
    19. RemoteEndPoint = New IPEndPoint(ipV4, port)
    20. Else
    21. RemoteEndPoint = New IPEndPoint(ipV4, port)
    22. End If
    23. Dim _greetingReceived = False
    24. Dim SocketAsyncEventArgs = New SocketAsyncEventArgs With {.RemoteEndPoint = RemoteEndPoint, .UserToken = New SocketAsyncEventArgsUserToken With {.Socket = Socket}}
    25. Socket.InvokeAsyncMethod(Socket.ConnectAsync, Client_Connected, SocketAsyncEventArgs) 'InvokeAsyncMethod ist kein Member von Socket
    26. End Sub
    27. Private Sub Client_Connected(ByVal sender As Object, ByVal socketAsyncEventArgs As SocketAsyncEventArgs)
    28. socketAsyncEventArgs.Completed -= Client_Connected(Nothing, EventArgs.Empty) ' Ausdruck ergibt keinen WErt
    29. EnsureSocketSuccess(socketAsyncEventArgs, Function()
    30. Dim userToken As SocketAsyncEventArgsUserToken = CType(socketAsyncEventArgs.UserToken, SocketAsyncEventArgsUserToken) 'SocketAsyncEventArgsUserToken typ gibt es nicht
    31. Dim sizeBuffer As Byte() = New Byte(RECEIVE_BUFFER_SIZE - 1) {}
    32. socketAsyncEventArgs.SetBuffer(sizeBuffer, 0, sizeBuffer.Length)
    33. userToken.Socket.InvokeAsyncMethod(userToken.Socket.ReceiveAsync, MessageReceived, socketAsyncEventArgs) 'MessageReceived parameter fehlt
    34. End Function)
    35. End Sub
    36. Private Sub MessageReceived(ByVal socketAsyncEventArgs As SocketAsyncEventArgs)
    37. End Sub
    38. Protected Sub EnsureSocketSuccess(ByVal socketAsyncEventArgs As SocketAsyncEventArgs, ByVal action As Action)
    39. Select Case socketAsyncEventArgs.SocketError
    40. Case System.Net.Sockets.SocketError.Success
    41. action()
    42. Case Else
    43. OnSocketError(socketAsyncEventArgs.SocketError)
    44. End Select
    45. End Sub
    46. Protected Sub OnSocketError(ByVal socketError As SocketError)
    47. ThreadPool.QueueUserWorkItem(OnSocketErrorInternal, socketError) 'Fehler Sub OnSocketErrorInternal fehlt ein Object Paramteter
    48. End Sub
    49. Private Sub OnSocketErrorInternal(ByVal state As Object)
    50. Dim socketError As SocketError = CType(state, SocketError)
    51. If Not socketError = Nothing Then SyncContext.PostEx(Function(p) socketError((CType(p, Object()))(0), New SocketErrorEventArgs(CType((CType(p, Object()))(1), SocketError))), New Object() {Me, socketError}) 'Fehler: SyncContext nicht definiert
    52. End Sub
    53. Public Event SocketError As EventHandler(Of SocketError)
    54. End Class