Forum: PC-Programmierung ESP8266 Server/ .Net client


von Gerhard (Gast)


Lesenswert?

Auf dem ESP läuft nur die normale AT-Software, hinten dran ein 
ATMega328.
Verbindungsaufbau klappt. Auch der Datenaustausch funktioniert im 
Prinzip...

Problem ist die Erkennung, ob denn nun die Antwort eingetroffen ist.

Wenn ich streamr.ReadLine aufrufe und (noch) nichts drin ist gibts eine 
I/O-Exception.
Also:
Sub Timer1Tick(ByVal sender As Object, ByVal e As EventArgs)  '50ms
  Try
     str=streamr.ReadLine.ToString & vbCr
     tcp_received ()
     .
     .
   Catch e as Exception
  End Try
End Sub
Funktioniert, allerdings wird dadurch die ganze Applikatin extrem träge.
Ideal wäre, vor Aufruf zu wissen, ob Daten da sind, also die 
I/O-Exception vermeiden (das ist der eigentlich Störfaktor).

Ich gestehe, dass ich nur wenig Ahnung von der Geschichte habe, bitte 
also um Nachsicht.
Lösungen? Ganz anderer Ansatz?
Bin für jede Anregung dankbar.

von Ich (Gast)


Lesenswert?

ich habe gerade kene Entwicklungungsmgebung zur Hand, aber 
streamr.available sollte dir helfen.
Ansonsten bitte vollständigen Source herzeigen.

von Gerhard (Gast)


Angehängte Dateien:

Lesenswert?

Danke schon mal für die Antwort.
streamr.available hatte ich auch schon irgendwo gefunden, gibts bei mir 
aber nicht (siehe Bild)
Liegts vielleicht daran, dass ich SharpDevelop benutze? Bisher hatte ich 
aber noch keine Kompatibiltätsprobleme.
Vielleicht fehlt noch was wichtiges?

Imports System.Net.Sockets
Imports System.IO
Imports System.IO.Ports

Durch den  vollständigen Code willst du dich sicher nicht durchwursteln 
(sind knappe 5000 Zeilen und 99,x% haben damit nichts zu tun), es lässt 
sich schon auf den angegebenen Teil beschränken.

von Sebastian R. (basti72)


Lesenswert?

Ein wenig mehr Sourcecode wäre schon hilfreich, da so z.B. gar nicht 
klar ist wie die TCP/IP-Verbindung aufgebaut wird bzw. welche Klassen 
dafür verwendet werden.

Dein streamr ist ja wahrscheinlich ein TextReader (bzw. StreamReader) 
und hat mit TCP/IP nichts zu tun.

Falls du z.B. die Klasse TcpClient verwendest, hat die dann auch die 
"Available" Eigenschaft. Der TcpClient hat aber auch Eigenschaften für 
das Timeout (z.B. ReceiveTimeout) womit du das "hängen" verkürzen 
kannst.


Aber sorry, deiner ganzer Ansatz ist schon murks!

Das empfangen der Daten sollte asynchron erfolgen. Mit aktuellem .NET 
musst du dich dabei nicht einmal mit Tasks rumärgern, sondern kannst 
"await streamr.ReadLineAsync" verwenden. In der Doku von MS findest du 
zu "ReadLineAsync" ein passendes Beispiel:
1
Async Sub ReadCharacters()
2
    Dim result As String
3
4
    Using reader As StreamReader = File.OpenText("existingfile.txt")
5
        Console.WriteLine("Opened file.")
6
        result = Await reader.ReadLineAsync()
7
        Console.WriteLine("First line contains: " + result)
8
    End Using
9
End Sub

Gruß
Basti

von Gerhard (Gast)


Lesenswert?

Owei, muss mich wohl etwas gründlicher damit beschäftugen...
Ist ein altes Projekt, was mal über einen COM-Port lief und jetzt auf 
Wifi umgestellt werden muss.

client As New TCPClient
stream As NetworkStream
streamw As StreamWriter
streamr As StreamReader

Ich hatte es mir einfacher vorgestellt :-)

von Sebastian R. (basti72)


Lesenswert?

Wenn du in deiner Timer-Methode den Try-Block nur ausführst, wenn auch 
Daten vorhanden sind sollte es einigermaßen laufen:

Sub Timer1Tick(ByVal sender As Object, ByVal e As EventArgs)  '50ms
  If client.Available Then
    Try
       str=streamr.ReadLine & vbCr
       tcp_received ()
       .
       .
     Catch e as Exception
    End Try
  End If
End Sub

von Gerhard (Gast)


Lesenswert?

Das funktioniert super, vielen Dank!! Hätte ich mal eher gefragt :-)

Jetzt würde ich es gerne noch besser verstehen, werde mich mal 
informieren.

Noch besser wäre, wenn der client selbst ein Empfangsereignis auslösen 
würde, geht sicher auch, oder? Bzw. ist das mehr oder weniger das, was 
du oben mit Async Sub ReadCharacters() meinst?

Dann bräuchte ich den Timer gar nicht.
Stammt noch aus der COMPort-Zeit:
-schauen, ob Empfangsbuffer.length > 0
-wenn ja schauen, ob darin ein vbcr enthalten ist
-wenn ja Zeile lesen


Auch wenn es jetzt erstmal wie gewünscht funktioniert, würde ich den 
Timer lieber rausschmeissen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.