Seite 3 von 4
Re: noch ein daten senden problem
Verfasst: 07.01.2013 19:34
von STARGÅTE
Man schickt aber eigentlich keine einzelnen Longs durch Internet, da ist ja der Header und alle Protokolldaten größer ^^
Entweder du schickst die Zahlen als String mit rüber (gibt ja genügend Trennzeichen, w.z.B. TAB) oder du baust dir ausgehend von den Vorlagen hier im Forum deine eigene Prozedur.
Re: noch ein daten senden problem
Verfasst: 07.01.2013 23:15
von Moxl
okaaay

das schmeißt jetzt meine ganze plaunung und alles um^^
du hast mir den den vorschlag in nem anderen beitrag gemacht x)
Code: Alles auswählen
ReceiveNetworkData(Client, @Type, 4)
Select Type
Case #Datei
ReceiveNetworkData(Client, @LaengeDateiName, 4)
Case #Text
ReceiveNetworkData(Client, @LaengeText, 4)
EndSelect
type ist ja ein long^^ und auf dem prinzip hab ich mir jetzt mein ganzes programm aufgebaut^^
Re: noch ein daten senden problem
Verfasst: 07.01.2013 23:48
von STARGÅTE
Du hast aber den Hinweis "PseudoCode" zu diesem Code vergessen.
Natürlich kannst du diesen Code nicht in dieser Form verwenden (aus den bereits genannten Grunden bezüglich ReceiveNetworkData).
Natürlich sollst du nicht alles mittels Strings senden, das geht ja auch nicht immer.
Sondern, du sollst Code (von anderen oder mir) als Idee nehmen, bzw. als Vorlage.
Du kannst ja auch sowas senden:
"DateiName"+#Tab$+"Beispiel.txt"
"Text"+#Tab$+"Hallo Welt!"
Und die empfangenen Strings kannst du mit StringField() teilen und immer den Typ und Inhalt auslesen.
Auch nur eine Idee!
Du hast jetzt eine Planung gemacht, deswegen musst du auch selber ein dafür zugeschnittenes Include bauen.
Ich habe ein solches Include für mich geschrieben, was auch meine Bedürfnisse zugeschnitten ist.
Du hast jetzt für Strings eine möglichkeit bekommen und ich denke du kannst diese Möglichkeit schnell für andere Sachen umschreiben.
Re: noch ein daten senden problem
Verfasst: 22.01.2017 15:12
von schleicher
STARGÅTE hat geschrieben:
Code: Alles auswählen
EnableExplicit
Structure ReceiveNetworkBlock
Length.l
Shift.i
*Memory
CurrentLength.i
EndStructure
Procedure.i SendString(ConnectionID.i, String.s)
Protected Length.i = StringByteLength(String, #PB_UTF8)
Protected CurrentLength.i, Result.i
Protected *Buffer = AllocateMemory(SizeOf(Long)+Length+1)
PokeL(*Buffer, Length)
PokeS(*Buffer+SizeOf(Long), String, Length, #PB_UTF8)
Repeat
Result = SendNetworkData(ConnectionID, *Buffer, SizeOf(Long)+Length-CurrentLength)
If Result > 0
CurrentLength + Result
ElseIf Result = -1
FreeMemory(*Buffer)
ProcedureReturn #False
EndIf
Until CurrentLength = SizeOf(Long)+Length
FreeMemory(*Buffer)
ProcedureReturn Length
EndProcedure
Procedure.s ReceiveString(ConnectionID.i)
Static NewMap Connection.ReceiveNetworkBlock()
Protected *Connection.ReceiveNetworkBlock, String.s
Protected Key.s = Str(ConnectionID)
Protected ReceiveLength.i, Length.i
; Verbindungs suchen
If FindMapElement(Connection(), Key)
*Connection = Connection()
Else
*Connection = AddMapElement(Connection(), Key)
EndIf
If *Connection\Memory = #Null
; Länge eines neuen Strings empfangen
ReceiveLength = ReceiveNetworkData(ConnectionID, @*Connection\Length+*Connection\Shift, SizeOf(Long)-*Connection\Shift)
If ReceiveLength > 0
If ReceiveLength+*Connection\Shift = SizeOf(Long)
*Connection\Memory = AllocateMemory(*Connection\Length+1)
Else
*Connection\Shift + ReceiveLength
EndIf
EndIf
Else
; alten Strings weiter empfangen
Length = *Connection\Length - *Connection\CurrentLength
ReceiveLength = ReceiveNetworkData(ConnectionID, *Connection\Memory+*Connection\CurrentLength, Length)
If ReceiveLength = Length
String = PeekS(*Connection\Memory, *Connection\Length, #PB_UTF8)
FreeMemory(*Connection\Memory)
DeleteMapElement(Connection(), Key)
ElseIf ReceiveLength > 0
*Connection\CurrentLength + ReceiveLength
EndIf
EndIf
ProcedureReturn String
EndProcedure
InitNetwork()
CreateNetworkServer(1, 7000)
Define CID = OpenNetworkConnection("84.189.151.203", 7000)
Define String.s
Debug SendString(CID, "Hallo Welt!")
Debug SendString(CID, "Das ist eine andere Zeichenkette.")
Debug SendString(CID, "Hier kommt noch was langes: "+Space(4000)+" das wars.")
Debug SendString(CID, "Ende!")
Repeat
If NetworkServerEvent() = #PB_NetworkEvent_Data
String = ReceiveString(EventClient())
If String : Debug Str(Len(String))+" : "+String : EndIf
Else
Delay(1)
EndIf
ForEver
Nach soetwas habe ich gesucht für mein Telnet-Prog. Leider funktioniert der Code unter PB 5.51 nicht und ich weiß nicht warum. ReceiveString(ConnectionID.i) gibt
keine Antwort vom Server zuück. Kannst du da nochmal helfen ?
Re: noch ein daten senden problem
Verfasst: 22.01.2017 20:17
von STARGÅTE
Hallo Schleicher,
du musst natürlich die IP ändern. Ich hatte damals vermutlich eine Route mit hohem Ping gewählt, um dort die Funktionsfähigkeit zu testen. Es geht aber auch genauso mit 127.0.0.1
Re: noch ein daten senden problem
Verfasst: 22.01.2017 20:37
von schleicher
Hallo
IP und Port hatte ich geändert. Ich möchte dein Beispiel für eine Telnetverbindung (Linux Server)nutzen und sitze schon den ganzen Tag an dem folgendem Problem.
Receivestring() gibt den Fehler zurück, das beim Speicher bereitstellen der Wert negativ ist .
Der Befehl
Code: Alles auswählen
ReceiveLength = ReceiveNetworkData(ConnectionID, @*Connection\Length+*Connection\Shift, SizeOf(Long)-*Connection\Shift)
erzeugt in der Map bei *Connection\Length den Minuswert aber ReceiveLength=4
Habe es auch schon mit meinem FTP Server(auch Linux Server) versucht. Dort ist der Wert nicht im Minusbereich, sondern in einem sehr hohen Plusbereich was auch nicht richtig ist.
Hier mein Testcode
Code: Alles auswählen
EnableExplicit
Structure ReceiveNetworkBlock
Length.l
Shift.i
*Memory
CurrentLength.i
EndStructure
Global ip.s="192.168.40.29" ; hier IP, port, user und pass anpassen
Global port=23
Global user.s="root"
Global pass.s="pass"
Global CID
Declare Telnet_Connect(ip.s, port, user.s, pass.s)
Declare.i SendString(ConnectionID.i, String.s)
Declare.s Receivestring(ConnectionID)
Procedure Telnet_Connect(ip.s, port, user.s, pass.s)
Protected antwort.s, connect, ConnectionID_Telnet, *Connection, t
Protected Key
t=ElapsedMilliseconds()
connect=0
ConnectionID_Telnet=OpenNetworkConnection(ip, port)
If ConnectionID_Telnet
Delay(100)
antwort= Receivestring(ConnectionID_Telnet)
Debug "0 "+antwort
If FindString(antwort, "login:", 1)
SendString(ConnectionID_Telnet, user )
antwort = Receivestring(ConnectionID_Telnet)
Debug "1 "+antwort
If FindString(antwort, "Last login") ;Login erfolgt wenn der Server ohne Passwort läuft
connect=1
ElseIf FindString(antwort, "Password", 1)
If SendString(ConnectionID_Telnet, pass )
antwort= Receivestring(ConnectionID_Telnet)
Debug "2 "+antwort
If FindString(antwort, "Last login") ;Login mit Passwort erfolgt
connect=1
EndIf
EndIf
EndIf
EndIf
If connect=1
ProcedureReturn ConnectionID_Telnet
Else
MessageRequester("Error", " Connection error ! Please check User, Pass and Telnet-Port !", #MB_ICONERROR)
EndIf
EndIf
EndProcedure
Procedure.i SendString(ConnectionID.i, String.s)
Protected Length.i = StringByteLength(String, #PB_UTF8)
Protected CurrentLength.i, Result.i
Protected *Buffer = AllocateMemory(SizeOf(Long)+Length+1)
PokeL(*Buffer, Length)
PokeS(*Buffer+SizeOf(Long), String, Length, #PB_UTF8)
Repeat
Result = SendNetworkData(ConnectionID, *Buffer, SizeOf(Long)+Length-CurrentLength)
If Result > 0
CurrentLength + Result
ElseIf Result = -1
FreeMemory(*Buffer)
ProcedureReturn #False
EndIf
Until CurrentLength = SizeOf(Long)+Length
FreeMemory(*Buffer)
ProcedureReturn Length
EndProcedure
Procedure.s Receivestring(ConnectionID)
Static NewMap Connection.ReceiveNetworkBlock()
Protected *Connection.ReceiveNetworkBlock, String.s
Protected Key.s = Str(ConnectionID)
Protected ReceiveLength.i, Length.i
Debug "Verbindungs suchen"
If FindMapElement(Connection(), Key)
*Connection = Connection()
Else
*Connection = AddMapElement(Connection(), Key)
EndIf
If *Connection\Memory = #Null
Debug"Länge eines neuen Strings empfangen"
ReceiveLength = ReceiveNetworkData(ConnectionID, @*Connection\Length+*Connection\Shift, SizeOf(Long)-*Connection\Shift)
If ReceiveLength > 0
If ReceiveLength+*Connection\Shift = SizeOf(Long)
*Connection\Memory = AllocateMemory(*Connection\Length+1) ; *Connection\Length+1 ist hier negativ und bricht ab !
Else
*Connection\Shift + ReceiveLength
EndIf
EndIf
Else
Debug "alten Strings weiter empfangen"
Length = *Connection\Length - *Connection\CurrentLength
Debug "Lenght is "+Str(Length)
ReceiveLength = ReceiveNetworkData(ConnectionID, *Connection\Memory+*Connection\CurrentLength, Length)
Debug "Receivelenght = "+Str(ReceiveLength)+ "Length = "+Str(Length)
If ReceiveLength = Length
String = PeekS(*Connection\Memory, *Connection\Length, #PB_UTF8)
FreeMemory(*Connection\Memory)
DeleteMapElement(Connection(), Key)
ElseIf ReceiveLength > 0
*Connection\CurrentLength + ReceiveLength
EndIf
EndIf
ProcedureReturn String
EndProcedure
InitNetwork()
CID=Telnet_Connect(ip.s, port, user.s, pass.s)
If CID
Debug "Connection with User, Pass, telnet_port ok"
Else
Debug "No Connection"
EndIf
Re: noch ein daten senden problem
Verfasst: 23.01.2017 12:53
von schleicher
Hat es vieleicht was mit der Textcodierung von Linux zu tun. Zeilenende, Zeilenumbruch ?
Re: noch ein daten senden problem
Verfasst: 23.01.2017 16:41
von schleicher
Keiner eine Idee ? Kann man die Länge des vom Server gesendeten String noch anders herausbekommen ?
Re: noch ein daten senden problem
Verfasst: 23.01.2017 19:39
von STARGÅTE
Mir ist nicht ganz klar, um was es geht.
"Mein" ReceiveString() darf nur im Zusammenhang mit "meinem" SendString() verwendet werden.
Das heißt du kannst weder einen "fremden" String mit ReceiveString() empfangen, noch einem fremden Programm einen String mit SendString() senden.
Eine Telnetverbindung (Linux Server) nutzt vermutlich das Telnet-Protokoll (genauso wie es das HTTP- oder FTP-Protokoll gibt), du müsstest dich also mal mit dem Aufbau dieses Protokolls auseinander setzten, damit du nach diesen Regeln Daten senden und empfangen kannst (ähnlich wie du es ja bei HTTP oder FTP auch machen muss).
Bei HTTP bekommt man zB die Länge des Inhalts als Klartext mitgesendet.
Verarbeiten musst du die Daten dann wieder mit den "Grundbefehlen" ReceiveNetworkData und SendNetworkData
PS: Und ja, es ist u.a. sehr wichtig zu wissen in welchem Format Strings zurückgesendet werden und in welchem Format der Zeilenumbruch vorliegt. Steht vermutlich auch in der Dokumentation vom Telnet-Protokoll
Re: noch ein daten senden problem
Verfasst: 23.01.2017 20:54
von schleicher
STARGÅTE hat geschrieben:
"Mein" ReceiveString() darf nur im Zusammenhang mit "meinem" SendString() verwendet werden.
Ich will as auch komplett so nutzen , aber wenn ich die OpenNetworkConnection(IP, port) anfordere, sendet der Server (Telnet) die Loginabfragen User und Passwort (bevor ich überhaupt SendString() benutzt habe).
Ich hatte die Telentverbindung schon selbst fertig geschrieben, doch ich hatte da ein Timing-Problem, wenn der Server länger braucht oder größere Informationen sendet dann gibt es Probleme mit dem empfangen. (Siehe Code unten) Info über das Telnetprotokoll sieht man hier :
http://wiki.blue-panel.com/index.php/BusyBox
Da finde ich aber keine Informationen, wie (mit welchen Zeilenumbruch usw.) der Server dann sendet
Hier ist ein Beispiel, wie die Verbindung mit User und Passwort funktioniert, was aber das genannte Problem hat.
Wie kann man das noch machen, das man auch
alle Informationen sicher empfängt ?
Code: Alles auswählen
EnableExplicit
Global ConnectionID
Global IP.s="192.168.40.29" ;hier anpassen
Global User.s="root"
Global Pass.s=""
Global Port=23
Declare connect()
Declare SendString(ConnectionID, String.s)
Declare .s GetString(ConnectionID, TimeOut = 5000)
InitNetwork()
ConnectionID=connect()
Debug ConnectionID
Procedure connect()
Protected connec.s
ConnectionID= OpenNetworkConnection(IP, Port)
If ConnectionID
connec.s = GetString(ConnectionID)
Debug connec
If FindString(connec, "login:", 1, #PB_String_CaseSensitive)
SendNetworkString(ConnectionID, User +#CRLF$, #PB_Ascii)
Delay(100)
connec.s = GetString(ConnectionID)
Debug connec
Delay(100)
If FindString(connec, "Password", 1, #PB_String_CaseSensitive)
If SendNetworkString(ConnectionID, Pass +#CRLF$, #PB_Ascii)
Delay(500)
connec.s = GetString(ConnectionID)
Debug connec
EndIf
EndIf
EndIf
ProcedureReturn ConnectionID
Else
MessageRequester("Error", "Please check IP and Port ! ", #MB_ICONERROR)
EndIf
EndProcedure
Procedure SendString(ConnectionID, String.s)
Protected Size, *Buffersend, Result = #Null
String = String + #CRLF$
Size = StringByteLength(String, #PB_UTF8) + 1
*Buffersend = AllocateMemory(size)
If *Buffersend
PokeS(*Buffersend, String, Size, #PB_UTF8)
Result = SendNetworkData(ConnectionID, *Buffersend, MemorySize(*Buffersend)-1)
FreeMemory(*Buffersend)
EndIf
ProcedureReturn Result
EndProcedure
Procedure.s GetString(ConnectionID, TimeOut = 5000)
Protected *Buffer, t, Size, Text.s
Delay(200)
*Buffer = AllocateMemory(65536)
t = ElapsedMilliseconds()
If *Buffer
While NetworkClientEvent(ConnectionID) <> 2 And ElapsedMilliseconds()-t < Timeout
Delay(100)
Wend
Repeat
Size=ReceiveNetworkData(ConnectionID, *Buffer, 65536)
Text.s = PeekS(*Buffer, Size, #PB_UTF8)
If Size<65536
Break
EndIf
ForEver
FreeMemory(*Buffer)
ProcedureReturn Text
EndIf
EndProcedure