Socket



  • Hi, Ich bins mal wieder^^ also hab mir da was kleines gebastelt, aber leider klappt es nicht so recht 😞 Ich bekomme zwar ne Verbindung zu meinem rechner, aber das senden eines TESTSTRINGS funktioniert nicht... vlt könnt ihr mir ja helfen ^^ 😉

    SERVER:

    #include <cstdlib>
    #include <iostream>
    #include <winsock.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    using namespace std;
    
    int sock;
    int size;
    int bytes;
    char buffer[] = "Willkommen zu dem Test-Server\r\n";
    
    int main(void)
    {
        sockaddr_in service;
        sockaddr_in client;
    
        {
    		WSADATA wsa;
    		if (WSAStartup(MAKEWORD(1, 1), &wsa))
    		{
    			printf("WSAStartup() failed, %lu\n", (unsigned long)GetLastError());
    
    		}
    	}
    
    	service.sin_family = AF_INET;
        service.sin_port = htons(1234);
        service.sin_addr.s_addr = inet_addr("192.168.178.11");
    
        sock = socket(AF_INET, SOCK_STREAM, 0);
    
        if (sock == -1)
        {
    	      perror("socket() failed");
    
        }
    
        else cout << "socket() started successful!" << endl;
    
        if (bind(sock, reinterpret_cast<sockaddr*>(&service), sizeof(service)) == -1)
        {
    	   perror("bind() failed");
    
        }
    
        else cout << "bind() started successful!" << endl;
    
        if (listen(sock, 3) == -1)
        {
    	   perror("listen () failed");
    
        }
    
        else cout << "listen() is use..." << endl << endl;
    
        size = sizeof( client );
    
        while (true) 
        {
    
            if (accept( sock, reinterpret_cast<sockaddr*>(&client), &size)  == -1 ) 
            {
               perror("accept () failed");
            }
    
            cout << "accept() is OK." << endl << endl;
    
            break;
    
        }
    
        bytes = send(sock, buffer, strlen(buffer), 0);
    	if (bytes == -1)
    	{
    		perror("send() fehlgeschlagen");
    
    	}
    
        closesocket(sock);
    
        system("PAUSE");
        return 0;
    }
    

    So nun der CLIENT... Ich weiß das is etwas umständlich vonwegen Server und Client^^ 😉

    CLIENT :

    #include <cstdlib>
    #include <iostream>
    #include <winsock.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    using namespace std;
    
    int sock;
    char buffer[1024];
    int bytes;
    
    int main(void)
    {
        sockaddr_in service;
    
        {
    		WSADATA wsa;
    		if (WSAStartup(MAKEWORD(1, 1), &wsa))
    		{
    			printf("WSAStartup() failed, %lu\n", (unsigned long)GetLastError());
    
    		}
    	}
    
        service.sin_family = AF_INET;
        service.sin_port = htons(1234);
        service.sin_addr.s_addr = inet_addr("192.168.178.11");
    
        sock = socket(AF_INET, SOCK_STREAM, 0);
    
        if (sock == -1)
        {
    	      perror("socket() failed");
    
        }
    
        else cout << "socket() started successful!" << endl;
    
        if (connect(sock, reinterpret_cast<sockaddr*>(&service), sizeof(service)) == -1)
        {
           perror("connect() failed");
    
        }
    
        else cout << "connect() started successful!" << endl;
    
        bytes = recv(sock, buffer, sizeof(buffer) - 1, 0);
    	if (bytes == -1)
    	{
    		perror("recv() fehlgeschlagen");
    
    	}
    	buffer[bytes] = '\0';
    	printf("Server: %s", buffer);
    
        closesocket(sock);
    
        system("PAUSE");
        return 0;
    }
    

    Ich hoffe ihr könnt helfen 😉

    MfG FoX



  • Accept gibt Dir einen neuen Socket zurück, den Du speichern musst. Von diesem neuen Socket musst Du dann lesen, nicht von dem listening Socket.



  • hmmm und wie müsste dann die code änderung asusehen ?
    also im augenblick versteh ich nich wie du das meinst, wie kann ich auf diesen neuen sockel zugreifen ? kannste nich mal ein klitze kleines codefragment machen ^^ 😉

    mfg



  • Jo. Analog zum Aufruf der Funktion socket eigentlich:

    int sock2 = accept( sock, reinterpret_cast<sockaddr*>(&client), &size);
    if ( sock2 == -1 ) 
    {
        perror("accept () failed");
    }
    

    Und beim Senden dann nicht sock sondern sock2 benutzen 😉



  • dnake 🙂



  • Ausserdem würd ich für den listener statt einer festen IP, ADDR_ANY verwenden, dann lauscht er auch an deinen anderen IP adressen.

    und zu deinem aufbau, empfehle ich dir statt reinen char-streams immer eine struktur vorher zu senden

    typedef struct {
    	word PackageLength;
    	byte Protcolnumber;
    } TPackageHeader;
    

    die packetlänge wird entscheidend, wenn deine strings btw. daten die pufferlänge des sockets überschreiten.

    achte auf die datenausrichtung deines compiler, hab mich da gestern selbst in die nesseln gesetzt



  • Hi!

    Oder er macht wie z.B. bei IRC ein zeilenorientiertes Protokoll, welches mit \r\n abschließt. Je nachdem was er alles übertragen will. Wenn entsprechende Felder existieren und es nicht zig unterschiede in den Paketen gibt macht es aber sicher mehr Sinn eine Struktur zu verwenden.

    Greetz



  • solang die zeile den puffer nicht sprengt iss alles i.O. ^^

    ich hab mir sogar ne zentrale protokoll-klasse erzeugt, dort handel ich das serialisieren und das deserialisieren von übergebenen objekten und strukturen ab und dort sind auch die ganzen pakettypen aufgeführt und der code dafür, sowohl server als auch client implementieren dann diese klasse und wenn eine neues paket hinzugefügt wird spart man sich glatt die halbe arbeit ^^



  • Naja, in IRC hat man oft Zeilen die nicht in den Puffer passen, da wird natürlich der Rest mit einem zweiten Paket geschickt, dass muss man halt entsprechend handeln was auch nicht wirklich schwer ist, aber ich finds auch nicht wirklich toll.
    Da bin ich auch eher für vernünftige Pakete, ist einfach besser. 😉

    Greetz


Anmelden zum Antworten