amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > bsd socket EOF? [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- 2 [ - Beitrag schreiben - ]

23.03.2009, 13:57 Uhr

MaikG
Posts: 5172
Nutzer
hi,
bsd weiss bei recv mit MSG_Waitall wann der Transfer vollständig ist.
Gibt es eine andere möglichkeit dies festzustellen?
Waitall blockt bis vollständig, daher bei Verbindungabbruch
ein Problem.
Den Inhalt der Daten kann ich nicht auswerten da der ausserhalb Norm liegt.

[ - Antworten - Zitieren - Direktlink - ]

23.03.2009, 14:35 Uhr

thomas
Posts: 7716
Nutzer
@MaikG:

Ich weiß nicht, ob das generell so ist, aber ich habe in einem meiner Programme angenommen, daß EOF erreicht ist, wenn recv einmal mit 0 Bytes zurück kommt. Danach darf man natürlich nicht nochmal recv aufrufen, sonst wartet man bis zum Sanktnimmerleinstag.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

23.03.2009, 14:54 Uhr

MaikG
Posts: 5172
Nutzer
Naja bei stabielen, schnellen Servern klappt das, aber leider nur dann.
Denn 0 kann auch heissen das der Server nicht hinterherkommt.
Bissher habe ich das mit einem Delay gemacht, aber auch wenn der
Transfer beendet ist wird 3 sek gewartet. Was Geschwindigkeitstechnisch
schlecht ist und es gibt sogar Server bei denen unterbricht der
Datenstrom viel länger, was ein zerhaktes file bedeutet.

[ - Antworten - Zitieren - Direktlink - ]

23.03.2009, 17:13 Uhr

akl
Posts: 265
Nutzer
@MaikG:
Du überprüfst auf -1 und wertest errno aus?

[ - Antworten - Zitieren - Direktlink - ]

23.03.2009, 21:25 Uhr

MaikG
Posts: 5172
Nutzer
@akl:

dann müsste ich auf nonblocking umstellen.
und errno enthält dann EOF?

[ - Antworten - Zitieren - Direktlink - ]

30.03.2009, 12:11 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
dann müsste ich auf nonblocking umstellen.
und errno enthält dann EOF?

Nein, andersrum. Wenn Dein socket non-blocking ist, dann erhälst Du den Rückgabewert -1 und die Fehlernummer EAGAIN, wenn keine Daten vorliegen, das Ende aber nicht erreicht ist. Eine Rückgabewert von 0 dagegen bedeutet immer EOF, ganz egal ob blocking oder non-blocking.

Wieso kommt mir das alles nur so bekannt vor?

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

31.03.2009, 11:24 Uhr

MaikG
Posts: 5172
Nutzer
Zitat:
Original von Holger:
Nein, andersrum. Wenn Dein socket non-blocking ist, dann erhälst Du den Rückgabewert -1 und die Fehlernummer EAGAIN, wenn keine Daten vorliegen, das Ende aber nicht erreicht ist. Eine Rückgabewert von 0 dagegen bedeutet immer EOF, ganz egal ob blocking oder non-blocking.

Wieso kommt mir das alles nur so bekannt vor?

mfg


Momentan hole ich mir den Pufferfüllstand damit nichts hängen bleibt und lese wenn <>0.
Bei recv gibts das Problem das es hängen bleibt, ggf. für immer.

[ - Antworten - Zitieren - Direktlink - ]

31.03.2009, 12:38 Uhr

thomas
Posts: 7716
Nutzer

Daß -1 auch ungleich 0 ist, aber einen Fehler bedeutet, hast du nicht verstanden ?

Und daß gleich 0 EOF bedeutet, steht jetzt fest, auch wenn du es nicht glauben willst.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

31.03.2009, 15:02 Uhr

Wishmaster
Posts: 140
Nutzer
@thomas:

Er will nicht sagen, was er programmieren will.
Möchte aber, dass du ihm fertige Programmzeilen vorgibst.
--
Pegasos MorphOS

[ - Antworten - Zitieren - Direktlink - ]

31.03.2009, 16:42 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
Bei recv gibts das Problem das es hängen bleibt, ggf. für immer.

Ja, solange Du waitall benutzt, kann das passieren. Schließlich sagst Du der Funktion damit ja auch ausdrücklich, dass sie erst zurückkehren soll, bis so viele Daten angekommen sind, wie der Puffer fassen kann. Wenn niemals so viele Daten geliefert werden, wartest der Funktionsaufruf bis in alle Ewigkeit. Aber genau darum hast Du ihn ja auch gebeten.

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

31.03.2009, 16:57 Uhr

Mad_Dog
Posts: 1944
Nutzer
Zitat:
Original von Holger:
Zitat:
Original von MaikG:
Bei recv gibts das Problem das es hängen bleibt, ggf. für immer.

Ja, solange Du waitall benutzt, kann das passieren. Schließlich sagst Du der Funktion damit ja auch ausdrücklich, dass sie erst zurückkehren soll, bis so viele Daten angekommen sind, wie der Puffer fassen kann.

Das ist immernoch die gleiche Problematik wie in dem damaligen Thread: Er versteht nicht, wie man eine Schleife programmiert, um die zerstückelte Datei Stück für Stück aus dem Puffer zu lesen und dann wieder zusammenzufügen. Deshalb versucht er den Puffer so groß zu machen, daß die Datei am Stück hineinpasst. Damals habe ich ja vorgeschlagen, er möge mal probieren, ein kleines Testprogramm zu schreiben, welches eine Textdatei ZEILENWEISE einliest, um die Problematik nachvollziehen zu können. Aber das hat er damals mit dem Hinweis "ich weiß schon, wie das geht" ausgeschlagen... Was soll man dazu noch sagen?


--
http://www.norman-interactive.com

[ - Antworten - Zitieren - Direktlink - ]

31.03.2009, 19:26 Uhr

akl
Posts: 265
Nutzer
@MaikG:
schau' mal hier:
http://svn.opengroupware.org/SOPE/trunk/sope-core/NGStreams/NGDescriptorFunctions.m

[ - Antworten - Zitieren - Direktlink - ]

31.03.2009, 22:05 Uhr

MaikG
Posts: 5172
Nutzer
>Ja, solange Du waitall benutzt, kann das passieren. Schließlich >sagst Du der Funktion damit ja auch ausdrücklich, dass sie erst >zurückkehren soll, bis so viele Daten angekommen sind, wie der >Puffer fassen kann. Wenn niemals so viele Daten geliefert werden, >wartest der Funktionsaufruf bis in alle Ewigkeit. Aber genau darum >hast Du ihn ja auch gebeten.

Alles andere ausser waitall kann leider genauso hängen bleiben.


>Das ist immernoch die gleiche Problematik wie in dem damaligen >Thread: Er versteht nicht, wie man eine Schleife programmiert, um >die zerstückelte Datei Stück für Stück aus dem Puffer zu lesen und >dann wieder zusammenzufügen. Deshalb versucht er den Puffer so groß >zu machen, daß die Datei am Stück hineinpasst. Damals habe ich ja >vorgeschlagen, er möge mal probieren, ein kleines Testprogramm zu >schreiben, welches eine Textdatei ZEILENWEISE einliest, um die >Problematik nachvollziehen zu können. Aber das hat er damals mit dem >Hinweis "ich weiß schon, wie das geht" ausgeschlagen... Was soll man >dazu noch sagen?

Das waren die ersten geh Versuche.
Danach kam MSG_PEEK gefolgt von einem normalen recv mit der
Puffer Füllstandsgröße. Da das auch Blocken kann benutze ich
jetzt ioctl um die sofort lesbaren Daten zu bekommen und dann
ein normales recv mit dem Wert.
Fazit: ende kann so nicht ermittelt werden.




Den Source hab ich mir angesehen, so mit dem Timeout hatte ich auch
schon im Sinn müsste das dann komplett auf nonblocking mode umbauen und dann wäre 0 bei recv wohl irgendwie EOF falls es zum recv kommt den select muss dafür doch 1 liefern was laut src "data waiting, try to read" bedeutet. Nur wenn daten warten warum sollte dann EOF kommen.
Ich bin verwirrt :rotate:

[ - Antworten - Zitieren - Direktlink - ]

01.04.2009, 07:51 Uhr

akl
Posts: 265
Nutzer
@MaikG:
http://www.opengroup.org/onlinepubs/009695399/functions/recv.html

Wenn Du EAGAIN, EWOULDBLOCK und ETIMEDOUT richtig auswertest, sollte das doch gehen. Die Daten kommen eben nicht unbedingt an einem Stück an, und selbst wenn - dann erhälst Du sie nicht zwangsläufig vom TCP/IP-Stack auch in einem Stück...

Natürlich kannst Du mit ioctl() das Verhalten besser determinieren, aber ich würde z.B. bei FIONREAD aus dem gleichen Grund davon ausgehen, dass es sich schlicht um die minimal am Stück lesbare Datenmenge handelt - es kann ja zwischendurch noch mehr angekommen sein.

Im Endeffekt bestimmt immer die Statemachine des Stacks, wann Du wieviel lesen kannst - und EAGAIN kann auch simuliert sein. Blocking oder nicht.

[ - Antworten - Zitieren - Direktlink - ]

01.04.2009, 09:58 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
Alles andere ausser waitall kann leider genauso hängen bleiben.

Gehen wir noch mal zurück auf das erste Posting dieses Threads:
Zitat:
Original von MaikG:
hi,
bsd weiss bei recv mit MSG_Waitall wann der Transfer vollständig ist.

Falsch.
waitall heißt, dass die Funktion so lange warten soll, bis die Menge an Daten geliefert werden kann, die Du in diesem Aufruf angefordert hast. Das heißt nicht, dass der Transfer vollständig ist, wenn die Funktion zurückkommt.
Zitat:
Gibt es eine andere möglichkeit dies festzustellen?
Es gibt nur eine Möglichkeit.
Zitat:
Waitall blockt bis vollständig, daher bei Verbindungabbruch
ein Problem.

Auch falsch, da die Funktion bei einem Abbruch selbstverständlich zurückkehrt. Natürlich erst, wenn der Abbruch bemerkt wurde, aber das entspricht ja der Anforderung, so lange zu warten, bis die angeforderte Datenmenge da ist oder definitiv nicht geliefert werden kann.

Angesichts solcher Voraussetzungen, warum sollte ich Dir da glauben, dass der Fehler nicht bei Dir liegt, wenn Dein Programm hängen bleibt? Wie es funktioniert, wurde Dir bereits mehrfach erklärt. Der Rest liegt nun bei Dir.

Zitat:
Den Source hab ich mir angesehen, so mit dem Timeout hatte ich auch
schon im Sinn müsste das dann komplett auf nonblocking mode umbauen und dann wäre 0 bei recv wohl irgendwie EOF falls es zum recv kommt den select muss dafür doch 1 liefern was laut src "data waiting, try to read" bedeutet. Nur wenn daten warten warum sollte dann EOF kommen.
Ich bin verwirrt :rotate:

Ich auch. Was willst Du damit sagen?

Zitat:
Original von akl:
Im Endeffekt bestimmt immer die Statemachine des Stacks, wann Du wieviel lesen kannst - und EAGAIN kann auch simuliert sein. Blocking oder nicht.

Na ja, bei Blocking ohne Timeout sollte EAGAIN niemals auftreten...

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

01.04.2009, 12:08 Uhr

MaikG
Posts: 5172
Nutzer
>Wenn Du EAGAIN, EWOULDBLOCK und ETIMEDOUT richtig auswertest,
>sollte das doch gehen. Die Daten kommen eben nicht unbedingt an
>einem Stück an, und selbst wenn - dann erhälst Du sie nicht
>zwangsläufig vom TCP/IP-Stack auch in einem Stück...

Ja, den müsste ich den kram auf NonBlocking umstellen.


>Natürlich kannst Du mit ioctl() das Verhalten besser determinieren,
>aber ich würde z.B. bei FIONREAD aus dem gleichen Grund davon
>ausgehen, dass es sich schlicht um die minimal am Stück lesbare
>Datenmenge handelt - es kann ja zwischendurch noch mehr angekommen
>sein.

Deswegen ist es ja in einer Scleife.

> Zitat:
> Original von MaikG:
> hi,
> bsd weiss bei recv mit MSG_Waitall wann der Transfer vollständig ist.
>Falsch.
>waitall heißt, dass die Funktion so lange warten soll, bis die Menge an Daten geliefert werden kann, die Du in diesem Aufruf angefordert hast. Das heißt nicht, dass der Transfer vollständig ist, wenn die Funktion zurückkommt.

Ist schon klar das nicht bis ins nirvana geschrieben wird.


> Zitat:
> Gibt es eine andere möglichkeit dies festzustellen?
>Es gibt nur eine Möglichkeit.
> Zitat:
> Waitall blockt bis vollständig, daher bei Verbindungabbruch
> ein Problem.
>Auch falsch, da die Funktion bei einem Abbruch selbstverständlich
>zurückkehrt. Natürlich erst, wenn der Abbruch bemerkt wurde, aber
>das entspricht ja der Anforderung, so lange zu warten, bis die
>angeforderte Datenmenge da ist oder definitiv nicht geliefert
>werden kann.


Welcher abbruch? Vom Server kommt nichts mehr, wenn ein CTRL-C
gesendet wird ja. Und was evtl. nach Minuten zurückkommt ist
mir egal, das Programm bricht eh nach 15sek ab.

Es geht um die Optimierung es vor dem Timeout zu merken ob EOF
erreicht ist.


>Angesichts solcher Voraussetzungen, warum sollte ich Dir da glauben,
>dass der Fehler nicht bei Dir liegt, wenn Dein Programm hängen
>bleibt?

Wenn du richtig gelesen hättest wüsstest du das es gar nicht hängen
bleibt.


[ - Antworten - Zitieren - Direktlink - ]

01.04.2009, 15:14 Uhr

akl
Posts: 265
Nutzer
@Holger:
>Na ja, bei Blocking ohne Timeout sollte EAGAIN niemals auftreten...

Stimmt, die Fälle wo es auftritt, sind stets sehr "speziell". Oder Bugs.
Aber auch damit muss man rechnen, insbesondere wenn der BSD-Layer vielleicht nur emuliert ist.

Quellcode oder ein paar mehr Informationen wären generell nicht schlecht...

[ - Antworten - Zitieren - Direktlink - ]

01.04.2009, 16:31 Uhr

thomas
Posts: 7716
Nutzer
@MaikG:
Zitat:
Es geht um die Optimierung es vor dem Timeout zu merken ob EOF
erreicht ist.


Warum geht das in deinen Kopf nicht rein ? EOF bemerkst du sofort, nämlich wenn recv (blocking) mit 0 zurück kommt. Oder die Übertragung ist abgebrochen, dann kommt -1 zurück. Es gibt keinen Fall, wo 0 zurück kommt und EOF nicht erreicht ist.

Wenn es bei dir hängen bleibt, dann hast du was falsch gemacht. Vermutlich hast du nach dem EOF nochmal recv aufgerufen. Das wartet dann bis zum Sanktnimmerleinstag.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

01.04.2009, 16:59 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
Wenn du richtig gelesen hättest wüsstest du das es gar nicht hängen
bleibt.

Was bitteschön ist an dieser Aussage:
Zitat:
Original von MaikG:
Alles andere ausser waitall kann leider genauso hängen bleiben.

anders zu lesen, als das bei Dir (nebenbei gesagt nur bei Dir) die Anwendung hängen bleibt?

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

01.04.2009, 18:01 Uhr

MaikG
Posts: 5172
Nutzer
>Warum geht das in deinen Kopf nicht rein ? EOF bemerkst du sofort, >nämlich wenn recv (blocking) mit 0 zurück kommt.

Ich gucke wieviel Daten vorhanden sind und starte recv ausschliesslich wenn es >0 ist. Also kann recv in dem fall auch
niemals 0 sein.


>Oder die Übertragung ist abgebrochen, dann kommt -1 zurück. Es gibt >keinen Fall, wo 0 zurück kommt und EOF nicht erreicht ist.

Ich werde das im normalen Fall nochmal prüfen.
Bei AWeb kann die übertragung genauso hängen bleiben und es bricht nicht innerhalb von 15 sekunden ab - müssten die dann auch was falsch machen.


>Wenn es bei dir hängen bleibt, dann hast du was falsch gemacht. >Vermutlich hast du nach dem EOF nochmal recv aufgerufen. Das wartet >dann bis zum Sanktnimmerleinstag.

Die Vorversion geht bei recv 0 raus und braucht keine EOF
erkennung, kann aber hängen bleiben.



>Was bitteschön ist an dieser Aussage:

> Zitat:Original von MaikG:
> Alles andere ausser waitall kann leider genauso hängen bleiben.

>anders zu lesen, als das bei Dir (nebenbei gesagt nur bei Dir) die >Anwendung hängen bleibt?

ja bleibt ggf. hängen, ist aber nicht der Fall um den es geht.
Wait_All rufe ich in einem befehl auf, mit einem großen puffer
OHNE Schleife. D.h. kann es nur an recv liegen, nicht an der auswertung oder sonstiges.

[ - Antworten - Zitieren - Direktlink - ]

01.04.2009, 18:11 Uhr

Mad_Dog
Posts: 1944
Nutzer
Zitat:
Original von thomas:

Wenn es bei dir hängen bleibt, dann hast du was falsch gemacht. Vermutlich hast du nach dem EOF nochmal recv aufgerufen. Das wartet dann bis zum Sanktnimmerleinstag.


Ohne den Code zu sehen, können wir nur Vermutungen anstellen.
Ich befürchte, er hat (wie damals) noch immer nicht begriffen, daß sich der Puffer, aus dem er lesen möchte, ähnlich wie ein Stack verhält, d.h. wenn er immer nur ein PEEK macht, danach den Puffer aber wieder neu befüllen möchte und das in einer Schleife, bei der er auf EOF prüft, wartet er in der Tat bis zum Sanktnimmerleinstag auf EOF, weil im Puffer ja immer wieder das selbe stehen wird...
Nur wenn er "Glück" hat und die Datei "zufällig" so klein ist, daß sie auf einmal in den Puffer passt, bekommt er sein EOF.

--
http://www.norman-interactive.com

[ Dieser Beitrag wurde von Mad_Dog am 01.04.2009 um 18:13 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

01.04.2009, 18:26 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
Ich gucke wieviel Daten vorhanden sind und starte recv ausschliesslich wenn es >0 ist. Also kann recv in dem fall auch
niemals 0 sein.

Du wirst Dich irgendwann einmal an den Gedanken gewöhnen müssen, dass man recv mehr als einmal aufrufen muss, um eine Übertragung vollständig durchzuführen.
Wenn Daten übertragen wurden und kein Fehler aufgetreten ist, liefert recv die Anzahl übertragener bytes zurück.
Und das so lange, bis entweder ein Fehler aufgetreten ist oder die Datei zu Ende ist.
Zitat:
Bei AWeb kann die übertragung genauso hängen bleiben und es bricht nicht innerhalb von 15 sekunden ab - müssten die dann auch was falsch machen.
Ich habe keine Ahnung, woher Du die 15 Sekunden nimmst. Niemand hier hat gesagt, dass Dir ein Timeout von 15 Sekunden garantiert wird.

Zitat:
ja bleibt ggf. hängen, ist aber nicht der Fall um den es geht.
???
Und um was für einen Fall geht es dann, wenn nicht um den, den Du beschreibst?
Zitat:
Wait_All rufe ich in einem befehl auf, mit einem großen puffer
Dann dauert es natürlich dementsprechend lange, bis der Aufruf zurückkehrt. Welchen Teil von "waitall wartet, bis die gesamte angeforderte Datenmenge gelesen wurde" hast Du nicht verstanden?

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

01.04.2009, 18:34 Uhr

MaikG
Posts: 5172
Nutzer
>Ohne den Code zu sehen, können wir nur Vermutungen anstellen.
>Ich befürchte, er hat (wie damals) noch immer nicht begriffen,
>daß sich der Puffer, aus dem er lesen möchte, ähnlich wie ein
>Stack verhält, d.h. wenn er immer nur ein PEEK macht,

Nein, das hab ich lange schon begriffen.




> Zitat:
> Original von MaikG:
> Ich gucke wieviel Daten vorhanden sind und starte recv ausschliesslich wenn es >0 ist. Also kann recv in dem fall auch
> niemals 0 sein.
>Du wirst Dich irgendwann einmal an den Gedanken gewöhnen müssen, dass man recv mehr als einmal aufrufen muss, um eine Übertragung vollständig durchzuführen.
>Wenn Daten übertragen wurden und kein Fehler aufgetreten ist, liefert recv die Anzahl übertragener bytes zurück.
>Und das so lange, bis entweder ein Fehler aufgetreten ist oder die Datei zu Ende ist.

Das weiss ich doch und mache ich auch, es läuft in einer Schleife.


> Zitat:
> Bei AWeb kann die übertragung genauso hängen bleiben und es bricht nicht innerhalb von 15 sekunden ab - müssten die dann auch was falsch machen.
>Ich habe keine Ahnung, woher Du die 15 Sekunden nimmst. Niemand hier hat gesagt, dass Dir ein Timeout von 15 Sekunden garantiert wird.

Blöd forumuliert, ich brauche ein Timeout <15 sekunden.
Das Manage ich selber, wenn recv erst später mit 0 oder -1 zurückkommt
bringt es mir leider gar nichts.


> Zitat:
> ja bleibt ggf. hängen, ist aber nicht der Fall um den es geht.
>???
>Und um was für einen Fall geht es dann, wenn nicht um den, den Du beschreibst?

Verkürzt um diesen hier:

t!=Timer
while timer-t!<15
puffer&=0
junk&=IoctlSocket(fd&,FIONREAD&,VARPTR(puffer&))

IF puffer&>0 THEN
IF laenge&+puffer&>maxlaenge& THEN EXIT WHILE
position&=Recv(fd&,MyMemory&+laenge&,puffer&, 0)
laenge&=laenge&+position&
end if
wend



> Zitat:
> Wait_All rufe ich in einem befehl auf, mit einem großen puffer
>Dann dauert es natürlich dementsprechend lange, bis der Aufruf zurückkehrt. Welchen Teil von "waitall wartet, bis die gesamte angeforderte Datenmenge gelesen wurde" hast Du nicht verstanden?

Ich hab das schon verstanden, es geht um Abgerissene Verbindungen.
Stell dir einfach vor du ziehst den Netzwerkstecker raus.


@Thomas
Ich habe jetzt ein Displaybeep und eine Ausgabe bei -1 / 0 gemacht,
0 gibt es auch wenn der Server die Daten nicht schnell genug liefert
und nicht nur bei EOF.
-1 ist überhaupt noch nicht aufgetreten.
Obwohl sowohl bei 0 als auch bei -1 die Schleife sofort verlassen
wird hängt das ganze jetzt seid 30 Minuten, soviel dazu.

[ Dieser Beitrag wurde von MaikG am 01.04.2009 um 20:56 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

02.04.2009, 10:27 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
Blöd forumuliert, ich brauche ein Timeout <15 sekunden.

Es ist die beste Formulierung deinerseits in diesem Thread, bezüglich der Frage, was Du eigentlich willst.
Wie man den timeout eines Sockets setzt, habe ich nicht im Kopf. Spontan fällt mir dazu ein:
C code:
struct timeval tval;
tval.tv_sec = 15;
tval.tv_usec = 0;
result = setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, &tval, sizeof(tval));
if(result==0) printf("timeout set to 15sn");

Kann jetzt weder sagen, ob das exakt so richtig ist oder ob bzw. wie das beim Amiga funktioniert.

timeouts im Fehlerfall sind eine problematische Sache. Deshalb benutzt man ja auch non-blocking I/O, weil man dann zwar auch nicht weiß, ob gerade in diesem Moment ein Fehler aufgetreten ist, aber trotzdem in dieser Zeit etwas anderes tun kann.
Wenn es Dir allerdings darum geht, definitiv im Falle eines Fehler spätestens nach 15 Sekunden selbigen zu bemerken, brauchst Du eine entsprechende aktive Überprüfung, wie z.B. ein parallel laufenden ping oder ähnliches. Bei der Übertragung eines Datenstreams bekommst Du so etwas nicht (innerhalb einer garantierten Zeit) mit.
Zitat:
Verkürzt um diesen hier:

t!=Timer
while timer-t!<15
puffer&=0
junk&=IoctlSocket(fd&,FIONREAD&,VARPTR(puffer&))

IF puffer&>0 THEN
IF laenge&+puffer&>maxlaenge& THEN EXIT WHILE
position&=Recv(fd&,MyMemory&+laenge&,puffer&, 0)
laenge&=laenge&+position&
end if
wend

In diesem Code kann natürlich niemals ein Fehler oder EOF festgestellt werden, da Du recv ja niemals aufrufst, wenn keine Daten vorhanden sind. Wenn Daten vorhanden sind, liefert recv natürlich eben jene Daten, und wenn keine vorhanden sind hängt sich Deine Schleife auf, da Du immer nur ioctl aufrufst und sonst nichts.

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

02.04.2009, 10:37 Uhr

MaikG
Posts: 5172
Nutzer
>Wie man den timeout eines Sockets setzt, habe ich nicht im Kopf. >Spontan fällt mir dazu ein:

> C code:

> struct timeval tval;
> tval.tv_sec = 15;
> tval.tv_usec = 0;
> result = setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, &tval, sizeof(tval));
> if(result==0) printf("timeout set to 15sn");

>Kann jetzt weder sagen, ob das exakt so richtig ist oder ob bzw. wie >das beim Amiga funktioniert.

und was ist sd?


>In diesem Code kann natürlich niemals ein Fehler oder EOF festgestellt >werden, da Du recv ja niemals aufrufst, wenn keine Daten vorhanden >sind. Wenn Daten vorhanden sind, liefert recv natürlich eben jene >Daten, und wenn keine vorhanden sind hängt sich Deine Schleife auf, da >Du immer nur ioctl aufrufst und sonst nichts.

Ja, genau das meine ich. Zwar bleibt mir der komplizierte Nonblocking kram ersparrt aber es ist ggf. langsamer. Trotzdem schneller als die Vorversion weil es ebend immer weiter geht und nie ganz aufhört.

[ - Antworten - Zitieren - Direktlink - ]

02.04.2009, 10:58 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
und was ist sd?

socket descriptor, das gleiche wie ein file descriptor für sockets ;)
Zitat:
Zwar bleibt mir der komplizierte Nonblocking kram ersparrt ...
Es bleibt Dir nicht erspart. Schließlich ist eine "Lösung", die nicht funktioniert, eben keine Lösung.

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

02.04.2009, 15:52 Uhr

DrNOP
Posts: 4118
Nutzer
Zitat:
Original von MaikG:
Wait_All rufe ich in einem befehl auf, mit einem großen puffer
OHNE Schleife. D.h. kann es nur an recv liegen, nicht an der auswertung oder sonstiges.

Zitat:
Original von MaikG:
>Wenn Daten übertragen wurden und kein Fehler aufgetreten ist, liefert recv die Anzahl übertragener bytes zurück.
>Und das so lange, bis entweder ein Fehler aufgetreten ist oder die Datei zu Ende ist.

Das weiss ich doch und mache ich auch, es läuft in einer Schleife.


Wie nun: MIT oder OHNE Schleife?
--
Signaturen mit mehr als zwei Zeilen gehen mir auf den Wecker

[ - Antworten - Zitieren - Direktlink - ]

02.04.2009, 18:32 Uhr

MaikG
Posts: 5172
Nutzer
>Wie nun: MIT oder OHNE Schleife?

Waitall ohne, alle anderen mit.

Okay, ich guck mir nonblocking nochmal an.

[ - Antworten - Zitieren - Direktlink - ]

02.04.2009, 19:36 Uhr

MaikG
Posts: 5172
Nutzer
Also ich hab jetzt folgendes:

a&=1:junk=IoctlSocket(fd&,FIONBIO&,VARPTR(a&))

puffer&=0
puffer&=Recv(fd&,MyMemory&+laenge&,100, MSG_PEEK%)
IF puffer&<0 THEN
SockErrNo&=0
SetErrnoPtr VARPTR(SockErrNo&), 4
OPEN "ram:Nonblockingtest" FOR APPEND AS 6
PRINT #6, laenge&, puffer&, SockErrNo&
CLOSE #6
Puffer&=0
END IF

Aber der fall -1 tritt gar nicht auf???

[ - Antworten - Zitieren - Direktlink - ]

03.04.2009, 10:25 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
Aber der fall -1 tritt gar nicht auf???

Warum sollte er auch?
Du benutzt immer noch MSG_PEEK, und das kann nicht blocken, als tritt der Fehler EWOULDBLOCK (was heißt das auf deutsch?) auch nicht auf.

Außerdem solltest Du mal darüber nachdenken, ob es nicht sinnvoller wäre, dem TCP/IP-Stack die Adresse für die Fehlernummer mitzuteilen, bevor ein Fehler auftritt...

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]


-1- 2 [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > bsd socket EOF? [ - Suche - Neue Beiträge - Registrieren - Login - ]


.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten.
.