Nachrichten empfangen solange Enter nicht gedrückt
-
Hallo zusammen,
ich habe einen Chat mit Client und Server geschrieben. Server klappt so wie es soll, leider komme ich bei dem Client nicht so ganz weiter.
Ich möchte, dass der Client Nachrichten empfangen kann solange nicht Enter gedrückt wurde, damit der User selber nachrichten eintippen kann.
Auszug:
// Soll immer wieder ausgeführt werden while (1) { //Solange Enter nicht gedrückt wird soll es nachrichten empfangen while (getchar() != 0x0A) { memset(&recvbuf, 0, sizeof(recvbuf)); rc = recv(sConnect, recvbuf, 256, 0); if (rc == SOCKET_ERROR) cout << "error recv(): " << WSAGetLastError() << endl; else { cout << rc << " bytes erhalten: " << recvbuf << endl; } } // Wenn Enter gedrückt wurde geht es aus der Schleife und Senden // soll möglich sein memset(&sendbuf, 0, sizeof(sendbuf)); cout << "Nachricht: "; cin.getline(sendbuf, 256); rc = send(sConnect, sendbuf, strlen(sendbuf), 0); if (rc == SOCKET_ERROR) cout << "error send(): " << WSAGetLastError() << endl; else cout << rc << " bytes gesendet" << endl; }
Gibt es andere Möglichkeiten? Kann man auch irgendwie Senden und empfangen gleichzeitig lösen? Also auch wenn man schreibt sollen nachrichten empfangen werden.
Vielen Dank!
-
Schau dir mal die Funktion select() an. Z.B.: http://www.zotteljedi.de/socket-tipps/select.html
Da kann man auch ein Timeout angeben.
Um zu sehen, ob Zeichen an stdin (oder Tastatur) anliegen, brauchst du aber Systemabhängige Funktionen.PS. Diese Informationen gelten für C, da du hier im C-Unterforum bist.
Für C++ mag das (gerade mit BOOST) anders aussehen.
-
DirkB schrieb:
Schau dir mal die Funktion select() an. Z.B.: http://www.zotteljedi.de/socket-tipps/select.html
Da kann man auch ein Timeout angeben.
Um zu sehen, ob Zeichen an stdin (oder Tastatur) anliegen, brauchst du aber Systemabhängige Funktionen.PS. Diese Informationen gelten für C, da du hier im C-Unterforum bist.
Für C++ mag das (gerade mit BOOST) anders aussehen.Select habe ich für den Server angewendet, damit mehrere Clients gleichzeitig behandelt werden können. Ich blicke nicht durch, wie ich das vorteilhaft hier einbauen kann.
-
Thisisit schrieb:
Select habe ich für den Server angewendet, damit mehrere Clients gleichzeitig behandelt werden können. Ich blicke nicht durch, wie ich das vorteilhaft hier einbauen kann.
Hast du dir den Link mal angesehen?
Zotteljedi schrieb:
select() kann übrigens nicht nur verwendet werden, um herauszufinden ob von einem Socket gelesen werden kann ohne zu blockieren.
Zotteljedi schrieb:
select() arbeitet übrigens, wie viele der anderen "Socket"-Funktionen auch, ebenfalls auf Deskriptoren wie sie von pipe() oder open() geliefert werden. Damit ist es z.B. sehr simpel einen Konsolen-Client zu schreiben, der auf die Tastatur und auf eine Netzwerkverbindung achten muß.
Schau halt mal auf der Seite http://www.zotteljedi.de/ unter Schriften zur Programmierung bei den sockets nach
Wie aber schon gesagt, ist das vor allem C.
Du programmierst aber C++
-
Nutze ich Select so richtig? Wie kann ich jetzt sagen, wenn etwas zu lesen gibt soll die Funktion aktiv werden sonst soll es bei Send bleiben?
fd_set Socketlist; FD_ZERO(&Socketlist); FD_SET(sConnect, &Socketlist); while (1) { fd_set SocketlistCopy = Socketlist; int socketAnzahl = select(0, &SocketlistCopy, nullptr, nullptr, nullptr); char buf[4096]; ZeroMemory(buf, 4096); int bytesIn = recv(sConnect, buf, 4096, 0); cout << bytesIn << " bytes erhalten: " << buf << endl; memset(&sendbuf, 0, sizeof(sendbuf)); cout << "Nachricht: "; cin.getline(sendbuf, 256); rc = send(sConnect, sendbuf, strlen(sendbuf), 0); if (rc == SOCKET_ERROR) cout << "error send(): " << WSAGetLastError() << endl; else cout << rc << " bytes gesendet" << endl; }
-
Thisisit schrieb:
Nutze ich Select so richtig?
Der erste Paramter gibt an, auf wieviel Deskriptoren maximal (max+1) geachtet werden soll.
Bei dir ist der dummerweise 0.STDIN darf da auch drin sein.
select
wartet jetzt so lange, bis einer der überwachten Deskriptoren ein Ereignis hat.
Dies kannst du überprüfen, in dem du die übergebenenfd_set
auswertest.
Du hast nur den fürread
.Wenn da was zu lesen ist, dann lies.
Aber du benutzt das ja schon im Server.
-
Für Windows steht in meiner Quelle, dass eine Eingabe nicht nötig sei für die erste Stelle bei select. Bytes senden funktioniert soweit bis auf Empfangen. Ich erkenne mein Fehler nicht
while (1) { while (getchar() == 0x0A) { memset(&sendbuf, 0, sizeof(sendbuf)); cout << "Nachricht: "; cin.getline(sendbuf, 256); rc = send(sConnect, sendbuf, strlen(sendbuf), 0); if (rc == SOCKET_ERROR) cout << "error send(): " << WSAGetLastError() << endl; else cout << rc << " bytes gesendet" << endl; } FD_ZERO(&fdSetRead); FD_SET(sConnect, &fdSetRead); timeout.tv_sec = 0; timeout.tv_usec = 0; while ((rc = select(0, &fdSetRead, NULL, NULL, &timeout))>0) { memset(&recvbuf, 0, sizeof(recvbuf)); rc = recv(sConnect, recvbuf, 256, 0); if (rc == SOCKET_ERROR) cout << "error recv(): " << WSAGetLastError() << endl; else { cout << rc << " bytes erhalten: " << recvbuf << endl; } }
-
Ist
stdin
bei dir blockierend?
-
DirkB schrieb:
Ist
stdin
bei dir blockierend?An welcher stelle meinst du das?
Edit: Ich merke das ich erst Nachrichten empfange wenn ich in der Console etwas schreibe und Enter drücke. Woran kann das liegen?
Also ich schreibe etwas drücke Enter und bei dem anderen Client muss ich etwas eintippen und enter drücken dann erst wird die nachricht angezeigt.
-
Thisisit schrieb:
Edit: Ich merke das ich erst Nachrichten empfange wenn ich in der Console etwas schreibe und Enter drücke. Woran kann das liegen?
Daran, dass
stdin
blockierend ist.
getline wartet solange, bis eine Zeile (mit Enter) eingegeben wurde.Allerdings gibt
stdin
(meistens) auch erst die Daten weiter, wenn Enter gedrückt wurde.Darum auch der (mehrmalige) Hinweis, dass
select
auch mitSTDIN
klar kommt.
-
Wie kann ich den Stdin bei select definieren, das habe ich nicht ganz verstanden?
-
Thisisit schrieb:
Wie kann ich den Stdin bei select definieren, das habe ich nicht ganz verstanden?
Du hast auch nicht verstanden, daß Du im falschen Forum postest
-
ralros schrieb:
Thisisit schrieb:
Wie kann ich den Stdin bei select definieren, das habe ich nicht ganz verstanden?
Du hast auch nicht verstanden, daß Du im falschen Forum postest
Kann jemand den Thread verschieben oder soll ich eine neue erstellen. Ich bin kurz vor dem Ziel
-
Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C (alle ISO-Standards) in das Forum C++ (alle ISO-Standards) verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Hat sich geklärt getchar war das problem. Danke