Hallo,
ich möchte/muss unter C++ mit Sockets arbeiten. Das sieht jetzt so aus
und funktioniert:
1
charecho_buffer[RCVBUFSIZE];
2
intrecv_size;
3
4
recv_size=recv(sock,echo_buffer,RCVBUFSIZE,0);
5
if(recv_size<0)
6
error_exit("Fehler bei recv()");
7
8
echo_buffer[recv_size]='\0';
9
leer[recv_size]='\0';
Bei recv gibt er mir alle epfangenen Daten seit dem letzten Mal. Wenn
aber keine Daten kommen, wartet er, bis Daten kommen. Das darf nicht
sein.
Mit
1
recv_size>0//Daten sind da
wird das auch nichts.
Meine Frage:
Wie kann ich gucken, ob überhaupt in diesem Moment neue Daten verfügbar
sind, damit recv auf gar keinen Fall wartet?
Auf Linux "man recv" tippen oder ein Buch lesen?
Man kann den Socket Non-Blocking machen (mit fcntl) oder (üblicher) mit
select abfragen, ob Daten anliegen.
Ich würde zum Erlernen der Socket-Programmierung das Buch Unix Network
Programming von Ruchard W. Stevens empfehlen. Es enthält sehr gut
dokumentierte Beispiele in C.
Danke für die Antworten!!!
Select scheint schonmal das richtige zu sein. Bisher suche ich noch nach
einer Möglichkeit select() zu benutzen.
Hat da jemand einen Gedankenanstoß?
Der ist falsch. Wie es richtig geht steht in der man-Page, zu der ich
Dir den Link gegeben habe. Passt ja schon allein mit den Datentypen
nicht.
Ein Tipp: Im Link fragen sie Eingaben vom Keyboard ab (entspricht etwa
einem Socket mit dem Wert 0).
Für den Rest: Tutorials sind dein Freund.
CC schrieb:> Ah, es macht auch wenig sinn, recv() VOR select() aufzurufen.> Letzteres> teilt nämlich mit, ob recv() blockieren wird oder nicht.
Mir fehlt der erste Parameter von select() Das ist das große Problem.
c++ schrieb:> #include <stdio.h>
In C++ heißt diese Datei <cstdio>
> #include <stdlib.h>
und die <cstdlib>
> #include <string.h>
und die <cstring>
> #include <errno.h>
und die <cerrno>
> #include <string.h>
und die <cstring> - hoppla, die haben wir ja schon includet
> #include <cstring>
Uund gleich noch einmal includen.
c++ schrieb:> #define RCVBUFSIZE 8192
In C++ muss man sich keiner Textersetzung bedienen, sondern kann echte
Konstanten verwenden um die diversen Makro-Probleme zu vermeiden:
Warum eigentlich überhaupt select()? Das ergibt doch hier überhaupt
keinen Sinn. Das Haupt-Ziel von select() ist es, sich um mehrere fds
gleichzeitig zu kümmern. Die gibt es hier aber gar nicht.
Es reicht, einfach den Socket non-blocking zu machen. Dann kehrt recv()
immer ohne Wartezeit zurück, und wenn keine Daten verfügbar sind,
liefert es -1 zurück, und errno wird auf den Wert EAGAIN gesetzt.
Dr. Sommer schrieb:> In C++ muss man sich keiner Textersetzung bedienen, sondern kann echte> Konstanten verwenden um die diversen Makro-Probleme zu vermeiden:> const size_t RCVBUFSIZE = 8192;
Dann aber bitte auch nicht komplett groß scheiben, da das eigentlich das
Erkennungszeichen für Makros ist.
c++ schrieb:> Mir fehlt der erste Parameter von select() Das ist das große Problem.
Das große Problem ist eher, daß du noch gar nicht verstanden hast, was
select() überhaupt tut.
Rolf Magnus schrieb:> Es reicht, einfach den Socket non-blocking zu machen. Dann kehrt recv()> immer ohne Wartezeit zurück, und wenn keine Daten verfügbar sind,> liefert es -1 zurück,
Genau das will ich!!! Hast da jemand einen Ansatz?
c++ schrieb:> Rolf Magnus schrieb:>> Es reicht, einfach den Socket non-blocking zu machen. Dann kehrt recv()>> immer ohne Wartezeit zurück, und wenn keine Daten verfügbar sind,>> liefert es -1 zurück,>> Genau das will ich!!! Hast da jemand einen Ansatz?
Ich hab sogar mehrere:
- man-Page lesen
- Ein Buch lesen
- Nach dem Thema googeln
- falls das Lesen von Doku untragbar ist: umsatteln auf Briefmarken
sammeln
Rolf Magnus schrieb:> c++ schrieb:>> Rolf Magnus schrieb:>>> Es reicht, einfach den Socket non-blocking zu machen. Dann kehrt recv()>>> immer ohne Wartezeit zurück, und wenn keine Daten verfügbar sind,>>> liefert es -1 zurück,>>>> Genau das will ich!!! Hast da jemand einen Ansatz?>> Ich hab sogar mehrere:>> - man-Page lesen> - Ein Buch lesen> - Nach dem Thema googeln> - falls das Lesen von Doku untragbar ist: umsatteln auf Briefmarken> sammeln
Danke! Ich hasse nur leider Sockets in C++ und brauche diese für EIN
Projekt. Und dieser ganze FD-Mist entsprach nicht im Ansatz dem, was ich
gebraucht habe. Nach langer Suche ohne FD hab ich nun
1
fcntl(sock,F_SETFL,O_NONBLOCK)
gefunden, was mein Problem löst.
Rolf Magnus schrieb:> Dann aber bitte auch nicht komplett groß scheiben, da das eigentlich das> Erkennungszeichen für Makros ist.
Stimmt. Der gepostete Code ist Dreck, das weiß ich selbst. Der Rest des
Projektes sieht deutlich sauberer aus. Wir sind nämlich keine Anfänger.
Da dieser Teil aber Softwaretechnisch unser größtes Problem darstellte,
haben wir uns erst um eine Lösung bemüht und kümmern uns nun auch in
dieser Klasse um einen sauberen Programmierstil.
Rolf Magnus schrieb:> Ich hab sogar mehrere:>> - man-Page lesen> - Ein Buch lesen> - Nach dem Thema googeln> - falls das Lesen von Doku untragbar ist: umsatteln auf Briefmarken> sammeln
Ich lese oft Doku. Das hat mir in diesem Fall leider nicht besonders
geholfen. Da C++ keine besonders neue Sprache ist (damit wurden schon
uralte Großrechner programmiert, lange vor TCP) , ist der ganze TCP-Kram
nicht so in der Sprache drin, wie in anderen Programmiersprachen.
In C# oder Java ist das schon einfacher. Da tut es "ein wenig" Doku
lesen. So hardwareferne Sprachen können wir hier aber leider nicht
gebrauchen.
==========
Vielen Dank an alle, die nach einer Lösung gesucht haben.
c++ schrieb:> Nach langer Suche ohne FD hab ich nunfcntl(sock, F_SETFL, O_NONBLOCK)> gefunden, was mein Problem löst.
Um ehrlich zu sein wundert mich das. Wenn man bei google nach
"non-blocking socket" sucht, bekommt man seitenweise Ergebnisse, wo das
drin steht.
c++ schrieb:> Da C++ keine besonders neue Sprache ist (damit wurden schon> uralte Großrechner programmiert, lange vor TCP) , ist der ganze TCP-Kram> nicht so in der Sprache drin, wie in anderen Programmiersprachen.
Bei boost gibt's ein socket-API für C++. Hab ich aber noch nicht
ausprobiert.
c++ schrieb:> Da C++ keine besonders neue Sprache ist (damit wurden schon uralte> Großrechner programmiert, lange vor TCP)hust
C++ gibt es effektiv* erst seit 1985, TCP ist gut zehn Jahre älter ...
Sprachbestandteil ist "der ganze TCP-Kram" aus ganz anderen Gründen
nicht.
*) Den Namen gibt es seit '83, '85 erschien die erste Ausgabe des Buchs
von Stroustrup