# Libnodave Timeout



## Lazarus™ (13 Oktober 2005)

Hallo Zottel, nochmal eine Frage   

Ich habe DaveInterface^.Timeout := 2000000;   // 2 Sekunden

und folgenden Code :


```
function TMaschine.NextJob: Integer;
begin
  Result := -1;
  if TestPing(FIpAdresse, PollTimeOut) then begin
    case FJobIndex of
      0: Result := DaveReadBytes(DaveConnection, DaveInputs, 0, 0,  128, @EData[0]);      // EB 0 - 127
      1: Result := DaveReadBytes(DaveConnection, DaveOutputs, 0, 0,  2, @AData[0]);       // AB 0 - 127
      2: Result := DaveReadBytes(DaveConnection, DaveFlags, 0, 0, 128, @MData[0]);        // MB 0-127
      3: Result := DaveReadBytes(DaveConnection, DaveFlags, 0, 128, 128, @MData[128]);    // MB 128 - 255
      4: Result := DaveReadBytes(DaveConnection, DaveDB, 1, 0, 150, @DB1Data[0]);         // DB1 DBB 0 - 149
      5: Result := DaveReadBytes(DaveConnection, DaveDB, 1, 150,  148, @DB1Data[150]);    // DB1 DBB 150 - 298
      6: Result := DaveReadBytes(DaveConnection, DaveDB, 35, 0, 150, @DB35Data[0]);       // DB35 DBB 0 - 149
      7: Result := DaveReadBytes(DaveConnection, DaveDB, 35, 150, 150, @DB35Data[150]);   // DB35 DBB 150 - 299
      8: Result := DaveReadBytes(DaveConnection, DaveDB, 35, 300, 150, @DB35Data[300]);   // DB35 DBB 300 - 449
      9: Result := DaveReadBytes(DaveConnection, DaveDB, 20, 0,  103, @DB20Data[0]);      // DB20 DBB 0 - 102
      10: Result := DaveReadSZL(DaveConnection, $19, 0, @SzlData[0]);                     // SZL Led - Abbild
      100: Result := DaveWriteBytes(DaveConnection, DaveDB, 1, 48, 4, @DB1Data[48]);      // DB1 DBB 48 - 51
    end;
    Inc(FJobIndex);
    if FJobIndex < 100 then begin
      if FJobIndex > 10 then
        FJobIndex := 0;
    end else begin
      if FJobIndex > 100 then
        FJobIndex := 0;
    end;
  end;
end;
```

Wenn direkt im Lesen von Variablen aus der Steuerung nun der CP ausgeht, kommt mein Programm nie wieder ??
Gilt das TimeOut nicht auch für DaveReadBytes... Kann es sein, das, wenn der CP ausfällt mitten in DaveReadBytes ein Programmhänger entsteht ????  Früher,mit dem Seriellen Adapter, habe ich das so nie gesehen. Bin mir aber nicht sicher...

Und lach nicht, mit dem Ping vor dem Lesen, habe ich eine schnellere Reaktion bei ausgefallenem CP (?)


----------



## Zottel (13 Oktober 2005)

> Wenn direkt im Lesen von Variablen aus der Steuerung nun der CP ausgeht, kommt mein
> Programm nie wieder ??


Ist das eine Feststellung oder eine Frage?



> Gilt das TimeOut nicht auch für DaveReadBytes


Nein, nicht wenn es eine TCP/IP-Verbindung under Windows ist. Die handhabt winsock2 mit default-Einstellungen.


> ... Kann es sein, das, wenn der CP ausfällt mitten in DaveReadBytes ein Programmhänger entsteht ????


Du meinst, daß das Programm "hängt"? Ja das könnte wohl sein, daß die Funktion receive() aus winsock2.dll nie zurückkehrt. Ich muß es mal systematisch probieren. Habe aber keinen CP und die Simulation eines CP auf Linux ist so schnell, daß es schwer ist, mitten im Senden den Stecker zu ziehen. Und der TCP/IP -Stack von Linux gut genug, um das Paket nachzureichen, wenn der Stecker wieder reingesteckt wird...


> Und lach nicht, mit dem Ping vor dem Lesen, habe ich eine schnellere Reaktion bei ausgefallenem CP (?)


Ist das eine Feststellung oder eine Frage?
Ich habe sowas ähnliches an ganz anderer Stelle: Aus einem Linux-Programm sende ich Daten an eine AS400. Das passiert nur alle 20-60 Minuten. Da bekam ich timeouts. Das passiert nicht, wenn ich sie vorher "pinge"... Habe es nicht näher untersucht. Auf jeden Fall sind Ethernet-Switches dazwischen. Möglicherweise "lernen" sie beim 1. Ping die Route neu und vergessen sie zwischenzeitlich. Möglicherweise setzt die AS400 irgenetwas zur Handhabung der Ethenet-Schnittstelle oder verbindungsspezifische Sachen auf niedrige Prioirtät. Kann sein, daß so ein Ping auch den CP weckt.

[/quote]


----------



## Lazarus™ (13 Oktober 2005)

Aha,dann ist es nicht ein logischer Fehler meinerseits. Also bei Verwendung von einem MPI-Adapter passiert das auch nicht...

Schade...  Ist schon doof,wenn der Anwender später die Maschine Abends ausmacht und das BDE ergurgelt sich...  Na mal sehen, was man da machen kann,an die Funktion receive() aus winsock2.dll komme ich ja so nicht ran, um das abzufangen ...

Sorry für die Fragezeichen (?) und ?? sollten Ratlosigkeit symbolisieren


----------



## Lazarus™ (14 Oktober 2005)

Ja, ist wohl wirklich so, unter TCPIP kommt der Aufruf DaveReadBytes(...)
nie mehr wieder, wenn der CP aussteigt... Wenn mein Debugger nicht gelogen hat  :roll: (Bediener vor PC ist kein Assembler Freak) , hängt das irgendwo ausserhalb deiner Routinen im OS... Wüsste gern, wie man das lösen könnte. Einen Weg muss es ja geben...

Gibt es eigentlich einen Unterschied, ob man das mit Prodave/LibNoDave oder S7-SAPI macht ??? Weil, wenn man irre viele Variablen mit WinCC in sehr kurzen abständen pollt, läuft das recht flott. Mit den eigenen Routinen ist das eher Zeitlupe... Mache ich was falsch, oder ist das Protokollbedingt ??

Wieder viele Fragen *ggg*, aber nützt ja nix  :evil:


----------



## Zottel (14 Oktober 2005)

Lazarus™ schrieb:
			
		

> Ja, ist wohl wirklich so, unter TCPIP kommt der Aufruf DaveReadBytes(...)
> nie mehr wieder, wenn der CP aussteigt... Wenn mein Debugger nicht gelogen hat  :roll: (Bediener vor PC ist kein Assembler Freak) , hängt das irgendwo ausserhalb deiner Routinen im OS... Wüsste gern, wie man das lösen könnte. Einen Weg muss es ja geben...


Habe gestern folgendes probiert: testISO_TCP -b -d <IP-von-der-Linux-Box> auf Win2000 laufen lassen. Vorher in nodave.c vor und hinter den recv()-Aufrufen Zeilen eingefügt wie 'log1("before recv\n")';, 'log1("back from recv\n")';
Auf der Linux-Kiste lief isotest4 (CP-Simulation).
Dann im laufenden Benchmark Stecker gezogen. Programm hing 2-3 Minuten. Dann gab's aber timeout-Meldungen. Das Programm hing also nicht in "alle Ewigkeit". 



> Gibt es eigentlich einen Unterschied, ob man das mit Prodave/LibNoDave oder S7-SAPI macht ??? Weil, wenn man irre viele Variablen mit WinCC in sehr kurzen abständen pollt, läuft das recht flott.


Keine Ahnung, wie WinCC das macht. Generell kann es auch nicht mehr. Die Begrenzung auf
PDU-Länge- 18 bytes pro Lesezufriff ist S7-spezifisch, da kann auch WinCC nicht anders.
Oder zeichne mal den Datenaustauch von WinCC mit Ethereal auf. Natürlich diie vollständigen Pakete.


> Mit den eigenen Routinen ist das eher Zeitlupe... Mache ich was falsch, oder ist das Protokollbedingt ??


Was sagt der Benchmrk (testISO_TCP -b)?
Zu deinen Blocklängen: Wie groß ist die PDU-Länge mit deinem CP?
testISO_TCP -d zeigt das an:
** Partner offered PDU length
und dann 240 oder 480.
Die solltest du auch ausnutzen.


----------



## Lazarus™ (15 Oktober 2005)

Nochmal ich  :twisted: 

Ist es möglich in deiner Lib parallel zu Read,Write, OpenSock... eine Timeoutgeschichte zu machen ???  Also ich meine wenn abgelaufen, Abbruch und die Funktion kommt mit einem Fehler zurück ???

Also ich meine ein Timeout auf dem Untersten Level vom Protokoll...

Nur so eine Idee,weiss  garnicht ob das ginge...

Also bei mir zumindest, kommt bei einem Read nie mehr ne Antwort. Ich habe schon Stunde gewartet über Nacht. Bix. Kommt nie wieder zurück.
Ich denke es liegt an Windows...

Übrigens die 0.8 funzt auch gut, die Unit ist ok unter Delphi. Und die Komponente funktioniert auch...


----------



## Zottel (16 Oktober 2005)

Lazarus™ schrieb:
			
		

> Ist es möglich in deiner Lib parallel zu Read,Write, OpenSock... eine Timeoutgeschichte zu machen ???


Paraleel würde, wenn ich es richtig verstehe, darauf hinauslaufen, parallele threads zu starten, einer wartet auf recv(), der andere zählt die Zeit und killt den ersten, wenn's zu lange dauert. Nein, das werde ich nicht tun. Erstens müßte ich mir die ganze threading-Sache von Windows reintun, zweitens würde es die Bibliothek ziemlich verkomplizieren. Das kann man sicher auf Anwender-Ebene genauso machen: einer wartet auf daveReadBytes(), der andere zählt die Zeit und killt den ersten, wenn's zu lange dauert.


> Also ich meine ein Timeout auf dem Untersten Level vom Protokoll...
> Nur so eine Idee,weiss  garnicht ob das ginge...


Ich hatte das oben dargestellte Ergebnis meiner Versuche so verstnaden, daß es durchaus ein timeout für recv auf Windows-Ebene gibt. Mein Programm (unter Win2000, nur die CP-Simulation lief unter Linux) kam ja zurück.
Nur diese Zeit ist (unter Windows) nicht mit daveSetTimeout beeinflußbar (was anders sein sollte).
Welche Windows-Version benutzt du?
Die andere Frage ist, ob ein realer CP irgendetwas (beim Aufbau der TCP/IP-Verbindung) übermittelet, was Windows veranlaßt "ewig" zu warten.


> Übrigens die 0.8 funzt auch gut, die Unit ist ok unter Delphi. Und die Komponente funktioniert auch...


Gut zu hören.


----------



## Lazarus™ (16 Oktober 2005)

Also im Moment XPSP2, habe noch nicht getestet, ob es unter Win2K oder so anders aussieht. Das werde ich mal machen...

Hast recht, ich kann meinen Thread ja auch überwachen *an Kopf klatsch*,
also manchmal sieht man den Wald vor lauter Bäumen garnich...


----------

