php.de

Zurück   php.de > Webentwicklung > PHP Einsteiger > PHP Tipps 2009

 
 
LinkBack Themen-Optionen Thema bewerten
Alt 06.07.2009, 22:10  
Neuer Benutzer
 
Registriert seit: 06.07.2009
Beiträge: 2
PHP-Kenntnisse:
Anfänger
Duesi befindet sich auf einem aufstrebenden Ast
Standard Sockets -> Prüfen, ob ein neuer Client verbindet?

Moin.
Ich wollte mir vor kurzem einmal die Funktionen für PHP für die Netzwerksockets ( darf man das so sagen? ) anschauen bzw. eine Kleinigkeit damit machen... Naja, sehr weit bin ich nicht gekommen, da ich nicht versteh, wie man nun prüfen kann (ohne das Script anzuhalten), ob ein neuer Client verbindet. Denn setzt man nur socket_accept ein, wird das Script solange blockiert, bis ein neuer Client verbindet. Hebt man diese Blockierung mittels socket_nonblock auf, kommt eine Fehlermeldung, wenn genau in diesem Moment, wenn die Funktion ausgeführt wird, kein Client verbindet?!
(Das könnte man dann als erste Frage deuten. )

Nach etwas Googeln bin ich dann auf folgendes Tutorial gestoßen: Writing Socket Servers in PHP (Zweites Codebeispiel).
So... das Script, dass mir ja helfen sollte verwirrt mich nun aber noch mehr.

Es geht um folgende Zeilen:
PHP-Code:
while(true

    
$read[0] = $sock
    .... 
    if (
in_array($sock$read)) { 
        for (
$i 0$i $max_clients$i++) 
        { 
            if (
$client[$i]['sock'] == null) { 
                
$client[$i]['sock'] = socket_accept($sock); 
                break; 
            } 
        } 
    } 
    .... 

.... 
So... $sock enthält die Resource vom mittels sock_create erstellen Socket... Die Zeilen sollen prüfen, ob ein neuer Client verbindet...
Funktionieren tut das zwar, aber wie? In das array $read kommt $sock, dann wird geprüft ob $sock in $read ist, wenn ja verbindet ein neuer Client? Wenn man $read[] = $sock; schreibt ist $sock ja immer in $read, was hat das dann damit zu tuen, ob ein neuer Client verbindet? Hoffe ihr könnt mich da etwas aufklären.

MfG
Duesi ist offline  
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 07.07.2009, 12:37  
Erfahrener Benutzer
 
Benutzerbild von GelaMu
 
Registriert seit: 05.03.2006
Beiträge: 183
GelaMu
Standard

Ich verstehe zwar nicht, warum du ein non-blocking Socket haben willst, denn PHP unterstützt sowieso keine Threads und solche Socket sind da wenig vom Nutzen, aber wie man das machen könnte, kann ich dir verraten: wie in deinem Beispiel, kannst du ein Array benutzen, in dem die Sockets gespeichert werden. Nennen wir dieses Array mal einfach $sockets. Du hast eine While-Schleife und prüfst bei jedem Durchlauf, ob sich in $sockets ein Wert ungleich null befindet, weil dieser ja der Socket sein muss. Je nach dem, was du machen willst, wenn sich ein neuer Klient angemeldet hat, kannst du per socket_accept($sockets[$freie_platz]) auf neue Kliente warten, wärend der aktuellen Klient bedient wird. Wie du ja weißt, blockiert socket_accept() nicht, weil du das ganze zuvor auf non-blocking gestellt hast, deshalb kannst du nach socket_accept() gleich weitermachen, ohne zu warten.

PHP-Code:

// Socket einrichten usw. ...
$maxClients 10;
$sockets array_fill(0$maxClientsnull);
// vor der Schleife muss irgendein Schlüssel aus $sockets mit socket_accept()
// gekoppelt werden, da sonst in der Schleife alle Werte aus $sockets IMMER
// null-Werte wären
$sockets[0] = socket_accept($socket);
while(
true) {
   foreach(
$socket as $socketId => &$tmpSocket) {
      if(
$tmpSocket !== null) {
         echo 
"Neue Verbindung in \$sockets[$socketId]\n";
         if(
$socketId == $maxClients-1) {
            echo 
"Maximale Anzahl von $maxClients Clients erreicht\n";
         } else {
            
$newSocketId $socketId+1;
            echo 
"Warte auf neue Verbindung auf \$sockets[$newSocketId]\n";
            
$sockets[$newSocketId] = socket_accept($socket);
         }
         
// {{{ Hier geht es weiter mit der Bedienung des Klienten $tmpSocket
         
socket_write($tmpSocket"Halloechen :)\n");
         
socket_close($tmpSocket); // Socket wieder schließen und freigeben
         // }}}
      
}
   }

So, ich hoffe ich konnte es dir einigermaßen verständlich erkären. Der Code von mir ist natürlich nicht voll funktionstüchtig. Ist halt ein Beispiel, zur Veranschaulichung.

Sockets sind eine interessante Sache und es lohnt sich mit ihnen zu beschäftigen.
Also, wünsch dir viel Spaß.

Geändert von GelaMu (07.07.2009 um 12:41 Uhr).
GelaMu ist offline  
Alt 07.07.2009, 18:16  
Neuer Benutzer
 
Registriert seit: 06.07.2009
Beiträge: 2
PHP-Kenntnisse:
Anfänger
Duesi befindet sich auf einem aufstrebenden Ast
Standard

Moin.
Danke erstmal...

Zitat:
Nennen wir dieses Array mal einfach $sockets. Du hast eine While-Schleife und prüfst bei jedem Durchlauf, ob sich in $sockets ein Wert ungleich null befindet, weil dieser ja der Socket sein muss.
Hm, ja, wenn ein Eintrag mit Wet ungeleich 0 enthalten ist, ist es ein Socket ok... Soweit verstehe ichs.

Zitat:
Je nach dem, was du machen willst, wenn sich ein neuer Klient angemeldet hat, kannst du per socket_accept($sockets[$freie_platz]) auf neue Kliente warten, wärend der aktuellen Klient bedient wird.
Und ab hier dann nicht mehr. Woher soll ich nun auf einmal Wissen, ob sich ein neuer Client anmeldet? Also wieder mittels socket_accept? Ok... Aber -> Ohne nonblock wird nun wieder die Anwendung pausiert (ist ja klar), mit nonblock aber denkt die Anwendung nun bei jedem Schleifendurchlauf, dass ein neuer Client verbindet?! (Zumale es eine Fehlermeldung gibt, wenn ich socket_accept unblockiert ausführe, wenn nicht gerade in diesem Moment ein Client verbindet)
So sehe ich das zumindest und wenn ich es ausführe wohl auch php.

-->
PHP-Code:
<?php 
// Timeout
set_time_limit (0); 

// Einstellungen
$address '127.0.0.1'
$port 9000
$maxClients 10;

// Initialisieren
$sockets array_fill(0$maxClientsnull);

// Socket erstellen und einrichten
$socket socket_create(AF_INETSOCK_STREAM0); 
socket_bind($socket$address$port) or die('Could not bind to address'); 
socket_listen($socket); 


// Anwendung
$sockets[0] = socket_accept($socket);

// non-block
socket_set_nonblock($socket);

// Schleife
while(true) {
   foreach(
$sockets AS $socketId => &$tmpSocket) {
      if(
$tmpSocket !== null) {
         echo 
"Neue Verbindung in \$sockets[$socketId]\n";
         if(
$socketId == $maxClients-1) {
            echo 
"Maximale Anzahl von $maxClients Clients erreicht\n";
         } else {
            
$newSocketId $socketId+1;
            echo 
"Warte auf neue Verbindung auf \$sockets[$newSocketId]\n";
            
$sockets[$newSocketId] = @socket_accept($socket);
         }

         
// {{{ Hier geht es weiter mit der Bedienung des Klienten $tmpSocket
         
socket_write($tmpSocket"Halloechen :)\n");
         
socket_close($tmpSocket); // Socket wieder schließen und freigeben
         // }}}
      
}
   }

?>
Duesi ist offline  
Alt 07.07.2009, 22:25  
Erfahrener Benutzer
 
Benutzerbild von GelaMu
 
Registriert seit: 05.03.2006
Beiträge: 183
GelaMu
Standard

Also, ich bin davon ausgegangen, dass socket_set_nonblock() auch so funktioniert, wie erwartet, aber das Manual sagt was anderes: PHP: socket_set_nonblock - Manual

Und dein Script mit einem Marker am Anfang und Ende der Schleife zeigt auch, dass socket_accept() auf sich warten lässt.

PHP-Code:
<?php
// Timeout
set_time_limit (0);

// Einstellungen
$address '127.0.0.1';
$port 9000;
$maxClients 10;

// Initialisieren
$sockets array_fill(0$maxClientsnull);

// Socket erstellen und einrichten
$socket socket_create(AF_INETSOCK_STREAM0);
socket_set_option($socketSOL_SOCKETSO_REUSEADDR1);
socket_bind($socket$address$port) or die('Could not bind to address');
socket_listen($socket);


// Anwendung
$sockets[0] = socket_accept($socket);

// non-block
socket_set_nonblock($socket);

// Schleife
while(true) {
    echo 
"SCHLEIFE ANFANG\n";
    foreach(
$sockets AS $socketId => &$tmpSocket) {
        if(
$tmpSocket !== null) {
            echo 
"Neue Verbindung in \$sockets[$socketId]\n";
            if(
$socketId == $maxClients-1) {
                echo 
"Maximale Anzahl von $maxClients Clients erreicht\n";
            } else {
                
$newSocketId $socketId+1;
                echo 
"Warte auf neue Verbindung auf \$sockets[$newSocketId]\n";
                
$sockets[$newSocketId] = socket_accept($socket);
                exit;
            }

            
// {{{ Hier geht es weiter mit der Bedienung des Klienten $tmpSocket
            
socket_write($tmpSocket"Halloechen :)\n");
            
socket_close($tmpSocket); // Socket wieder schließen und freigeben
            // }}}
        
}
    }
    echo 
"SCHLEIDE ENDE\n";
}
?>
Also, ich würde dir mal raten, das ganze mit pcntl_fork() zu realisieren (funktioniert allerdings nicht unter Windows). Ich habe sogar ein HTTP-Server mit PHP geschrieben, der seit über 2 Jahren ohne Probleme läuft. Ist sehr einfach aufgebaut.

Wenn es dich vielleicht interessieren sollte, ich hab den Server mal in ein Archiv gepackt (welches auch auf diesem Server liegt): http://gelamu.de:1984/php-http-server.7z

Wenn was unverständlich sein sollte, kannst ich dir gerne weiterhelfen.
GelaMu ist offline  
 


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
SSL Verbindung zum Client prüfen Broadcast PHP-Fortgeschrittene 2 23.02.2007 20:46

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
php socket client, php socket mehrere clients, php client socket, socket einrichten, java überprüfen ob ob sich ein client verbindet, php socket_accept blocks, http://www.php.de/php-einsteiger/56809-sockets-gt-pruefen-ob-ein-neuer-client-verbindet.html, php socket überprüfen, server online überprüfen php sock, socket verbindungsversuch ohne client, prüfen ob socket online ist php, c socket prüfen ob sich ein client verinden will, wie verbindet man einen socket, php socket server, php socket socket_accept überprüfenm, mit php prüfen einer socket verbindung, echo \neuer client angemeldet:, php socket example clients, sockets php prüfen, &amp gt

Alle Zeitangaben in WEZ +2. Es ist jetzt 16:19 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum