Parallele Verbindungen



  • Hallo Kollegen,

    ich hab im Forum nach parallelen Verbindungen gesucht, bin aber auf nichts gestoßen. Weiß jemand wie man in einem Programm mehrere Clienten erstellt, die dann z.B. alle einen bestimmten Teil einer Datei an den Server schicken. Das lässt sich, denke ich, mit Threads machen. Aber was muss alles in die Threads hinein? Kann ich mit dem gleichen Socket in allen Threads arbeiten, oder muss ich für jeden Thread einen Neuen erstellen?
    D.h. muss ich das jedes Mal in den Thread schreiben:

    Socket = socket(AF_INET, SOCK_STREAM, 0);
          Adressinfo.sin_family = AF_INET;
          Adressinfo.sin_addr.s_addr = inet_addr("127.0.0.1");//Ip
          Adressinfo.sin_port = htons(12345);
          Laenge = sizeof(Adressinfo);
    
          Verbindung = connect(Socket, (struct sockaddr *)&Adressinfo, Laenge);
          if (Verbindung == 0)
          {
                           printf("Verbindungsaufbau erfolgreich!\n");
                           break;
          }
    

    Oder reicht es, das einmal zu schreiben und alles über diesen Socket zu schicken?
    Meine andere Frage bezieht sich auf den Server. Wie mach ich es, dass dieser z.B. 10 Datenpakete auf einmal empfängt.

    Danke für eure Antworten,
    Felix



  • was soll das bringen?



  • Das soll eine schnellere Übertragung bringen. Wenn man z.B. ein Bild in 4 Datenteile teilt und diese von den Threads übertragen lässt, ist die Übertragung doch viermal so schnell, als wenn man das ganze Bild auf einmal überträgt.





  • Achso, aber würde das trotzdem gehen?



  • wie kommsten du da drauf Felix? Vergessen wir die Physik und machen einfach 456734876378267693 Threads und schon können wir terrabyteweise daten in ein paar ms um die Welt schicken? NeeNee ... was du vorhast ist realisierbar, aber unsinnig (bringt nix).



  • Und was ist, wenn man 2 odere mehrere Datenpakete auf einmal schicken will, wie z.B. beim Windows Remote Desktop Programm. Da werden die Mausdaten, das Bildschirmbild und die Tastaturdaten alle auf einmal geschickt, oder mein ich das nur?



  • Jetzt bin ich verwirrt:

    Von folgender Website: http://www.cappoodoo.de/?id=download&s=ak&action=showall&category=f7f2e0d076&lang=de

    Fresh Download - Version 7.98

    Fresh Download ist ein einfach zu benutzender, kostenloser Download-Manager, der durch mehrere parallele Verbindungen zur selben Datei die Download-Geschwindigkeit erheblich erhöhen kann. Die Software kommt vollkommen ohne Bannerwerbung (welche auch Traffic verursacht), oder Spyware aus.

    Features:
    Sehr schnelle Downloads aller Arten von Dateien über FTP, HTTP und HTTPS mittels Ihrer aktuellen Internetverbindung (Modem, Kabel, DSL/ADSL, Satellit, T1, etc.)
    Pausieren und fortsetzen abgebrochener Downloads, Wiederherstellung nach einer unterbrochenen Internetverbindung.
    Mehrere parallele Verbindungen (Standard 4, bis zu 8 Verbindungen) zur selben Datei, um die größtmögliche Download-Geschwindigkeit zu erreichen. Laut Benutzerberichten kann dies Methode Ihre Downloads bis zu 400% beschleunigen.
    Einfache Integrierung in alle derzeit gängigen Browser und lauffähig auf jedem Windows-System ab Windows 95 - Vista.
    Taskplaner: Planen der Downloads für Perioden mit geringem Datenverkehr.
    Zwischenablage-Überwachung und Drag'n'Drop Funktion. Erfassssung aller URLs aus jeder beliebigen Anwendung.
    Antivirus-Unterstützung: Prüft heruntergeladene Dateien auf Schädlinge mittels Ihrer derzeit installierten Antiviren-Software.
    Downloadmöglichkeit von Passwortgeschützen Seiten des HTTP-, oder FTP-Protokolls.
    Proxyserver-Unterstützung via HTTP-, oder FTP-Protokoll.
    Vorschau des Inhaltes gepackter (ZIP) Dateien.



  • Trau keiner Statistik die du nicht selbst gefälscht hast 🤡

    Edit: Rest entfernt, zu vorschnell geschrieben.



  • Das Teil nützt wahrscheinlich die Tatsache aus, dass viele Download-Server die Bandbreite pro Verbindung künstlich reduzieren. Wenn man jetzt mehrere Socket-Verbindungen einsetzt kann man das umgehen. Du musst dafür mehrere Sockets erstellen. Threads sind nicht notwendig.



  • Wie funktionieren die parallelen Verbindungen sonst, wenn es keine Threads sind?

    Und da steht:

    Mehrere parallele Verbindungen (Standard 4, bis zu 8 Verbindungen) zur selben Datei, um die größtmögliche Download-Geschwindigkeit zu erreichen. Laut Benutzerberichten kann dies Methode Ihre Downloads bis zu 400% beschleunigen.



  • @hajoe: Danke für Antwort. Aber ich will die Sockets ja gleichzeitig verwenden, also brauch ich doch die Threads, oder?



  • Wie ist so ein Server mit Threads aufgebaut?



  • Ich hab jetzt mal selber einen Server geschrieben. Allerdings funktioniert der noch nicht so richtig:

    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #define BUF_SIZE 255
    
    int Port = 12345;
    
    long rc;
    SOCKET acceptSocket;
    SOCKET connectedSocket;
    SOCKADDR_IN addr;
    
    int Clientenanzahl;
    
    int Verbindung;
    
    char Zahl1[900];
    char Zahl2[900];
    
    FD_SET fdSet;
    SOCKET clients[100];
    int i;
    
    int antwortlaenge1;
    int antwortlaenge2;
    int Laenge1;
    int Laenge2; 
    char buffer1[100];
    char buffer2[100];
    char juhu[900];
    
    typedef struct MyData {
        int data;
    } MYDATA, *PMYDATA;
    
    PMYDATA pDataArray[100];
    
    int startWinsock(void)
    {
      WSADATA wsa;
      return WSAStartup(MAKEWORD(2,0),&wsa);
    }
    
    DWORD WINAPI NeuerClient(LPVOID lpParam) 
    { 
        HANDLE hStdout;
        PMYDATA pDataArray;
        int nummer;
    
        TCHAR msgBuf[BUF_SIZE];
        size_t cchStringSize;
        DWORD dwChars;
    
        hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
        if( hStdout == INVALID_HANDLE_VALUE )
            return 1;
    
        pDataArray = (PMYDATA)lpParam;
    
        nummer=pDataArray->data;
    
        printf("%d.Client\n",nummer);
        while(1) 
        { 
                 antwortlaenge1 = recv(clients[nummer], buffer1, 1, 0);
                 buffer1[antwortlaenge1] = '\0';
                 Laenge1 = atoi(buffer1);
    
                 antwortlaenge2 = recv(clients[nummer], buffer2, Laenge1, 0);
                 buffer2[antwortlaenge2] = '\0';
                 Laenge2 = atoi(buffer2);
    
                 Verbindung=recv(clients[nummer],juhu,Laenge2,0); 
                 if(Verbindung==SOCKET_ERROR) 
                 { 
                                  break;
                 }
                 juhu[Verbindung]='\0';
        }
    return 0; 
    }
    
    int main(int argc, char *argv[])
    {
    
      rc=startWinsock();
      if(rc!=0)
      {
             printf("\r\nWinsock konnte nicht gestartet werden!\r\n");
             return 0;
      }
      else
      {
              printf("\r\nWinsock gestartet!\r\n");
      }
    
      acceptSocket=socket(AF_INET,SOCK_STREAM,0);
      if(acceptSocket==INVALID_SOCKET)
      {
                    printf("Fehler: Der Socket konnte nicht erstellt werden!\r\n");
                    return 0;
      }
      else
      {
                    printf("Socket erstellt!\r\n");
      }
    
      memset(&addr,0,sizeof(SOCKADDR_IN));
      addr.sin_family=AF_INET;
      addr.sin_port=htons(Port);
      addr.sin_addr.s_addr=ADDR_ANY;
    
      rc=bind(acceptSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN));
      if(rc==SOCKET_ERROR)
      {
                 printf("Socket konnte nicht an den Port 12345 gebunden werden!\r\n");
                 return 0;
      }
      else
      {
                 printf("Socket an Port 12345 gebunden\r\n");
      }
    
      rc=listen(acceptSocket,100);
      if(rc==SOCKET_ERROR)
      {
                          printf("acceptSocket ist nicht im listen Modus!\r\n");
                          return 0;
      }
      else
      {
                          printf("acceptSocket ist im listen Modus...\r\n"); 
      }
      while(1) 
      { 
                sleep(10);
                FD_ZERO(&fdSet); // Inhalt leeren
                FD_SET(acceptSocket,&fdSet); // Den Socket der verbindungen annimmt hinzufügen
    
        // alle gültigen client sockets hinzufügen (nur die die nicht INVALID_SOCKET sind)
                for(i=0;i<100;i++) 
                {
                            if(clients[i]!=INVALID_SOCKET)
                            {
                                           FD_SET(clients[i],&fdSet);
                            }
                }
    
                rc=select(0,&fdSet,NULL,NULL,NULL); // nicht vergessen den ersten parameter bei anderen betriebssystem anzugeben
                if(rc==SOCKET_ERROR) 
                {
                  //return 0;
                }
    
                // acceptSocket is im fd_set? => verbindung annehmen (sofern es platz hat)
                if(FD_ISSET(acceptSocket,&fdSet)) 
                {
                          // einen freien platz für den neuen client suchen, und die verbingung annehmen
                          for(i=0;i<100;i++)
                          {
                                       if(clients[i]==INVALID_SOCKET) 
                                       {
                                                  clients[i]=accept(acceptSocket,NULL,NULL);//akzeptieren
                                                  printf("Neuer Client\n");
    
                                                  pDataArray[i] = (PMYDATA) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,sizeof(MYDATA));
                                                  pDataArray[i]->data = i;
    
                                                  CreateThread(NULL, 0, NeuerClient, pDataArray[i], 0, NULL);
                                                  break;
                                       }
                          }
                }
    
                // prüfen welcher client sockets im fd_set sind
                for(i=0;i<100;i++) 
                {
                            if(clients[i]==INVALID_SOCKET)
                            {
                                              continue; // ungültiger socket, d.h. kein verbunder client an dieser position im array
                            }
                            if(FD_ISSET(clients[i],&fdSet))
                            {
                                          //Client will was schicken                                                                                 
                            }
                }
    
      } 
    
      return 0;
    }
    

    Was ist da falsch?



  • Nein, Threads sind nicht notwendig. Ich wäre mit Threads überhaupt sparsam. Das Zauberwort heißt "Asynchron". Du musst die FD_XXX Funktionen ersetzen durch WSA_XXX, also WSAWaitForMultipleEvents usw. Dann kannst Du in einem Thread (dem Hauptthread der Anwendung) beliebig viele Sockets bedienen. Dieses ganze FD_XXX Zeug funktioniert unter Windows nicht richtig!



  • Dieses ganze FD_XXX Zeug funktioniert unter Windows nicht richtig!

    rofl. klar funktioniert das.



  • hajoe schrieb:

    Dieses ganze FD_XXX Zeug funktioniert unter Windows nicht richtig!

    olo 👍



  • Schon mal was von "Editieren" gehört? Das gibts in jedem noch so verschissenen Forum, und bestimmt nicht, damit es nicht benutzt wird ... nur so btw.



  • @ hajoe: Das Problem ist jetzt nur, dass ich mit Dev-C++ arbeite und da funktioniert getaddrinfo und freeaddrinfo irgendwie nicht. Ich hab alle möglichen .a eingebunden und die richtigen Bibliotheken, aber es geht nicht. Geht das auch ohne die Funktionen oder muss ich doch auf VC++ umsteigen?



  • Ich verstehe das Problem nicht, Du musst doch nur die Funktionen der WinSocket-API einbinden. Übrigens, wenn hier jemand meint die FD_XXX Funktionen tun genau das, was sie sollen, kann er sie ja verwenden, ich tu's nicht (aus Erfahrung).


Anmelden zum Antworten