ENGLISH VERSION |
|
Links | | | Forum | | | Kommentare | | | News melden |
Chat | | | Umfragen | | | Newsticker | | | Archiv |
amiga-news.de Forum > Programmierung > Http Post Request | [ - Suche - Neue Beiträge - Registrieren - Login - ] |
1 2 -3- 4 | [ - Beitrag schreiben - ] |
01.05.2008, 11:31 Uhr MaikG Posts: 5172 Nutzer |
Ich hab das mit dem waitselect prinzip mal auf msg_peek adaptiert: code:t!=TIMER:laenge&=0 WHILE TIMER-t!<5 puffer&=Recv(fd&,MyMemory&+laenge&,1, MSG_PEEK%) IF puffer&>0 THEN position&=Recv(fd&,MyMemory&+laenge&,MIN(puffer&,maxlaenge&-1000), 0) laenge&=laenge&+position& ELSEIF puffer&=0 AND laenge&>0 THEN EXIT WHILE ELSE delay 1 END IF WEND Das müsste jetzt im Empfangsbereich NONBlocking sein. [ - Antworten - Zitieren - Direktlink - ] |
01.05.2008, 12:02 Uhr Holger Posts: 8116 Nutzer |
Zitat: Der Code bleibt schon hängen, wenn keine bytes ankommen. Wieso brichst Du nur dann ab, wenn laenge&>0? Ich dachte es ginge Dir gerade darum, dass Du nicht blockieren willst, bis mindestens ein byte gelesen wurde. Also nochmal: Zum Schluss: fällt Dir der Unterschied auf, wie jemand durch bloßen Anschauen Deines Code und Nachdenken substantielle Bugs findet, während Du gleichzeitig der Meinung bist, er wäre vollkommen korrekt, weil er Dir bei ein, zwei, drei oder wievielen Testläufen auch immer diesmal nicht um die Ohren gefolgen ist? mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Antworten - Zitieren - Direktlink - ] |
01.05.2008, 13:20 Uhr whose Posts: 2156 Nutzer |
Zitat: Nein. Du kannst mit select() überprüfen, ob Daten an einem Socket ankommen oder nicht. Du kannst das jederzeit und Du kannst den Test mit einem timeout versehen, so daß Du in der Lage bist, einen Socket notfalls nicht nur ein Mal zu überprüfen. Dein Code überprüft nur ein mal, ob beim ersten Versuch Daten ankamen oder nicht und dann ist Sense. Zitat: *stöhn* Wie wärs damit, die Dokumentation zu lesen, was n überhaupt für ein Wert ist?? Waitselect() ist sowas ähnliches wie Wait(), genauer: eine Kombination aus dem bsdsocket-select() (welches nur Sockets testet und ggf. bei Ablauf des timeouts zurückkehrt, mit Angaben, was an dem getesteten Socket los ist) und dem AmigaOS-Wait(), was u.A. AmigaOS-Signale testet. Damit könntest Du u.A. nachschauen, ob der Benutzer CTRL-C gedrückt hat usw. Vorschlag zur Güte: probiere erst einmal, select() zu verstehen und zu benutzen. Und dann laß endlich dieses vermaledeite MSG_PEEK in Ruhe, das brauchst Du dann nicht mehr! Sobald Du begriffen hast, wie select() funktioniert und was es macht, brauchst Du nichts anderes mehr außer einem stinknormalen recv() ohne MSG_PEEK. Das Problem mit dem ggf. blockierenden Socket erledigt select() für Dich. Zitat: Genau deswegen gibt es Dokumentation. Die solltest Du lesen. Was ein Descriptor ist, solltest Du eigentlich wissen, den hast Du bei connect() bereits benutzt. Das einzige Problem, daß ich sehe, sind die Macros, die für select() verwendet werden. Aber glaub mir, wenn Du das auseinandergepfriemelt hast, verstehst Du es auch. Also gib Dir Mühe. Und was Holger Dir unter anderem sagen will, ist: Funktionen, die Rückgabewerte liefern, tun das nicht just for fun. Die Rückgabewerte sollen Dir etwas sagen! Und bei 3 Möglichkeiten, was recv() zurückliefern kann, kann es doch nicht so schwer sein, das Programm entsprechend zu gestalten. Positive Zahl: Daten sind angekommen, nämlich genau so viel, wie die positive Zahl angibt. 0 bedeutet: Das wars, da kommt nichts mehr, mach Feierabend. Negative Zahl bedeutet: Ey, hier ist was schiefgegangen, ich hab Dir ne Nachricht hinterlassen, was genau schiefgegangen ist. Dein Problem ist, daß Du das ignorierst und Holger möchte Dich eigentlich nur davor bewahren, daß Du Dich (wie sonst auch üblich) verzettelst, weil Du mit abenteuerlichen Annahmen hantierst. Also: Hör auf ihn, bau Deinen Code entsprechend um und dann zeig ihm den. -- --- µA1 PPC 750GX-800 A4000 PPC 604e-233 [ - Antworten - Zitieren - Direktlink - ] |
01.05.2008, 14:53 Uhr Mad_Dog Posts: 1944 Nutzer |
Zitat: Deine ganzen Programmierkünste, die Du hier an den Tag legst, zeigen, daß es Dir offensichtlich an elementaren Grundkenntnissen mangelt und Du nur durch Kopieren + Raten + Wilde Spekulationen + Glück versuchst, Programme zu schreiben. Das Problem X - Daten aus dem Puffer eines Sockets lesen, der eine Datei Häpchenweise liefert - und das Problem Y - eine Textdatei zeilenweise einlesen - haben durchaus etwas miteinander zu tun, denn: - bei beiden Problemen liest man eine Datei nicht "an Stück" sondern "geschnitten" - bei beiden Problemen braucht man Schleifen, mit sinnvollen und korrekt formulierten Klauseln für die Abbruchbedingung der Schleife. - bei beiden Problemen muß man das Ende einer Datei erkennen Ich habe Dir vorgeschlagen, zur Übung ein Programm zu schreiben, welches eine Textdatei Zeilenweise einliest und am Bildschirm ausgibt, weil ich vermutet habe, daß Du - aufgrund Deiner mangelnden Kenntnisse - dabei wieder ganz ähnliche Fehler machen wirst. Aber das ist nicht weiter schlimm, denn aus Fehlern kann man ja lernen. Voraussetzung ist allerdings, daß man das, was man gesagt bekommt auch zur Kenntnis nimmt und nicht auf Durchzug schaltet. Zitat: Vermutlich Zufall. Äußerst günstige Bedingungen, bei denen eben zufällig all die Fehler, die Du in diesem kurzen Codeschnipsel geschafft hast einzubauen, nicht zum tragen gekommen sind. Höchstwahrscheinlich haben dabei die Eingabedaten die entscheidende Rolle gespielt - die werden höchstwahrscheinlich gerade mal so groß gewesen sein, daß sie im ganzen in den Puffer des Sockets gepasst haben. Zitat: Das ist nicht besser, sondern genauso Quatsch wie der andere Codeschnipsel. Zitat: Genau. Im Land der Spätzlefresser haben wir ein Sprichwort: "Wenn dr Bauer et schwemma koa, ischt Badhos schuld." Auf Hochdeutsch übersetzt: "Wenn der Bauer nicht schwimmen kann, ist die Badehose schuld." Du schaffst es nicht mal - wie ich vorgeschlagen habe - zur Übung eine Textdatei zeilenweise einzulesen und am Bildschirm auszugeben. Und wer oder was ist Schuld, wenn Du an einer solch einfachen Aufgabe kläglich scheiterst? Natürlich nicht Deine mangelhaften Grundkenntnisse, sondern - wie ich schon einige Posts vorher prophezeit habe - die unzuverlässigen magnetischen Datenträger. -- http://www.norman-interactive.com [ Dieser Beitrag wurde von Mad_Dog am 01.05.2008 um 15:18 Uhr geändert. ] [ - Antworten - Zitieren - Direktlink - ] |
01.05.2008, 18:06 Uhr MaikG Posts: 5172 Nutzer |
>Der Code bleibt schon hängen, wenn keine bytes ankommen. Nein, der Code kehrt spätestens nach 5 sekunden zurück, egal was passiert. >o Wenn der Rückgabewert von recv (mit MSG_PEEK) 0 ist, kann das >heißen, das die Datei zu Ende ist, aber auch, dass keine Daten >gelesen wurden, Das findest Du aber definitiv nicht dadurch raus, >dass Du die bisher gelsene byte-Zahl mit 0 vergleichst. >Eine Datei kann die Länge 0 haben, und eine Verbindung kann auch >dann langsamer werden, wenn Du schon ein byte gelesen hast, >ohne dass die Datei schon zu Ende ist. Ja, stimmt. >o recv, sowohl mit als auch ohne MSG_PEEK kann -1 zurückliefern, >wenn ein Fehler aufgetreten ist. Dein Code wartet dann bis in alle >Ewigkeit. 5 sek, -1 könnte man noch mit einbauen. > o Buffer Overflow. Sagt Dir das was? Ja. >Zum Schluss: fällt Dir der Unterschied auf, wie jemand durch bloßen >Anschauen Deines Code und Nachdenken substantielle Bugs findet, >während Du gleichzeitig der Meinung bist, er wäre vollkommen korrekt, >weil er Dir bei ein, zwei, drei oder wievielen Testläufen auch immer >diesmal nicht um die Ohren gefolgen ist? Ist halt neu für mich das bsd zeugs. >Nein. Du kannst mit select() überprüfen, ob Daten an einem Socket >ankommen oder nicht. Und was hält WaitSelect vom Buffer Overlow ab? >Du kannst das jederzeit und Du kannst den Test mit einem timeout >versehen, so daß Du in der Lage bist, einen Socket notfalls nicht >nur ein Mal zu überprüfen. Dein Code überprüft nur ein mal, >ob beim ersten Versuch Daten ankamen oder nicht und dann ist Sense. Der Code prüft so lang bis 5 Sekunden um sind. >Vorschlag zur Güte: probiere erst einmal, select() zu verstehen >und zu benutzen. Und dann laß endlich dieses vermaledeite MSG_PEEK >in Ruhe, das brauchst Du dann nicht mehr! Das schlimme dafür müsste man es halt verstehen... >Vermutlich Zufall. Äußerst günstige Bedingungen, bei denen eben >zufällig all die Fehler, die Du in diesem kurzen Codeschnipsel >geschafft hast einzubauen, nicht zum tragen gekommen sind. >Höchstwahrscheinlich haben dabei die Eingabedaten die entscheidende >Rolle gespielt - die werden höchstwahrscheinlich gerade mal so groß >gewesen sein, daß sie im ganzen in den Puffer des Sockets gepasst >haben. Lag vielleicht am Analog Modem... [ - Antworten - Zitieren - Direktlink - ] |
02.05.2008, 09:36 Uhr Holger Posts: 8116 Nutzer |
Zitat:Vermutlich die Tatsache, dass es gar nicht in irgendeinen Buffer schreibt. Setz Dich endlich mal hin, und überlege, was Dein Programm macht, und berücksichtige alle Situationen, die auftreten können. So viele sind es ja gar nicht. Du übergibst eine Speicheradresse und eine Länge an recv, wenigstens diese zwei Parameter solltest Du verstanden haben. Und jetzt guck Dir Deinen Code an. mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Antworten - Zitieren - Direktlink - ] |
02.05.2008, 09:49 Uhr MaikG Posts: 5172 Nutzer |
>Vermutlich die Tatsache, dass es gar nicht in irgendeinen Buffer >schreibt. Also hält es praktisch den eingehenden Datenstrom auf, bzw. lässt ihn erst bei einer Recv Operation zu? >Setz Dich endlich mal hin, und überlege, was Dein Programm macht, >und berücksichtige alle Situationen, die auftreten können. So viele >sind es ja gar nicht. Wenn ich eine ruhige Minute habe druck ich mir Waitselect aus, ist immer besser wenn ich es auf dem Papier ansehe. >Du übergibst eine Speicheradresse und eine Länge an recv, wenigstens >diese zwei Parameter solltest Du verstanden haben. Und jetzt guck >Dir Deinen Code an. Ja, die Parameter habe ich verstanden. Ich weiss auch das der Code bei Negativen Rückgabewerten nicht korrekt funktioniert. [ - Antworten - Zitieren - Direktlink - ] |
02.05.2008, 10:35 Uhr Holger Posts: 8116 Nutzer |
Zitat:Du hast es immer noch nicht begriffen. [ - Antworten - Zitieren - Direktlink - ] |
02.05.2008, 11:58 Uhr MaikG Posts: 5172 Nutzer |
Dann sprich doch nicht in Rätzeln, dann weiss ich evtl. was du meinst. Okay, select sieht auf den Papier auch nicht viel einfacher aus. n= WaitSelect( fd&, ?, NULL, NULL, 60, NULL) könnte es sein. ? - Weiss ich nicht was das ist und wo es herkommen soll. [ - Antworten - Zitieren - Direktlink - ] |
02.05.2008, 12:48 Uhr Mad_Dog Posts: 1944 Nutzer |
Zitat: BUFFER OVERFLOW BUFFER OVERFLOW BUFFER OVERFLOW Du hast geschrieben, Du wüsstest was das ist. In Deinem Programmcode kann ein BUFFER OVERFLOW auftretem, wenn die zu empfangende Datei größer, als Dein Puffer ist. Wenn Du weißt, was ein BUFFER OVERFLOW ist, müsste Dir das eigentlich klar sein. Wenn Du nicht weißt was das ist. dann frage und schreib nicht wieder, Du wüsstest es. -- http://www.norman-interactive.com [ - Antworten - Zitieren - Direktlink - ] |
02.05.2008, 13:52 Uhr MaikG Posts: 5172 Nutzer |
>BUFFER OVERFLOW >Du hast geschrieben, Du wüsstest was das ist. Ja, ein Puffer überlauf. Die Daten kommen schneller als erwartet und der Puffer ist voll und kann keine neuen Daten aufnehmen. >In Deinem Programmcode kann ein BUFFER OVERFLOW auftretem, wenn >die zu empfangende Datei größer, als Dein Puffer ist. Meiner oder der von bsd? Meiner ist 12 mal so groß wie die größte Datei die kommen kann. Das mit MIN() ist nur so zur sicherheit. >Wenn Du weißt, was ein BUFFER OVERFLOW ist, müsste Dir das >eigentlich klar sein. Wenn Du nicht weißt was das ist. dann >frage und schreib nicht wieder, Du wüsstest es. Ich wusste nicht worauf er sich bezieht. [ - Antworten - Zitieren - Direktlink - ] |
02.05.2008, 14:14 Uhr Mad_Dog Posts: 1944 Nutzer |
Zitat: Thema verfehlt 6 setzen! Unter einem Buffer Overflow versteht man, wenn man einen Speicherbereich der Größe X hat, also z.B. ein Array mit X Elementen und dann X+Y (Y>0) Elemente dort reinschreiben will. Was passiert dann? Dann wird einfach in einen Speicherbereich geschrieben, wo möglicherweise schon andere Daten liegen, die dann einfach überschrieben werden. Siehe auch http://de.wikipedia.org/wiki/Puffer%C3%BCberlauf Was Du in Deinem Prgramm machst: Du kopierst ständig die Daten aus dem Puffer Deines Sockets in Deinen eigenen Puffer, ohne jedoch zu prüfen, ob Du über du über diesen Bereich hinausschreibst. Das kannst Du Dir in etwa so vorstellen, wie bei einem Überweisungsformular von der Bank: Dort sind für die jeweiligen Felder (die Arrays) nur eine gewisse Anzahl von Kästchen (entspricht den Bytes) vorgegeben. Wenn Du nun einen Text eintragen möchtest, der länger ist, schreibst Du eben darüber hinaus, was aber so nicht vorgesehen ist. -- http://www.norman-interactive.com [ Dieser Beitrag wurde von Mad_Dog am 02.05.2008 um 14:30 Uhr geändert. ] [ - Antworten - Zitieren - Direktlink - ] |
02.05.2008, 14:22 Uhr Mad_Dog Posts: 1944 Nutzer |
Zitat: Das ist ebenfalls Quatsch. Woher willst Du denn wissen, wie groß "die größte Datei, die ankommen kann" sein wird? Das kannst Du garnicht wissen. Die Datei landet stückchenweise in dem Puffer des Sockets. Von dort kopierst Du diese Stückchen in Deinen eigenen Puffer, um die Datei wieder zusammenzusetzen. Aber Du prüfst nicht, ob Du dabei über die Grenzen dieses Puffers hinausschreibst. -- http://www.norman-interactive.com [ - Antworten - Zitieren - Direktlink - ] |
02.05.2008, 14:41 Uhr MaikG Posts: 5172 Nutzer |
>Was Du in Deinem Prgramm machst: Du kopierst ständig die Daten aus >dem Puffer Deines Sockets in Deinen eigenen Puffer, ohne jedoch zu >prüfen, ob Du über du über diesen Bereich hinausschreibst. Ah, meine Sicherheitsprüfung ist mist. Für den alten fall war sie okay, für diesen ist sie falsch. Verstehe. >Das ist ebenfalls Quatsch. Woher willst Du denn wissen, wie >groß "die größte Datei, die ankommen kann" sein wird? Anhand der Firmwareversion des Gerätes. Normalerweise aber nicht, das ist schon richtig. code:t!=TIMER:laenge&=0 WHILE TIMER-t!<5 puffer&=Recv(fd&,MyMemory&+laenge&,1, MSG_PEEK%) IF puffer&>0 THEN IF laenge&+puffer&>maxlaenge& THEN EXIT WHILE position&=Recv(fd&,MyMemory&+laenge&,puffer&, 0) laenge&=laenge&+position& ELSEIF puffer&=0 AND laenge&>0 THEN EXIT WHILE ELSE delay 1 END IF WEND [ Dieser Beitrag wurde von MaikG am 02.05.2008 um 14:44 Uhr geändert. ] [ - Antworten - Zitieren - Direktlink - ] |
02.05.2008, 15:34 Uhr Holger Posts: 8116 Nutzer |
Zitat:Du bist der erste, der hier wieder mit einem Problem kommt, weil ein via copy&paste verwendetes Stück Code nicht funktioniert, obwohl es scheinbar in einem anderen Programm funktioniert. Brauchst nur in diesem Thread zu suchen... mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Antworten - Zitieren - Direktlink - ] |
02.05.2008, 16:08 Uhr MaikG Posts: 5172 Nutzer |
>Du bist der erste, der hier wieder mit einem Problem kommt, >weil ein via copy&paste verwendetes Stück Code nicht funktioniert, >obwohl es scheinbar in einem anderen Programm funktioniert. >Brauchst nur in diesem Thread zu suchen... Ist auch erst das 2.mal das ich den verwende. Das 1.mal war es auf MSG_PEEK ausgelegt, daher wars ausreichend die Maximal zu lesendem Bytes zu begrenze. Da gab es keine veränderung der Pufferbeginns. Ist in dem sinne ja kein Copy&Paste, weil die Function verändert wurde. [ - Antworten - Zitieren - Direktlink - ] |
02.05.2008, 16:11 Uhr whose Posts: 2156 Nutzer |
@MaikG: Wir tasten uns langsam weiter vor... ok, select() ist Dir zu kompliziert, hab verstanden, lassen wirs halt. Tu mir nur einen Gefallen und jammere nicht, wenn die Klamotte irgendwann trotzdem mal hängenbleibt, weil weitere Daten nach ein paar anfänglichen Bytes ausbleiben... Ich hab Dir gesagt, was Dein Code tut, und das er das nur ein Mal tut, nämlich ganz zu Anfang, und daß das in einem für Dich ungünstigen Fall nicht ausreichend sein wird. Denk einfach dran, daß Du den Code eines schönen Tages vielleicht in ein anderes Projekt reindengelst und Dich dann nicht wundern willst, weshalb es mittendrin hängenleibt. Jetzt gibts aber vor allem erst einmal 2 Sachen, die Du auf jeden noch zu erledigen hast, damit Holger zumindest wieder etwas gelassener tippen kann: 1. Der Fall n = recv()... mit n = -1 2. Der Fall, daß die Datei (wider Erwarten) größer wird, als Dein Puffer derzeit ist (buffer overflow). Dein Abbruch tut zwar seinen Dienst, aber machs Dir nicht immer ganz so einfach. Du hast ganz am Anfang gesagt, Du wolltest lernen... dann tus auch! Wenn Du den Sinn dieser "Erweiterung" der Aufgabe nicht erfassen solltest: Wenn der Code dann auch in dieser Situation fehlerfrei funktioniert, kannst Du ihn in anderen Programmen problemlos verwenden um Dateien via http zu lesen, auch wenn Dir deren Größe nicht im Voraus bekannt ist. Noch dazu kanns Dir helfen zu verstehen, wie buffered I/O funktioniert (was ja nicht nur bei Netzwerkzugriffen von Nutzen sein kann). Komm nicht wieder mit "in der Firmwareversion kann die Datei gar nicht größer sein, weil blablabla...", mach einfach. Zeig uns ein Mal, daß Du verstanden hast, was Holger Dir seit ner kleinen Ewigkeit näherbringen will: sauberes Programmieren inkl. guter Fehlerbehandlung und wenigstens einer kleinen Prise Vorausdenken. -- --- µA1 PPC 750GX-800 A4000 PPC 604e-233 [ - Antworten - Zitieren - Direktlink - ] |
02.05.2008, 17:47 Uhr MaikG Posts: 5172 Nutzer |
>ok, select() ist Dir zu kompliziert, hab verstanden, >lassen wirs halt. Wenn mir jemand halt in in Deutsch sagen würde was der 2. Parameter ist wäre das wohl nicht so kompliziert. >Tu mir nur einen Gefallen und jammere nicht, wenn die Klamotte >irgendwann trotzdem mal hängenbleibt, weil weitere Daten nach >ein paar anfänglichen Bytes ausbleiben... Wenn Recv/NULL nur jeweils die Anzahl Daten aus dem Puffer holt die Recv/Peek als vorhanden angibt? >1. Der Fall n = recv()... mit n = -1 Indirekt müsste das berücksichtigt sein. Wenn -1 zurückkommen sollte, beginnt die Schleife von vorn bis 5 sek um sind. Weiss ich nicht wie sich das verhält, wenn -1 zurückkommt könnte es theroretisch beim nächsten mal klappen. Ansonsten könnte man in dem Fall gleich rausgehen. >2. Der Fall, daß die Datei (wider Erwarten) größer wird, als >Dein Puffer derzeit ist (buffer overflow). Dann müsste ich einen weiteren Puffer anlegen, was aber einen erheblicher mehraufwand wäre. Denn wenn sich der html Inhalt grundlegend ändert funktioniert der Rest des Programmes ohnehin nicht mehr. Wenn ich irgendwann mal beliebig große htmls benutzen will werde ich das entsprechend anpassen. [ - Antworten - Zitieren - Direktlink - ] |
02.05.2008, 20:50 Uhr whose Posts: 2156 Nutzer |
Zitat: Ok, ich übersetze Dir den Part entweder heute Abend oder morgen. Zitat: Du verstehst noch nicht so ganz: Dein aktueller Code überprüft nur ein einziges Mal, direkt am Anfang, ob überhaupt etwas angekommen ist. Jetzt nimm mal an, es wären 3 Bytes angekommen und nach diesen 3 Bytes stockt die Verbindung auf einmal... was passiert wohl? Hängen im Schacht! Das war das, was Holger Dir erklären wollte: Du hast zu Beginn gesagt, daß Dir der timeout im blocking mode zu lang ist bzw. recv() erst zurückkehrte, wenn mindestens ein Byte gelesen wurde. Jetzt forderst Du alle Daten auf einmal an und riskierst, daß es unter ungünstigen Umständen gleich zwei Mal hängt. Die TIMER-Geschichte davor nützt Dir da herzlich wenig dagegen, daß die Verbindung u.U. nicht sofort alle Daten liefert. Zitat: In der Dokumentation steht, unter welchen Umständen -1 zurückkommen kann... Zitat: Eigentlich nicht. Doppelt verkettete Listen sind Deine Freunde... Zitat: Genau vor dieser Aussage hatte ich Angst... wetten, daß Du Dich dann nicht mehr an diesen Thread erinnern wirst? Tu es jetzt, dann hast Du für laaaange Zeit ein ziemlich universell einsetzbares Teilprogramm, mit dem Du, ohne viel Grübeln, wie was funktioniert, arbeiten kannst. -- --- µA1 PPC 750GX-800 A4000 PPC 604e-233 [ - Antworten - Zitieren - Direktlink - ] |
02.05.2008, 23:05 Uhr MaikG Posts: 5172 Nutzer |
>Ok, ich übersetze Dir den Part entweder heute Abend oder morgen. Cool. >Du verstehst noch nicht so ganz: Dein aktueller Code überprüft nur >ein einziges Mal, direkt am Anfang, ob überhaupt etwas angekommen >ist. Jetzt nimm mal an, es wären 3 Bytes angekommen und nach diesen >3 Bytes stockt die Verbindung auf einmal... >was passiert wohl? Also "hängen" tut da dann nichts. Peek wird immer wieder angefahren. Das was passieren könnte ist in dem fall das peek 0 liefert weil die Verbindung stockt und die schleife daraufhin verlassen wird. Also unvollständige Daten. Müsste ich jetzt noch ein mini Timeout einbauen. >In der Dokumentation steht, unter welchen Umständen -1 zurückkommen >kann... Hab ich gelesen. In diesem Fall (blocking mode, übergabe parameter werden geprüft) kommt da eigentlich keiner in frage. >Eigentlich nicht. Doppelt verkettete Listen sind Deine Freunde... Kein schimmer was das wieder ist. >Genau vor dieser Aussage hatte ich Angst... wetten, daß Du Dich >dann nicht mehr an diesen Thread erinnern wirst? Das macht nichts, ich speichere den ab. Ausserdem stehen bemerkungen in der History. >Tu es jetzt, dann hast Du für laaaange Zeit ein ziemlich universell >einsetzbares Teilprogramm, mit dem Du, ohne viel Grübeln, wie was >funktioniert, arbeiten kannst. Du verwendest entweder andere Technik, als ich im sinn habe oder glaubst der Rest des Programms wäre nur 1000 Zeilen lang... Der Analyse teil braucht z.B. einen Linearen Puffer. Also müsste man höchstens einen 2.(3...) Puffer beim Überlauf anfordern und die am Ende in einem neuen der groß genug ist umkopieren. Andere Methoden wärend des Empfangs wären zu komplex und würden zum BSD-Pufferüberlauf führen. (Basic ist unter umständen langsamer als C) [ - Antworten - Zitieren - Direktlink - ] |
03.05.2008, 17:38 Uhr Mad_Dog Posts: 1944 Nutzer |
Zitat: Das hat Holger Dir ein paar Posts vorher schonmal versucht, zu erklären: Zitat: Zitat: Das ist wieder was, wo zu den Grundlagen gehört. In meinem C-Kurs habe ich eine Lektion gebracht, die einfach verkettete Listen erläutert: http://w3.norman-interactive.com/C-Kurs_9_1.html Weitere Infos findest Du in jedem einführenden Buch zur Informatik oder auch im Internet, z.B. bei Wikipedia: http://de.wikipedia.org/wiki/Liste_%28Datenstruktur%29 Zitat: Von der Idee geht das schonmal in die richtige Richtung. Wenn Du Dich mal mit dem Thema verkettete Listen auseinandergesetzt hast, wird Dir hoffentlich ein Licht aufgehen. Zitat: Wenn das eigene Wissen nicht reicht, die Flinte in's Korn werfen. Was ist denn das für eine Einstellung? Seh es doch als Chance, Deine eigenen Fähigkeiten zu erweitern, indem Du Dir das notwendige Wissen aneignest. Ohne Fleiß kein Preis... Zitat: Du hast noch immer nicht verstanden, was man unter einem Pufferüberlauf versteht. Schade. -- http://www.norman-interactive.com [ - Antworten - Zitieren - Direktlink - ] |
03.05.2008, 17:48 Uhr MaikG Posts: 5172 Nutzer |
>Das hat Holger Dir ein paar Posts vorher schonmal versucht, >zu erklären: Das habe ich gelesen. Die Fehler die im Doc beschrieben sind, scheinen im vorliegenden Fall nicht(unter keinen umständen) auftreten zu können. Wenn ich das richtig verstanden habe. Die meinsten fehler beziehen sich auf falsche Parameter und die anderen auf den Nonblocking Modus. >Das ist wieder was, wo zu den Grundlagen gehört. >In meinem C-Kurs habe ich eine Lektion gebracht, die einfach >verkettete Listen erläutert: Nodes, ja kenn ich vom Listview. Trotzdem alles andere als Leicht zu implementieren und erheblicher Rechenaufwand. >>Zitat: >> und würden zum BSD-Pufferüberlauf führen. >Du hast noch immer nicht verstanden, was man unter einem >Pufferüberlauf versteht. Schade. Ich weiss was ich darunter verstehe und das meine ich auch. Nehmen wir einen Wassertonne, in die kontinuierlich Wasser reinläuft. Wenn ich nicht immer mit der Gießkanne Wasser abnehme läuft diese Über. [ - Antworten - Zitieren - Direktlink - ] |
03.05.2008, 18:24 Uhr Mad_Dog Posts: 1944 Nutzer |
Zitat: Was, wenn z.B. während der Übertragung der Datei (also innerhalb Deiner Schleife) plötzlich die Verbindung abreißt? Dann schlägt recv() fehl und gibt Dir den Wert -1 zurück, um Dir das mitzuteilen. Zitat: Der Rechenaufwand ist relativ gering. Das einzige was ist: Man muß eben mit einem gewissen Overhead leben, da für jeden Knoten auch ein Zeiger auf dessen Nachfolger (und bei doppelt verketteten Listen zusätzlich auf dessen Vorgänger) im Speicher gehalten muß. Zitat: O.k. ich hätte wohl korrekterweise schreiben müssen: Was man in der Informatik unter einem Pufferüberlauf versteht. Aber von der Analogie her passt das Beispiel mit dem Bank-Überweisungsformular eben doch besser. Also auf ein neues: Pufferüberlauf (Buffer Overflow) für Dummies: Nehmen wir an, Du hättest ein Array fester Größe definiert, welches, sagen wir für 8 Elemente Platz bietet: code:[ ][ ][ ][ ][ ][ ][ ][ ] Das soll die 8 Elemente Deines Arrays ("Kästchen im Formular") darstellen. Jetzt willst Du den String "Hallo!" dort eintragen: code:[H][a][l][l][o][!][ ][ ] O.k. passt! Du hast sogar noch 2 Elemente frei ("2 Kästchen"). Was passiert aber, wenn Du den String "Hallo Welt!" eintragen möchtest? code:[H][a][l][l][o][ ][W][e] l t ! Ups! Wir haben über die Grenzen des Arrays ("die vorgegebenen Kästchen im Formular") hinausgeschrieben. Die Zeichen "l", "t" und "!" werden in einen Speicherbereich geschrieben, der nicht zu unserem Array gehört. Da auch ein Amiga ein klassischer von Neumann Rechner ist, können sich aber in dem Speicherbereich, wo wir unsere Zeichen "l", "t" und "!" hineingeschrieben haben, schon Daten oder gar der Programmcode dieses oder eines anderen Programms befinden. Folge: Der Inhalt dieser Speicherstellen wird durch unsere Zeichen "l", "t" und "!" überschrieben. Daß dies fatale Folgen haben kann, sollte hoffentlich ohne weitere Erleuterungen klar sein? -- http://www.norman-interactive.com [ Dieser Beitrag wurde von Mad_Dog am 03.05.2008 um 18:59 Uhr geändert. ] [ - Antworten - Zitieren - Direktlink - ] |
03.05.2008, 18:55 Uhr whose Posts: 2156 Nutzer |
@Mad_Dog: Prinzipiell hat er das mit dem Pufferüberlauf verstanden, er hat nur noch nicht realisiert, daß es uns ausschließlich um den von ihm angelegten Puffer geht und daß dieser (bis auf die Tatsache, daß er später Daten vom socket hineinkopiert bekommt) wenig bis gar nichts mit dem socket-Puffer zu tun hat. @MaikG: Mag sein, daß ich da nicht richtig liege, der absolute Held in Sachen bsdsocket bin ich nicht, aber was ich bisher an Code und Doku zu sehen bekam sagt mir, daß der socket-Puffer im "Normalbetrieb" nicht überläuft, sondern die Verbindung "stalled" (also stehenbleibt). bsdsocket.library wartet dann mit weiteren Forderungen an die Außenwelt nach neuen Daten, bis Du den socket-Puffer "geräumt" hast. Anders sieht das wohl aus, wenn Du den Socket im non-blocked mode betreibst und zusätzlich Datenblöcke haben willst, die als Vielfaches die Größe des socket-Puffers teilweise überschreiten können. Aber selbst für den Fall scheint bsdsocket gerüstet. Wichtigste Frage ist aber, bevor ich mir die Mühe mache, select() zu erklären: Willst Du überhaupt den sauberen Weg gehen? Ich habe jetzt schon wieder den Eindruck, daß Du mit aller Gewalt an Deiner gefundenen "Lösung" festhältst und keinen Millimeter mehr davon abweichst. Das Gequängel um den Fall, daß recv() -1 zurückgibt, stimmt mich da arg nachdenklich, dabei brichst Du Dir nun wirklich keinen Zacken aus der Krone, wenn Du diesen Fall sauber abfängst. Ein oder zwei IF-Klauseln mehr, ist doch eigentlich ein Klacks, oder? -- --- µA1 PPC 750GX-800 A4000 PPC 604e-233 [ - Antworten - Zitieren - Direktlink - ] |
03.05.2008, 22:05 Uhr NoImag Posts: 1050 Nutzer |
Zitat: Oh je. Wenn Du doppelt verkettete Listen für schwer zu implementieren hältst, dann solltest Du von bsdsocket lieber die Finger lassen. Nur weil etwas für Dich neu (und damit ungewohnt) ist, ist es noch lange nicht schwer. Implementier es einfach. Wenn Du es einmal wirklich benutzt hast, dann wirst Du es schätzen lernen. Tschüß [ - Antworten - Zitieren - Direktlink - ] |
04.05.2008, 00:44 Uhr Maja Posts: 15429 Nutzer |
Zitat: Jetzt nehme noch an, dieser Wassertonne gehört einem Wirt und neben der Wassertonne steht ein Weinfass. Das überlaufende Wasser läuft aus der Wassertonne in das Weinfass. Der Wein verwässert und der Wirt wird wegen Panscherrei verklagt. [ - Antworten - Zitieren - Direktlink - ] |
04.05.2008, 01:05 Uhr Mad_Dog Posts: 1944 Nutzer |
Zitat: Auch eine sehr schöne Analogie. Fehlt nurnoch daß jemand kommt und mittels Typecast das Wasser zu Wein macht, dann passt wieder alles. -- http://www.norman-interactive.com [ Dieser Beitrag wurde von Mad_Dog am 04.05.2008 um 01:07 Uhr geändert. ] [ - Antworten - Zitieren - Direktlink - ] |
04.05.2008, 01:37 Uhr Maja Posts: 15429 Nutzer |
Zitat: Der wurde vor etwas mehr als 2000 Jahren auf Wunsch des Volkes ans Kreuz genagelt. Allerdings gibt es Stimmen die behaupten, in der Zeitrechnung hätte sich ein Bug eingeschlichen. Demnach haben wir jetzt 2001 oder 2004 n.Chr. und 2008 ist ein Buffer Overflow. So, Spass gehabt. Back to Topic, please. [ - Antworten - Zitieren - Direktlink - ] |
04.05.2008, 09:52 Uhr MaikG Posts: 5172 Nutzer |
@Mad_Dog: >Prinzipiell hat er das mit dem Pufferüberlauf verstanden, er hat >nur noch nicht realisiert, daß es uns ausschließlich um den von >ihm angelegten Puffer geht und daß dieser (bis auf die Tatsache, >daß er später Daten vom socket hineinkopiert bekommt) wenig >bis gar nichts mit dem socket-Puffer zu tun hat. Genau, weil er hat jetzt eine worst case variante(bsd überlauf), die ich mit meinem code nannte zitiert. Von daher dachte ich er bezieht sich jetzt auch darauf und nicht auf meinen Puffer. >Mag sein, daß ich da nicht richtig liege, der absolute Held in >Sachen bsdsocket bin ich nicht, aber was ich bisher an Code und >Doku zu sehen bekam sagt mir, daß der socket-Puffer im >"Normalbetrieb" nicht überläuft, sondern die Verbindung >"stalled" (also stehenbleibt). bsdsocket.library wartet dann mit >weiteren Forderungen an die Außenwelt nach neuen Daten, >bis Du den socket-Puffer "geräumt" hast. Cool, dann wäre der Code okay, bis auf meinem Pufferüberlauf. >Wichtigste Frage ist aber, bevor ich mir die Mühe mache, select() >zu erklären: Willst Du überhaupt den sauberen Weg gehen? Wenn ich das verstehe, warum nicht. >Das Gequängel um den Fall, daß recv() -1 >zurückgibt, stimmt mich da arg nachdenklich, dabei brichst Du >Dir nun wirklich keinen Zacken aus der Krone, wenn Du diesen >Fall sauber abfängst. Ein oder zwei IF-Klauseln mehr, ist >doch eigentlich ein Klacks, oder? Kann ich machen. Aber ist das wirklich besser? So probiert das Programm weiter, ist das nicht evtl. besser als beim 1. Fehler abzubrechen? Beim Lesen eine Diskette macht ADos auch 5 Retrys. >Implementier es einfach. Wenn Du es einmal wirklich benutzt hast, >dann wirst Du es schätzen lernen. Ich glaube mit dem overhead würde ich den Support von langsameren Prozessoren einfach killen. Ich kanns ja mal probieren wenn ich wieder ein bisschen Zeit hab. [ - Antworten - Zitieren - Direktlink - ] |
04.05.2008, 13:46 Uhr Mad_Dog Posts: 1944 Nutzer |
Zitat: Wo ist das Problem? Du kannst, wenn Du willst auch sofort aussteigen, wenn Dir recv() -1 liefert: basic code:t!=TIMER:laenge&=0 WHILE TIMER-t!<5 puffer&=Recv(fd&,MyMemory&+laenge&,1, MSG_PEEK%) IF puffer&>0 THEN IF laenge&+puffer&>maxlaenge& THEN EXIT WHILE position&=Recv(fd&,MyMemory&+laenge&,puffer&, 0) Rem Falls recv fehlschlägt, aus der Schleife aussteigen IF position%=-1 THEN EXIT WHILE laenge&=laenge&+position& ELSEIF puffer&=0 AND laenge&>0 THEN EXIT WHILE ELSE delay 1 END IF WEND Zitat: Der Overhead, den ich angesprochen habe, bezieht sich nur auf den Speicherbedarf. Sicher, Du mußt bei derser Methode zur Laufzeit ständig Speicher beschaffen und die Knoten in die Liste einhängen. Aber der "Rechenaufwand" (es wird ja nicht wirklich etwas dabei gerechnet, sondern es finden nur ein paar Zuweisungen statt) ist zu verschmerzen. -- http://www.norman-interactive.com [ Dieser Beitrag wurde von Mad_Dog am 04.05.2008 um 13:48 Uhr geändert. ] [ - Antworten - Zitieren - Direktlink - ] |
1 2 -3- 4 | [ - Beitrag schreiben - ] |
amiga-news.de Forum > Programmierung > Http Post Request | [ - Suche - Neue Beiträge - Registrieren - Login - ] |
Impressum |
Datenschutzerklärung |
Netiquette |
Werbung |
Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten. |