- LiTime Speicher und Akkus         
Ergebnis 1 bis 2 von 2

Thema: IPV6 Server Client Verbindung

  1. #1

    IPV6 Server Client Verbindung

    Anzeige

    Praxistest und DIY Projekte
    Hallo Zusammen,

    ich muss gerade für ein kleines Projekt eine TCP Server Client Verbindung programmieren in C unter Linux.
    Mit IPV4 hatte ich da bisher grundsätzlich Erfolg, für IPv6 klappt es leider nicht mehr.
    Bei connect() bekommt er keine Verbindung.
    Grundsätzlich soll die IP vom Sever mit in6addr_any festgelegt werden und bei Start angezeigt.
    Dazu nutze ich inet_ntop um diese in einen String umzuwandeln. Hier zeigt er aber jedes mal, selbst wenn ich eine fest IP vorgebe, das gleich an (a00:4d2:: )
    Auf Client Seite soll die IP dann als String eingegeben werden und mit inet_pton umgewandelt werden.
    Diese lasse ich nach dem connect versuch nochmals zurück umwandeln mit inet_ntop, hier kommt, egal welchen String ich anfangs eingebe, bzw auch wenn ich eine feste IP vorgebe immer 200:4d2:: zurück.
    Daher vermute ich mal, dass zum einen bei der Umwandlung auf Serverseite ein Fehler vorliegt und auf der Clientseite beim Einlesen und hin und her Umwandeln.

    Hat jemand eine Idee? Bitte etwas Umsicht mit mir, bin noch Anfänger beim Programmieren.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netdb.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    
    #define PORT 1234
    int x;
    char Y[10];
    
    
    int main()
    {
        char DataIN[1024];
        char DataOUT[1024];
        
        printf("Server startet!\n");    
        
        /***** Socket erzeugen *****/
        int ServerSocket = socket(AF_INET6, SOCK_STREAM, 0);
        if (ServerSocket < 0){printf("Erzeugen des Socket fehlgeschlagen!\n"); return EXIT_SUCCESS;}
        else {printf("Socket erzeugt...\n");}
           
        /***** Verbindung herstellen *****/
        struct sockaddr_in6 ServerAddr;
    
        memset(&ServerAddr, 0, sizeof(ServerAddr));
    
        ServerAddr.sin6_family = AF_INET6;
        ServerAddr.sin6_port = htons(PORT);
        ServerAddr.sin6_addr = in6addr_any;      
    
        char ServerIP[16];
        inet_ntop(AF_INET6, &ServerAddr, ServerIP, 16);
    
        if(bind(ServerSocket, (struct sockaddr*)&ServerAddr, sizeof(ServerAddr)) == -1){
            printf("Fehler beim Binden des Socket!\n"); return EXIT_SUCCESS;}
        else{
            printf("Server bereit!\n IP Adresse = %s Port = %d \n", ServerIP ,PORT);  
            //printf("Server bereit...\n");
            }
            
        if(listen(ServerSocket, 5) == 0){printf("Warte auf Client...\n");}    
    
        /***** Verbindung mit Client *****/
        struct sockaddr_in6 ClientAddr;
        int addr_size = sizeof(ClientAddr);
           
        int ClientSocket = accept(ServerSocket, (struct sockaddr*)&ClientAddr, &addr_size);
        if (ClientSocket == -1) {printf("Clientanfrage nicht akzeptiert!\n"); return EXIT_SUCCESS;}
            
        printf("Client Anfrage akzeptiert!\n");    
        strcpy(DataOUT, "[SERVER] Anfrage akzeptiert bitte Zahl eingeben!");
        send(ClientSocket, DataOUT, strlen(DataOUT), 0);
        
        recv(ClientSocket, &x, 1024, 0); 
        printf("[Client] %d \n", x);
    
        close(ClientSocket);
        close(ServerSocket);
        return 0;
    }
    Client
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netdb.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    
    int x;
    
    int main()
    {
        char ServerIP[16];
        int PORTNR;
        
        char DataIN[1024];
        char DataOUT[1024];
    
        printf("Client startet! \n");
        
        /***** IP Eingabe *****/   
        printf("IP Eingeben: \n"); 
        fgets(ServerIP, 16, stdin);
        //scanf("%s", ServerIP);
    
        printf("PortNr Eingeben: \n"); 
        scanf("%d", &PORTNR);
    
        /***** Socket erzeugen *****/
        int ClientSocket = socket(AF_INET6, SOCK_STREAM, 0);
        if (ClientSocket < 0){printf("Erzeugen des Socket fehlgeschlagen!\n"); return EXIT_SUCCESS;}
        else {printf("Socket erzeugt!\n Verbindung zu %s :%d wird hergestellt...\n", ServerIP, PORTNR);}
        
        /***** Verbindung herstellen *****/
        struct sockaddr_in6 ServerAddr;
     
        memset(&ServerAddr, 0, sizeof (ServerAddr));
        ServerAddr.sin6_family = AF_INET;
        ServerAddr.sin6_port = htons(PORTNR);
        inet_pton(AF_INET6, "ServerIP", &ServerAddr.sin6_addr);
    
        if(connect(ClientSocket, (struct sockaddr*)&ServerAddr, sizeof(ServerAddr)) == 0){
        printf("Verbindung zum Server wurde hergestellt!\n");
        }
        else {
            char IP[16];
            inet_ntop(AF_INET6, &ServerAddr, IP, 16);        
            printf("Verbindungsfehler! IP Adresse = %s Port = %d \n", IP ,PORTNR);
            return EXIT_SUCCESS;
            }
        
        for(;;){ 
            if(recv(ClientSocket, DataIN, 1024, 0) !=0){
                printf("%s\n", DataIN); 
                memset(DataIN,0,strlen(DataIN));            
            }
            //if(fgets(DataOUT, 1024, stdin) != 0){send(ClientSocket, DataOUT, strlen(DataOUT), 0);}
            scanf("%d", &x);
            send(ClientSocket, &x, sizeof(x), 0); 
            
        }
        
        close(ClientSocket);
        return 0;
    }
    Geändert von MikeK (09.11.2021 um 13:41 Uhr)

  2. #2
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    10.04.2005
    Ort
    Bad Aibling
    Beiträge
    212
    Hallo MikeK,

    ich habe das mal in einer C++ Klasse so gebaut das es ohne Änderung mit IPv4 und IPv6 funktioniert.
    Die Log-Klasse gibt es bei Dir natürlich nicht.

    Der folgenden Teil macht die Auflösung von Domainnamen zu IP Adresse:
    Code:
    // Parameter so einstellen das Ipv4 und Ipv6 Adressen gesucht werden.
      stIntParameter = {0};
      stIntHostInfo  = {0};
      stIntParameter.ai_family   = AF_UNSPEC;   // Beide Versionen IPv4 und IPv6
      stIntParameter.ai_socktype = SOCK_STREAM; // Tcp Stream Socket
    
    // Suche die Daten zu Netzwerkschnittstelle.
      int iRc = getaddrinfo (strIntDomainName.c_str (), NULL, &stIntParameter, &stIntHostInfo);
      if (iRc != 0)
      {
      // Debug Messages
        pIntLog->setLogLevel ("Error");
        pIntLog->sendMessage (std::string (__FILE__) + " - Call: DnsClient::getIpAdr () - getaddrinfo: " + gai_strerror (iRc));
        pIntLog->sendMessage (std::string (__FILE__) + " - Call: DnsClient::getIpAdr () - Namensauflösung fehlgeschlagen (Name falsch oder keine Netzwerkverbindung)");
           
        exit (1);
      }
    Hier wird dann die zurückgegebene IP-Adresse in eine String umgewandelt.
    Code:
    // IP-Adresse in einen String umwandeln.
    // stIntHostInfo ist eine verkettete Liste z.B wenn eine Domain mehrere IP-Adressen hat.
      struct addrinfo *aktHostInfo;
      std::vector<char> vecIpAdr;
      vecIpAdr.resize (INET6_ADDRSTRLEN);
    
    // Suche den passenden Eintrag für die gewünschte IP-Adresse.
      void *Adr;
      for (aktHostInfo = stIntHostInfo; aktHostInfo != NULL; aktHostInfo = aktHostInfo->ai_next)
      {
        std::string strIpVer;
    
      // Verschiedene Felder für IPv4 und IPv6
        if (aktHostInfo->ai_family == AF_INET)
        {
          struct sockaddr_in *ipv4 = (struct sockaddr_in *) aktHostInfo->ai_addr;
          Adr = &(ipv4->sin_addr);
          strIpVer = "IPv4";
          break;
        }
        else
        {
          struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *) aktHostInfo->ai_addr;
          Adr = &(ipv6->sin6_addr);
          strIpVer = "IPv6";
          break;
        }
      }
    
    // Konvertiere die IP in einen String und printe es
      inet_ntop (aktHostInfo->ai_family, Adr, vecIpAdr.data (), vecIpAdr.size ());
    
    // IP-Adresse in einen String kopieren.
    // Die folgenden Zeilen zeigen einige Methoden wie man den String aus einem char std::vector in einen std::string bekommt.
      //std::string strIpAdr (vecIpAdr.data (), vecIpAdr.size ());
      //std::string strIpAdr (vecIpAdr.begin (), vecIpAdr.end ());
      std::string strIpAdr;
      strIpAdr.assign (vecIpAdr.data ());
    
    // Debug Messages
      pIntLog->setLogLevel ("Debug");
      pIntLog->sendMessage (std::string (__FILE__) + " - Call: DnsClient::getIpAdr () - " + strIpAdr);
    Ich habe in meinem GIT noch weitere Sachen zur Netzwerkprogrammierung. Die Beispiele sind aber aktuell nicht direkt Übersetzbar weil ich erst einige Anpassungen wegen Änderungen in meinen Klassen noch umsetzen muss. Der GIT Server ist nur über IPv6 erreichbar weil IPv4 Adressen selten und teuer sind.
    Vielleicht hilft es Dir ja weiter: https://git.hts-software.de
    Unterordner: Athena-Api dann den Menüpunkt "tree" und dann den Ordner: Netzwerk

Ähnliche Themen

  1. Roboter mit Thin Client
    Von Johnny5 im Forum PC-, Pocket PC, Tablet PC, Smartphone oder Notebook
    Antworten: 2
    Letzter Beitrag: 20.11.2014, 16:58
  2. OPC Server / Client
    Von fali im Forum C - Programmierung (GCC u.a.)
    Antworten: 0
    Letzter Beitrag: 22.10.2009, 13:25
  3. Server/Client Programm RN-Robbi Steuerung erstellen
    Von BenniX im Forum PC-, Pocket PC, Tablet PC, Smartphone oder Notebook
    Antworten: 3
    Letzter Beitrag: 19.07.2008, 12:27
  4. TCP/IP Client
    Von feitzi im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 9
    Letzter Beitrag: 23.03.2008, 11:45
  5. Thin Client Igel-208
    Von Eris im Forum PC-, Pocket PC, Tablet PC, Smartphone oder Notebook
    Antworten: 11
    Letzter Beitrag: 30.08.2006, 23:18

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiTime Speicher und Akkus