Socket-Klasse



  • Kannst du mal den Code posten, wo du die Daten überhaupt empfangen willst?
    Du rufst Recv ja nirgens auf.

    Funktioniert der Connect auch mit der IP (255.255.255.255)?

    Kommt gar nix an, oder nur ein Zeichen? sizeof(text) ist an der Stelle falsch, da sollte strlen(text) hin^^



  • Du wartest ja beim Empfangen darauf, daß 1000 Zeichen ankommen... also steht solange der Prozess.

    Du solltest zuerst die Länge als int übertragen und danach dann die Daten.
    Beim Empfangen erst die Länge auslesen und danach genau soviele Daten abfragen, wie in der Länge angegebn sind.

    Und wenn du unterschiedliche System bzw. Endianess verwendest, solltest du die Funktion ntohl() und htonl() zum Übertragen verwenden.

    Zum Testen kannst du aber einfach mal die Konstante 1000 beim Senden als Länge übergeben, dann sollte auch das Empfangen funktionieren.
    Und übrigens kann es passieren, daß recv() nur einen Teil der Daten empfängt, d.h. du mußt dir eine Schleife darum bauen, bis du alle benötigten Daten zusammen hast.

    Schau dir mal andere Threads hier im Forum bzgl. Sockets (send und recv) an...



  • @Salomon: Nein, die Parameter die ich hier bei Connect() übergebe, entsprechen nicht der Wirklichkeit.

    Das Server-Programm macht nichts anderes als eine while()-Schleife ins Morgengrauen und dann immer fleißig recv() und ausgeben.

    Habe auch einen anderen Clienten getestet, welcher keine Klasse nutzt, sondern stur runtergeschriebenen Code - das funktioniert.

    Angemerkt sei noch, daß nicht mal send(Server.Socket,Text,sizeof(Text),0) funktioniert.

    kg Max



  • Hallo,
    255.255.255.255 ist die Local Broadcast Addresse.
    Auf die kann nicht Verbunden werden (TCP/IP).

    Wähle die Adresse der Gegenstelle (des Servers). Falls der Server auf dem gleichen Rechner ist kannst Du 127.0.0.1 nehmen.

    Aus einem char Array einen std::string machen:

    return std::string(Message);
    
    Status = connect(Socket,(SOCKADDR*)&Addr,sizeof(SOCKADDR));
    

    Du musst die Socket Variable names socket übergeben (nicht den Typ).

    Simon



  • Schonmal vielen Dank für Eure Antworten!

    Nochmal: 255.255.255.255 war ein Beispiel.

    Wenn Du C kennst weißt Du, dass (std::string)Message und std::string(Message) nur syntaktisch unterschiedlich sind.

    Wie sollte connect() Deines Erachtens aussehen?

    lg Max



  • Du wartest ja beim Empfangen darauf, daß 1000 Zeichen ankommen... also steht solange der Prozess.

    Stimmt nicht, das gibt bloss die Grösse des übergebenen Buffers an.
    recv kann nach wenigen Bytes wieder zurückkehren. Die Anzahl empfangenen Bytes stehen im return Wert von revc.



  • -> Quatsch, connect ist in Ordnung. Sorry.



  • Dieses Problem macht mich ganz krank, vielleicht schau ich mich mal um ob ich eine funktionierende Klasse finde und gleiche dann mal den Code ab.

    Grrrr 😡

    lg Max



  • Also wie gesagt, der einzige Fehler, der mir da spontan auffällt ist, dass Server.Send(Text,sizeof(Text)); falsch is. Da muss statt sizeof(Text) strlen hin.



  • So ich melde mich nochmal, weil ich nur geringfügig weitergekommen bin.

    Wahrscheinlich liegt die Lösung des Problems im Kontext des Programmaublaufs.

    Hier noch einmal meine Klasse (ein wenig geändert):

    class CServer
    {
    	private:
    	WSADATA wsa;
    	SOCKET Socket;
    	SOCKADDR_IN Addr;
    
    	public:
    	long Status;
    
    	CServer()
    	{
    		Status = WSAStartup(MAKEWORD(2,0),&wsa);
    	}
    
    	void Connect(char* IP,u_short PORT)
    	{
    		Socket = socket(AF_INET,SOCK_STREAM,0);
    		if (Socket == INVALID_SOCKET)
    		{
    			Status = SOCKET_ERROR;
    			return;
    		}
    		memset(&Addr,0,sizeof(SOCKADDR_IN));
    		Addr.sin_family = AF_INET;
    		Addr.sin_port = htons(PORT);
    		Addr.sin_addr.s_addr = inet_addr(IP);
    		Status = connect(Socket,(SOCKADDR*)&Addr,sizeof(SOCKADDR));
    	}
    
    	void Send(const std::string Message)
    	{
    		send(Socket,Message.data(),Message.length(),0);
    	}
    
    	std::string Recv()
    	{
    		char Message[1000] = "";
    		recv(Socket,Message,1000,0);
    		return (std::string)Message;
    	}
    
    	void Disconnect()
    	{
    		WSACleanup();
    	}
    };
    

    Das Problem einmal genauer dargestellt:

    LRESULT CALLBACK WndMain(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
    {
    	CServer Server;
    
    	switch (msg)
    	{
    		case WM_CREATE:
    		{
    			Server.Connect("255.255.255.255",9999); //Pseudo
    			Server.Send("TEST1"); //Kommt an
    			break;
    		}
    		case WM_COMMAND:
    		{
    			switch (LOWORD(wParam))
    			{
    				case ID_BUTTON_CLICKED:
    				{
    					Server.Send("TEST2"); //Kommt nicht an
    					break;
    				}
    			}
    			break;
    		}
    		case WM_DESTROY:
    		{
    			PostQuitMessage(0);
    			break;
    		}
    	}
    	return DefWindowProc(hWnd,msg,wParam,lParam);
    }
    

    Hoffentlich kommt jemand drauf.

    Ich weiß nimmer weiter...

    lg Max



  • Um Gottes Willen, ich bin so ein Idiot...

    Hab es gelöst 😃

    1. Instanz der Klasse global anlegen
    2. In der WinMain()-Funktion Server.Connect() ausführen

    Ansonsten bleibt alles gleich, weil CServer Server jetzt für alle Funktionen global ist und von überall angesteuert werden kann.

    Man man, peinlich wie ich mich wieder zum Deppen gemacht hab xD

    Naja, bis demnächst und Danke an alle die sich meiner Blödheit angenommen haben^^

    lg Max


Anmelden zum Antworten