socket client-> auf antwort warten und gleichzeitig eingaben empfangen
-
DrGreenthumb schrieb:
Bashar schrieb:
DrGreenthumb: Nö, das Beispiel überwacht fd 0. stdin ist ein gepufferter Überbau dazu, und den Status des Puffers kannst du nicht abfragen.
aha, hm, aber ist das nicht egal? Das Problem ist ja, dass das Programm bei der Eingabe blockiert. Und mit dem Beispiel aus der Manpage ist das nicht der Fall.
Nein, ist nicht egal. Wenn du auf fd 0 selectest, und Aktivität angezeigt wird, was tust du dann? Du liest mit stdio-Funktionen von stdin ... aber wieviel liest du? Liest du zuwenig, verbleiben Zeichen im Puffer, so dass select beim nächsten mal blockiert, obwohl noch Eingaben zu verarbeiten sind. Liest du zuviel, blockiert die Eingabe, bevor select zum Zuge kommt.
Das Beispiel aus der Manpage (reden wir vom gleichen Beispiel?) liest ja keine Eingabe, sondern macht nur einmalig ein select auf fd0 mit einem Timeout.
-
Und das heißt jetzt man dürfte nur mit dem lowlevel-read() von fd 0 einlesen, anstatt mit den stdio-Funktionen?
Aber auch dann weiß man doch nicht wieviel Zeichen man einlesen sollDachte mir das so, dass select zurückkehrt wenn der Benutzer enter gedrückt hat, also genau eine Zeile eingeben hat. Die liest man dann ein und fertig.
(Mehr als mit select rumgespielt hab ich bisher eh noch nie, aber da hat's immer so funktioniert.)
-
Bashar schrieb:
Das Beispiel aus der Manpage (reden wir vom gleichen Beispiel?) liest ja keine Eingabe, sondern macht nur einmalig ein select auf fd0 mit einem Timeout.
Ja, stimmt. Den Einlesepart hab ich selber dazu gedichtet
-
DrGreenthumb schrieb:
Und das heißt jetzt man dürfte nur mit dem lowlevel-read() von fd 0 einlesen, anstatt mit den stdio-Funktionen?
Aber auch dann weiß man doch nicht wieviel Zeichen man einlesen sollDoch: Entweder, man fordert mehr Zeichen an, als vorhanden sind. Das kann man am Rückgabewert von read erkennen. Oder man liest weniger als vorhanden sind (oder genau gleich viele), dann gibt select beim nächsten Aufruf gleich wieder die 0 als bereit zurück.
Dachte mir das so, dass select zurückkehrt wenn der Benutzer enter gedrückt hat, also genau eine Zeile eingeben hat. Die liest man dann ein und fertig.
Kann man machen, aber während man z.b gerade den Socket abarbeitet könnte der Benutzer zweimal Enter drücken ... was dann?
-
hio
short int rc; SOCKET s; SOCKADDR_IN addr; FD_SET fdset; char antwort[200]; int ilen; char buf[200];
rc=startWinsock(); s=socket(2,SOCK_STREAM,0); memset(&addr,0,sizeof(SOCKADDR_IN)); // zuerst alles auf 0 setzten addr.sin_family=2; addr.sin_port=htons(12345); // wir verwenden mal port 12345 addr.sin_addr.s_addr=inet_addr("127.0.0.1"); // zielrechner ist unser eigener rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR)); send(s,getNachricht(hwndNick),100,0); do{ select(0,&fdset,NULL,NULL,NULL); rc=recv(s,antwort,256,0); if(rc!=0) { antwort[rc]='\0'; SendMessage(hwndGet,WM_SETTEXT,0,(long)antwort); } }while(true);
durch die fußgesteuerte schleife stürzt mein programm ab..wie wende ichd as select an, mache ich etwas falsch?
cYa
-
danke bashar
rulzmaker, da fehlen jetzt die FD_-Makros. Ausserdem muss das erste Argument für select der Deskripter mit der höchsten Nummer + 1 sein, also hier s+1.
-
hi
fd_makros..hu?
void startVerbindung() { rc=startWinsock(); s=socket(2,SOCK_STREAM,0); memset(&addr,0,sizeof(SOCKADDR_IN)); // zuerst alles auf 0 setzten addr.sin_family=2; addr.sin_port=htons(12345); // wir verwenden mal port 12345 addr.sin_addr.s_addr=inet_addr(getNachricht(hwndHost)); // zielrechner ist unser eigener rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR)); send(s,getNachricht(hwndNick),100,0); select(0,&fdset,NULL,NULL,NULL); FD_ZERO(&fdset); FD_SET(s,&fdset); rc=recv(s,antwort,256,0); if(rc!=0) { antwort[rc]='\0'; SendMessage(hwndGet,WM_SETTEXT,0,(long)antwort); } }
s+1 ist nur für linux relevant nicht jedoch für windows.
cYa
-
rulzmaker schrieb:
fd_makros..hu?
FD_ZERO, FD_SET um den socket hinzuzufügen. Das muss vorm select()-Aufruf passieren.
s+1 ist nur für linux relevant nicht jedoch für windows.
achso
-
hi
void startVerbindung() { rc=startWinsock(); s=socket(2,SOCK_STREAM,0); memset(&addr,0,sizeof(SOCKADDR_IN)); // zuerst alles auf 0 setzten addr.sin_family=2; addr.sin_port=htons(12345); // wir verwenden mal port 12345 addr.sin_addr.s_addr=inet_addr(getNachricht(hwndHost)); // zielrechner ist unser eigener rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR)); send(s,getNachricht(hwndNick),100,0); do{ select(0,&fdset,NULL,NULL,NULL); rc=recv(s,antwort,256,0); if(rc!=0) { antwort[rc]='\0'; SendMessage(hwndGet,WM_SETTEXT,0,(long)antwort); } FD_ZERO(&fdset); FD_SET(s+1,&fdset); }while(true); }
es endet wieder in der endlosschleife..whyy
cYa
-
hi
weiß denn keiner was an dem select falsch ist?
cYa
-
Mann,
macht ihr sowas im wirklichen Leben?
So macht man dass
1 Hauptthread, der verwaltet 2 Kommunikationsthreads. Die Komm.Threads werfen ein Event, falls es neue Eingaben gibt, der Hautpthread empfängt die Events und reagiert drauf.
Und schon muss niemand auf den anderen warten.
Braucht man noch eine weitere eingabe möglichkeit, so macht man nen zusätzlichen Kom.Thread (z.B. Seriell)
mfg
-
Hi Gast,
schon mal dran gedacht, wie langsam das Programm dann wird, wenn du erstmal einige hundert Sockets = Threads hast?
ChrisM
-
Ist doch egal, dann kauft man halt mehr Hardware. So wird das gemacht!
-
hi
ich möchte das gerne mit dem select erstmal lösen...ich komme einfach nicht weiter
cYa