Chat Server und Client in C++
-
Hallo liebe Foren Mitglieder ich lese schon länger fleißig in diesem Forum mit und da ich nun auch mal einen Frage habe, habe ich mich gleich angemeldet um nachzufragen. Also ich bin noch Anfänger in C++ und weiß leider nicht was ich in meinem Programm falsch mache. Also ich hatte vor ein Chat Programm in C++ zu schreibe. Es sollen sich mehrere Cleinten mit dem Server verbinden können und die Narichten auch bei jedem Client ankommen. Doch das funktioniert leider nicht
Server:
#include <Winsock.h> #include <iostream> #include <windows.h> using namespace std; #pragma comment(lib, "ws2_32.lib") SOCKADDR_IN addr; // Speichern von Port und IP int addrlen = sizeof(addr); // Länge des Ports und der IP int Counter; // Zähler für verbundene Clients SOCKET sConnect; // Einkommende Narichten SOCKET sListen; // Ausgehende Narichten SOCKET* Connections; // Verbundene Clients int InitWinSock() // WinSock { int Val = 0; WSAData wsaData; WORD DLLVersion = MAKEWORD(2, 1); Val = WSAStartup(DLLVersion, &wsaData); // Einleitung von WinSock return Val; } int ServerThread(int ID) { char* Buffer = new char[256]; // Für jeden Client einen neuen Thread int size = 0; while (true) { ZeroMemory(Buffer, 256); if ((size = recv(Connections[ID], Buffer, 256, NULL)) > 0) // Wird nur getan wenn die Naricht nicht leer ist cout << Buffer << endl; { for (int a = 0; a > Counter; a++) // Das macht jeder Client im loop { if (Connections[a] == Connections[ID]) { ZeroMemory(Buffer, 256); cout << ID << Buffer << endl; } else // Die Naricht wird zu allen Client geschickt { ZeroMemory(Buffer, 256); cout << ID << Buffer << endl; send(Connections[a], Buffer, 256, NULL); cout << Buffer << endl; } } } } } int main() { system("color 0a"); // Konsolenfarbe Schwarz-Grün cout << "Server gestartet" << endl; int Val = InitWinSock(); if (Val != 0) { MessageBoxA(NULL, "Fehler beim starten von WinSocket", "Fehler", MB_OK | MB_ICONERROR) exit(1); } Connections = (SOCKET*)calloc(64, sizeof(SOCKET)); sListen = socket(AF_INET, SOCK_STREAM, NULL); sConnect = socket(AF_INET, SOCK_STREAM, NULL); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // Serveradresse in diesem Falle die lokale Adresse addr.sin_port = htons(2222); // Bereich in dem man Ports wählen darf addr.sin_family = AF_INET; // Art der Verbindung bind(sListen, (SOCKADDR*)&addr, sizeof(addr)); // Verbinden des Servers mit unserer IP und unserem Port listen(sListen, 64); // Warten auf Anfragen von Clients while (true) // Endless loop für Connections zu Clients { if (sConnect = accept(sListen, (SOCKADDR*)&addr, &addrlen)) // Connection zu Client wurde gefunden und angenommen { Connections[Counter] = sConnect; char* Name = new char[64]; // Name des Clients ZeroMemory(Name, 64); // Leeren des Chars sprintf(Name, "%i", Counter); send(Connections[Counter], Name, 64, NULL); send(Connections[Counter], "Willkommen auf dem Chat Server", 64, NULL); cout << "Neue Verbindung !" << endl; Counter++; // Ein Client mehr usw... CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ServerThread, (LPVOID)(Counter - 1), NULL, NULL); } Sleep(50); } }
Client:
#include <WinSock.h> #include <Windows.h> #include <iostream> using namespace std; #pragma comment(lib, "ws2_32.lib") // Libarie für WinSock SOCKET sConnect; // Einkommende Narichten SOCKADDR_IN addr; // Serveradresee int Startup_WinSock() { WSAData wsaData; WORD DLLVersion = MAKEWORD(2, 1); int Val = WSAStartup(DLLVersion, &wsaData); return Val; } int ClientThread() { char* Buffer = new char[256]; int size = 0; cout << Buffer << endl; while (true) { ZeroMemory(Buffer, 256); if ((size = recv(sConnect, Buffer, 256, NULL)) > 0) { cout << Buffer << endl; } Sleep(50); } } int main() { system("color 0a"); int Val = Startup_WinSock(); if (Val != 0) { cout << "WinSock konnte nicht gestartet werden" << endl; exit(1); } sConnect = socket(AF_INET, SOCK_STREAM, NULL); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // Serveradresse in diesem Falle die lokale Adresse addr.sin_port = htons(2222); // Bereich in dem man Ports wählen darf addr.sin_family = AF_INET; // Art der Verbindung cout << "Bitte druecken sie die Enter Taste" << endl; cin.get(); Val = connect(sConnect, (SOCKADDR*)&addr, sizeof(addr)); if (Val != 0) { cout << "Server kann nicht erreicht werden" << endl; main(); // Neuer Versuch } else { system("cls"); int ID; char* nID = new char[64]; // deine ID char* Hallo = new char[64]; // Eine Naricht vom Server ZeroMemory(Hallo, 64); ZeroMemory(nID, 64); recv(sConnect, nID, 64, NULL); // Empfang der Naricht recv(sConnect, Hallo, 64, NULL); // Empfang der Naricht ID = atoi(nID); cout << Hallo << endl; cout << "Deine ID ist:" << ID << endl; cout << "Wenn du bereit bist dann druecke bitte Enter erneut " << endl; cin.get(); system("cls"); cout << "Du > "; CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ClientThread, NULL, NULL, NULL); // CLient Thread while (true) { char* MSG = new char[256]; ZeroMemory(MSG, 256); cin.getline(MSG, 256); send(sConnect, MSG, 256, NULL); Sleep(50); } } return 0; }
Ich bedanke mich schonmal im vorraus für euere Antworten !!!
Mod-Edit (camper): Code-Tags + clang-format
-
Hallo liebe Foren Mitglieder ich lese schon länger fleißig in diesem Forum mit
Dann solltest du ja schon mitbekommen haben, dass
Doch das funktioniert leider nicht
keine ausreichende Fehlerbeschreibung ist.
Codetags wären auch hilfreich.
-
Also wenn ich den Server starte und dann den Client dann verbindet sich der Client sofort mit dem Server. Das ist ja schonmal gut. Wenn ich im Client etwas schreibe wird das auch zum Server geschickt ABER der Server schickt die Naricht nicht an die anderen verbundenen Clienten weiter.
-
Entschuldigung habe vorhin vergessen den Code in Codetags zu schrieben
Client:
#include <WinSock.h> #include <iostream> #include <Windows.h> using namespace std; #pragma comment (lib, "ws2_32.lib") // Libarie für WinSock SOCKET sConnect; // Einkommende Narichten SOCKADDR_IN addr; //Serveradresee int Startup_WinSock () { WSAData wsaData; WORD DLLVersion = MAKEWORD(2, 1); int Val = WSAStartup (DLLVersion, &wsaData); return Val; } int ClientThread() { char *Buffer = new char[256]; int size = 0; cout << Buffer << endl; while (true) { ZeroMemory(Buffer, 256); if ((size = recv(sConnect, Buffer, 256, NULL)) > 0) { cout << Buffer << endl; } Sleep(50); } } int main () { system("color 0a"); int Val = Startup_WinSock(); if (Val != 0) { cout << "WinSock konnte nicht gestartet werden" << endl; exit (1); } sConnect = socket(AF_INET, SOCK_STREAM, NULL); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // Serveradresse in diesem Falle die lokale Adresse addr.sin_port = htons(2222); // Bereich in dem man Ports wählen darf addr.sin_family = AF_INET; //Art der Verbindung cout << "Bitte druecken sie die Enter Taste" << endl; cin.get(); Val = connect(sConnect, (SOCKADDR*)&addr, sizeof(addr)); if (Val != 0) { cout << "Server kann nicht erreicht werden" << endl; main(); //Neuer Versuch } else { system("cls"); int ID; char *nID = new char[64]; //deine ID char *Hallo = new char[64]; // Eine Naricht vom Server ZeroMemory (Hallo, 64); ZeroMemory (nID, 64); recv(sConnect, nID, 64, NULL);//Empfang der Naricht recv(sConnect, Hallo, 64, NULL);//Empfang der Naricht ID = atoi(nID); cout << Hallo << endl; cout << "Deine ID ist:" << ID << endl; cout << "Wenn du bereit bist dann druecke bitte Enter erneut " << endl; cin.get(); system("cls"); cout << "Du > "; CreateThread (NULL, NULL, (LPTHREAD_START_ROUTINE) ClientThread, NULL, NULL, NULL);//CLient Thread while (true) { char *MSG = new char[256]; ZeroMemory(MSG, 256); cin.getline(MSG, 256); send(sConnect, MSG, 256, NULL); Sleep(50); } } return 0; }
Server:
#include <Winsock.h> #include <iostream> #include <windows.h> using namespace std; #pragma comment (lib, "ws2_32.lib") SOCKADDR_IN addr; // Speichern von Port und IP int addrlen = sizeof(addr); // Länge des Ports und der IP int Counter; //Zähler für verbundene Clients SOCKET sConnect; // Einkommende Narichten SOCKET sListen; // Ausgehende Narichten SOCKET *Connections; //Verbundene Clients int InitWinSock() // WinSock { int Val = 0; WSAData wsaData; WORD DLLVersion = MAKEWORD (2, 1); Val = WSAStartup(DLLVersion, &wsaData); // Einleitung von WinSock return Val; } int ServerThread(int ID) { char *Buffer = new char[256];// Für jeden Client einen neuen Thread int size = 0; while (true) { ZeroMemory(Buffer, 256); if ((size = recv(Connections[ID], Buffer, 256, NULL)) > 0)//Wird nur getan wenn die Naricht nicht leer ist cout << Buffer << endl; { for (int a = 0; a > Counter; a++)// Das macht jeder Client im loop { if (Connections [a] == Connections[ID]) { ZeroMemory(Buffer, 256); cout << ID << Buffer << endl; } else//Die Naricht wird zu allen Client geschickt { ZeroMemory(Buffer, 256); cout <<ID << Buffer << endl; send(Connections[a], Buffer, 256, NULL); cout << Buffer << endl; } } } } } int main() { system("color 0a"); // Konsolenfarbe Schwarz-Grün cout << "Server gestartet" << endl; int Val = InitWinSock(); if (Val != 0) { MessageBoxA(NULL, "Fehler beim starten von WinSocket", "Fehler", MB_OK | MB_ICONERROR); exit(1); } Connections = (SOCKET*) calloc (64, sizeof(SOCKET)); sListen = socket(AF_INET, SOCK_STREAM, NULL); sConnect = socket(AF_INET, SOCK_STREAM, NULL); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // Serveradresse in diesem Falle die lokale Adresse addr.sin_port = htons(2222); // Bereich in dem man Ports wählen darf addr.sin_family = AF_INET; //Art der Verbindung bind (sListen, (SOCKADDR*)&addr, sizeof(addr)); //Verbinden des Servers mit unserer IP und unserem Port listen(sListen, 64); //Warten auf Anfragen von Clients while (true) //Endless loop für Connections zu Clients { if (sConnect = accept(sListen, (SOCKADDR*)&addr, &addrlen)) // Connection zu Client wurde gefunden und angenommen { Connections[Counter] = sConnect; char *Name = new char[64];//Name des Clients ZeroMemory(Name, 64);//Leeren des Chars sprintf(Name, "%i", Counter); send(Connections[Counter], Name, 64, NULL); send(Connections[Counter], "Willkommen auf dem Chat Server", 64, NULL); cout << "Neue Verbindung !" << endl; Counter++; //Ein Client mehr usw... CreateThread (NULL, NULL, (LPTHREAD_START_ROUTINE) ServerThread, (LPVOID)(Counter - 1), NULL, NULL); } Sleep(50); } }
-
for (int a = 0; a > Counter; a++)
Wie oft wird das ausgeführt?
Benutze einen Debugger.
Das
char *Buffer = new char[256];
sollte wohl besser
char Buffer[256]; // noch besser std::array<char,256> Buffer;
sein.
256 könnte man auch als const int verwenden.
-
Also ich habe mir gedacht das jeder Client eine Nummer zugewiesen bekommt und die dann immer vor seinem Text erscheint. also z.b. Client und dann die Variablenen (z.b. Client 1: Hallo, Client 2: Wie gehts) Der Chat soll eh annonym sein von daher nur Zahlen als Namen.
for (int a = 0; a > Counter; a++)
-
Also ich habe mir gedacht das jeder Client eine Nummer zugewiesen bekommt und die dann immer vor seinem Text erscheint. also z.b. Client und dann die Variablenen (z.b. Client 1: Hallo, Client 2: Wie gehts) Der Chat soll eh annonym sein von daher nur Zahlen als Namen.
for (int a = 0; a > Counter; a++)
-
Programmer2000 schrieb:
Also ich habe mir gedacht das jeder Client eine Nummer zugewiesen bekommt und die dann immer vor seinem Text erscheint. also z.b. Client und dann die Variablenen (z.b. Client 1: Hallo, Client 2: Wie gehts) Der Chat soll eh annonym sein von daher nur Zahlen als Namen.
for (int a = 0; a > Counter; a++)
Und wie ist die Antwort auf meine Frage?
-
Ja es wird so oft ausgeführt wie Clienten den Server betreten.
-
Programmer2000 schrieb:
Ja es wird so oft ausgeführt wie Clienten den Server betreten.
Ich glaube nicht. Das soll es wohl tun, macht aber etwas anderes. Welchen Wert hat
a
? Welchen Wert hatCounter
?
-
Also a fängt mit dem Wert 0 an und erhöht sich durch jeden Client der beitritt um 1. Das klappt auch soweit.
-
Programmer2000 schrieb:
Also a fängt mit dem Wert 0 an und erhöht sich durch jeden Client der beitritt um 1. Das klappt auch soweit.
Nein!
-
ok dann erkläre es mir bitte. Wie gesagt ich bin noch Anfänger
-
for (int a = 0; a > Counter; a++)
vs.
for (int a = 0; a < Counter; a++)
-
Danke
-
Es funktioniert leider immer noch nicht so wie ich es mir erhofft habe. Irgendwie leitet der Server den Text des einen Clienten nicht zu dem anderen Clienten weiter;(
-
Vielleicht ist ZeroMemory vor dem Senden ungeschickt.
-
OH SCHEISSE
-
Also irgendwie steh ich gerade auf dem Schlauch. Ich bekomm es immer noch nicht hin. Aber danke manni66 habe das ZeroMemory entfernt
-
Ich habe jetzt ZeroMemory entfernt. Wenn ich jetzt von einem Client zum anderen eine Naricht sende funktioniert dies auch !!;);) ABER wenn ich von dem Client der die Naricht erhalten hat eine Naricht zurückschreibe kommt auf dem anderen Client keine Antwort an.