Chat Server und Client in C++



  • 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 hat Counter ?



  • 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.



  • Ich habe es hinbekommen. Danke für euere Mithilfe ! 😉


Anmelden zum Antworten