Socketklasse von istream und ostream ableiten?
-
Mir ist nicht klar, was diese Methoden tun und wo ich denn die Daten sende/empfange. Zum Buch... leider nicht.
-
Der Stream kümmert sich als erstes um die Formatierung (unter Mithilfe der IO-Operatoren und Locales) und schickt die Ausgaben dann in Textform an den darunterliegenden Puffer. Dieser kann noch einen eigenen Zwischenspeicher definieren und wenn der voll ist, ruft er die Methode overflow() auf, die die Daten tatsächlich nach außen übergibt:
class outbuf : public streambuf { char out_buffer[BUFLEN]; public: //Konstruktor - setzt den internen Zwischenspeicher outbuf() { setp(out_buffer, out_buffer+BUFLEN-1); } virtual ~outbuf() { sync(); } protected: // die eigentliche Ausgabe-Funktion int flushBuffer() { int num = pptr()-pbase(); if( write(out_buffer,num)!=num ) //bzw. dein send-Aufruf return EOF pbump(-num); return num; } //overflow() - wird ausgelöst, wenn der Zwischenspeicher voll ist virtual int_type overflow(int_type c) { if(c!=EOF) { *pptr()=c; pbump(1); } if(flushBuffer()==EOF) return EOF; return c; } virtual int sync() { if(flushBuffer()==EOF) return -1; return 0; } };
(das habe ich jetzt aus dem Jossutis übernommen und bislang behandelt es nur die Ausgabe)
Die Eingabe funktioniert im Prinzip genau andersherum - der Buffer verwendet die Methode underflow(), um einen Zwischenspeicher zu füllen und liefert anschließend den Inhalt des Speichers an den Stream. Allerdings ist die Verwaltung dort ein wenig komplizierter, weil du auch mit ungetc() und ähnlichen Scherzen rechnen mußt.
-
Hier noch zwei existierende Implmenationen zum Thema:
http://socketstream.sourceforge.net/
http://members.aon.at/hstraub/linux/socket++/
-
Diese Implementierungen haben alle einen eigenen sockbuf und sockstream, wozu?
-
314159265358979 schrieb:
Diese Implementierungen haben alle einen eigenen sockbuf und sockstream, wozu?
Ich kenne die Implementierungen nicht, aber im Allgemeinen macht man das so aus dem selben Grund warum es einen std::ifstream oder std::ofstream gibt. Der sockbuf macht das eigentliche IO von einzelnen Zeichen und der sockstream ist ein std::istream (oder ein std::ostream oder beides) und nimmt lediglich den sockbuf als Member auf und stellt einen Konstruktor zur Verfügung, der dem Anwender das Leben etwas erleichtert.
Ein Beispiel findest Du hier in der Implementierung von OFStream.
Gruß
Werner
-
314159265358979 schrieb:
Ich würde gerne eine Socketklasse von std::istream und std::ostream ableiten,
314159265358979 schrieb:
Diese Implementierungen haben alle einen eigenen [...] sockstream, wozu?
Irgendwie frage ich mich nach den beiden Fragen, was du denn jetzt wirklich willst.
Den sockbuf braucht man, weil der streambuffer nunmal das Herz jeder Streamklasse ist. Die fstreams haben einen filebuf, stringstreams einen streambuf - und sockstreams einen sockbuf.Wenn du auch nicht an das oben genannte Buch rankommst, solltest du evtl. mal im Netz nach Literatur suchen, die dir erklärt, wie die Streams aufgebaut sind und arbeiten. Evtl auch mal in deinen Standard-Headern schmökern.
-
Ich möchte in meinem Programm etwas ähnlich diesem schreiben können:
int main() { std::istream input; // Kann eine File, stdin, ein Socket, etc sein std::ostream output; // same here // Tu was mit input und output }
Brauche ich dazu jetzt also auch einen sockstream oder reicht ein sockbuf?
-
314159265358979 schrieb:
Ich möchte in meinem Programm etwas ähnlich diesem schreiben können:
int main() { std::istream input; // Kann eine File, stdin, ein Socket, etc sein std::ostream output; // same here // Tu was mit input und output }
Brauche ich dazu jetzt also auch einen sockstream oder reicht ein sockbuf?
Äääh!
- hast Du meinen Beitrag nebst Link gelesen und hast Du noch Fragen dazu?
-
Gelesen. Und ich verstehe so gut wie gar nichts von dem Gedöns
-
314159265358979 schrieb:
Brauche ich dazu jetzt also auch einen sockstream oder reicht ein sockbuf?
Es reicht ein Stream-Buffer.
Die eigene Stream-Klasse bietet man meist zwecks Bequemlichkeit an, da man Stream und Stream-Buffer normalerweise gemeinsam erzeugt und entsorgt.
-
Nimm Boost.Iostreams.
Damit lassen sich sehr einfach STL-kompatible Streams schreiben.Alternativ könntest du gleich aus Boost.Asio boost::asio::ip::tcp::iostream verwenden, der exakt das macht was du möchtest.
-
Ethon schrieb:
Alternativ könntest du gleich aus Boost.Asio boost::asio::ip::tcp::iostream verwenden, der exakt das macht was du möchtest.
Danke, genau das, was ich gesucht habe
-
314159265358979 schrieb:
Danke, genau das, was ich gesucht habe
An wen ist das
jetzt gerichtet?
-
Naja, sonst wird hier auch immer direkt gesagt, dass man etwas versucht, das man anderes besser lösen könnte. Den direkten Hinweis auf die Klasse hab ich vermisst
Aber danke für die Hilfe, eigentlich gibts doch gar keinen Grund mehr, die "rohen" TCP Sockets zu verwenden, oder?
-
Naja, ich hab gefragt, da du ja schon öfters was zu Boost.Asio geschrieben hast, dich schon damit beschäftigt. Da hätte ich angenommen dass dir auch die Streams bekannt sind
Und es gibt immer Gründe eine High-Level Bibliothek nicht zu verwenden. Mit Streams fälle z.B. schonmal das "a" in "asio" weg. Oder man will keine Boost mit reinziehen - warum auch immer. Auch nimmt einem fast jede "höhere" Abstraktionsschicht diverse Möglichkeiten weg, die man hat, wenn man direkt mit den "low level" Funktionen arbeitet.