Ankündigung

Einklappen
Keine Ankündigung bisher.

socket_recv und socket_write dauert sehr lange

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • socket_recv und socket_write dauert sehr lange

    Hallo Leute,

    Ich habe eine Frage zur Server-/Clientprogrammierung. Und zwar wollte ich mit Xampp einen PHP-Server programmieren, der auf TCP Verbindungen wartet.
    Wenn sich jemand verbindet und eine Nachricht schickt, schickt der Server die gleiche Nachricht zurück. Das Ganze klappt auch, nur dauert das etwas lange
    (zwischen unter 1 Sek und 3Minuten). Das Verbindendes Clients und abschicken der Nachricht geht sehr schnell. Das Warten auf die Antwort dauert lange.
    Gibt es da Einstellungen, dass ich das schneller hinbekomme kann? ...Weiß auch nicht, ob ich beser Port 80 oder irgendeinen ala 34567 nehmen
    soll. Mein derzeitiger Code sieht so aus:
    PHP-Code:
    <html>
    <head>
    <meta charset="UTF-8" />
    </head>
    <body>
    <?php
    error_reporting 
    (E_ALL);

    /* Das Skript wartet auf hereinkommende Verbindungsanforderungen. */
    set_time_limit(0);

    /* Die implizite Ausgabe wird eingeschaltet, so dass man sieht,
     * was gesendet wurde. */
    ob_implicit_flush ();

    $address '192.168.xxx.xxx';
    $port 80;

    if((
    $sock socket_create(AF_INETSOCK_STREAMSOL_TCP)) === false) {
        echo 
    "socket_create() fehlgeschlagen: Grund: " socket_strerror(socket_last_error()) . "\n";
    }

    if (
    socket_bind($sock$address$port) === false) {
        echo 
    "socket_bind() fehlgeschlagen: Grund: " socket_strerror(socket_last_error($sock)) . "\n";
    }

    if (
    socket_listen($sock5) === false) {
        echo 
    "socket_listen() fehlgeschlagen: Grund: " socket_strerror(socket_last_error($sock)) . "\n";
    }
    if ((
    $msgsock socket_accept($sock)) === false) {
        echo 
    "socket_accept() fehlgeschlagen: Grund: " socket_strerror(socket_last_error($sock)) . "\n";
        break;
    }

    //$buf = socket_read($msgsock,4);//, PHP_BINARY_READ)
    socket_recv($msgsock$buf4MSG_WAITALL );
    socket_write($msgsock$bufstrlen($buf));

    socket_close ($msgsock);

    socket_close ($sock);
    ?>
    </body>
    </html>
    Falls der Code des Clients gewünscht wird, kann ich den auch noch reinststellen.
    Danke schonmal!
    Mfg theundertaker

    ps: eventuell bin ich im falschen Unterforum. War mir nicht sicher, ob es in Einsteiger oder Server-hostig gehört.
    pps: könnte evtl die funktion tcp_nodelay() Abhilfe schaffen, die ich dann per socket_set_option() einstelle?

  • #2
    Port 80 für einen eigenen TCP-Server zu nehmen, schlechter geht es kaum, denn dort horcht dein Webserver. Und PHP Server ohne socket_select , da sind Verklemmungen vorprogrammiert.

    Schau hier: Writing Socket Servers in PHP

    Kommentar


    • #3
      Danke jspit, ich werde das mal direkt nach dem Mittagessen durcharbeiten.

      Kommentar


      • #4
        Hab soeben nochmal in den Link geklickt. Ist schon etwas älter, also nicht alles 1:1 übernehmen. Fürs Verständnis ist dies jedoch ok.

        Kommentar


        • #5
          // this was wrong

          Kommentar


          • #6
            @moma: _bind und _listen hatte ich doch drin, oder verstehe ich dich falsch?
            Ansonsten, der Link ist gut, ich muss mir nur noch mal genau Arrays in php und Socket_Select() anschauen, um das 100% zu verstehen was da abläuft, aber dann denke ich sollte das klappen. Eine Frage habe ich noch, wenn ich jetzt zB. auf Port 9000 höre, dann muss ich doch wahrscheinlich den Port in der Firewall durchlassen damit das alles dann läuft?

            Kommentar


            • #7
              : _bind und _listen hatte ich doch drin, oder verstehe ich dich falsch?
              oh man, heute bin ich auf beiden augen blind, ich nehm alles zurück.

              Kommentar


              • #8
                kein Ding

                Kommentar


                • #9
                  Was ich aber nicht verstehe, wenn ich es über Port 9000 versuche und in der Windows 8.1 Firewall entsprechende TCP Regeln erstellt habe( hab sogar auch udp erstellt), kommt nach 3 min der Fehler "connect() failed: Connection timed out".
                  Wenn ich die Firewall komplett abstelle, schafft es der Client auch nicht zu connecten. Es kommt direkt der Fehler "connect() failed: Connection refused". Versteh das ganze nicht ganz so. Deshalb hatte ich erst auch Port 80 gewählt, weil der ja offen ist.Das komische ist ja, da hat es noch am besten funktioniert...

                  Kommentar


                  • #10
                    Da unterliegst du einen Irrtum. Sofern dein Webserver auf Port 80 läuft, und davon gehe ich aus, kann das nicht funktionieren.
                    Du solltest Debugging betreiben, die echo's rausnehmen und mit Logs arbeiten. Dafür stehen professionelle Tools wie XDebug zur Verfügung.
                    Ich nutze fürs Debugging eine Klasse, die ohne eine Installation überall läuft.
                    Beispiel:
                    PHP-Code:
                    <?php
                    error_reporting
                    (-1);

                    //Download jspit.de
                    require __DIR__."/../../class/class.debug.php";

                    debug::log("sock1.html",true);  //Fehler + Warnungen mitloggen

                    $address '0.0.0.0';  //localhost
                    $port 80;

                    $sock socket_create(AF_INETSOCK_STREAMSOL_TCP);
                    debug::write("sock",$sock);

                    $bindOk socket_bind($sock$address$port);
                    debug::write("bindOk + error"$bindOksocket_strerror(socket_last_error($sock)));

                    socket_close ($sock);
                    Die Loggerinformationen werden als HTML generiert und können per Browser angezeigt werden.
                    Das Ergebnis sieht dann in etwa so aus und zeigt, daß es mit Port 80 nicht laufen kann.
                    debug_log_socket.png

                    LG jspit

                    Kommentar


                    • #11
                      Ja, mein Webserver läuft auf Port 80, und dass die echos blöd waren, war mir schon klar, ich hatte das nur irgendwo aus dem netz kopiert, deshalb waren die noch drin und weil die ja nicht gestört haben.
                      Und zum debuggen. Danke, das hatte mich gestört, dass ich nicht sehen konnte, wo es hapert. Ich benutze mal die Klasse mit Logs . Wenn ich den Fehler dann nicht finde, mach ich das Skript auf ner Linux Maschine
                      Danke und Grüße
                      theundertaker

                      Kommentar


                      • #12
                        also wenn dein script und dein webserver beide an port 80 lauschen sollen, müsste dein eingangsscript den fehler ausgeben; für solche fälle haste doch echo und socket_strerror drin.
                        wenn du sorgen wegen einer möglichen firewall hast, dann kommuniziere eben über 127.0.0.1 oder eine andere localhost addresse, denn die wird sogar win nicht blocken.

                        ich habe aber noch nicht verstanden was lange dauert, das:

                        Zitat von http://php.net/manual/de/function.socket-accept.php
                        Falls es keine wartenden Verbindungen gibt, blockiert die Funktion socket_accept() so lange, bis eine Verbindung angefordert wird. Falls der Socket socket mit den Funktionen socket_set_blocking() oder socket_set_nonblock() auf 'nicht blockieren' gesetzt wurde, wird FALSE zurückgegeben.
                        oder baust du irgendwo ne verbuindung auf.

                        Kommentar


                        • #13
                          Ja ich versuche das ganze ja mit localhost. Xampp lauscht bei mir auf Port 80 und 443. Und die Webseite wollte ich eigentlich auch nicht übern Browser aufrufen, sondern verschiedene Clients darüber kommunizieren lassen.
                          Zu den Fehlermeldungen:
                          Wenn ich auf den localhost einen "Tcplistener" auf Port 80 und der ip des lokalen Recheners lauschen lasse (ob ich 127.0.0.1 oder die lokale ip nehme macht doch keinen Unterschied?), und von einem Client im selben Netzwerk mich auf diese Verbindung einwählen möchte, braucht es zwischen unter 1sek und 3Minuten. Je nach Glück.
                          Wenn ich den "TCP listener" auf einen anderen Port hören lasse und in der WindowsFirewall des localhost diese Ports durchlasse, und dann mich mit dem Client auf dieser Verbindung einwählen möchte, versucht der Client 3min sich mit dem Socket zu verbinden, schafft das nicht und gibt dann den Fehler aus "connect() failed: Connection timed out". connect() ist meine Funktion, in der sich der Client verbinden lassen soll.
                          Wenn ich die Firewall des localhost mit dem tcp listener ausschalte und sich der Client mit dieser TCP verbindung verbinden lassen soll, kommt sofort die Fehelermeldung beim Client "connect() failed: connect refused". Was genau der Grund connect refused heißt hab ich noch nicht gegoogelt. Das Client skript ist in C.
                          ...Ich werden meistens nur 1 client haben, in selteneren Fällen mehrere Clients gleichzeitig, deshalb ist für mich wichtiger, dass es mit einem Client schnell läuft, als das ich mehrere Clients hab. Deshalb hatte ich das Skript auch nur mit einem Client der ne Nachricht schickt, diese zurückbekommt und die Verbindung wird wieder geschlossen. Aber ich werde den Tip von jspit mal befolgen und debuggen., ja und wenn das nicht klappt ansonsten eine andere Maschine nehmen. ^^

                          Kommentar

                          Lädt...
                          X