PHP Australia Conference 2015

Beispiele

Beispiel #1 Socket-Beispiel: Einfacher TCP/IP-Server

Dieses Beispiel zeigt einen einfachen Echo-Server. Passen Sie die Variablen address und port an Ihre Systemumgebung an und führen Sie das Skript aus. Dann können Sie sich mit einem Befehl wie: telnet 192.168.1.53 10000 (bei dem adress und port an Ihre Umgebung angepasst ist) mit dem Server verbinden. Alles, was Sie eingeben, wird an den Server geschickt und von diesem wieder an Sie zurückgegeben. Um die Verbindung zu trennen, geben Sie 'quit' ein.

#!/usr/local/bin/php -q
<?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.1.53';
$port 10000;

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";
}

do {
    if ((
$msgsock socket_accept($sock)) === false) {
        echo 
"socket_accept() fehlgeschlagen: Grund: " socket_strerror(socket_last_error($sock)) . "\n";
        break;
    }
    
/* Anweisungen senden. */
    
$msg "\nWillkommen auf dem PHP-Testserver.  \n" .
        
"Um zu beenden, geben Sie 'quit' ein. Um den Server herunterzufahren, geben Sie 'shutdown' ein.\n";
    
socket_write($msgsock$msgstrlen($msg));

    do {
        if (
false === ($buf socket_read ($msgsock2048PHP_NORMAL_READ))) {
            echo 
"socket_read() fehlgeschlagen: Grund: " socket_strerror(socket_last_error($msgsock)) . "\n";
            break 
2;
        }
        if (!
$buf trim ($buf)) {
            continue;
        }
        if (
$buf == 'quit') {
            break;
        }
        if (
$buf == 'shutdown') {
            
socket_close ($msgsock);
            break 
2;
        }
        
$talkback "PHP: Sie haben '$buf' eingegeben.\n";
        
socket_write ($msgsock$talkbackstrlen ($talkback));
        echo 
"$buf\n";
    } while (
true);
    
socket_close ($msgsock);
} while (
true);

socket_close ($sock);
?>

Beispiel #2 Socket-Beispiel: Einfacher TCP/IP-Client

Dieses Beispiel zeigt einen einfachen HTTP-Client für eine einmalige Verbidung. Es wird eine Verbindung zu einer Seite geöffnet, ein HEAD-Request gesendet, die Antwort zurück übertragen und die Verbindung wieder geschlossen.

<?php
error_reporting
(E_ALL);

echo 
"<h2>TCP/IP-Verbindung</h2>\n";

/* Den Port für den WWW-Dienst ermitteln. */
$service_port getservbyname('www''tcp');

/* Die  IP-Adresse des Zielrechners ermitteln. */
$address gethostbyname('www.example.com');

/* Einen TCP/IP-Socket erzeugen. */
$socket socket_create(AF_INETSOCK_STREAMSOL_TCP);
if (
$socket === false) {
    echo 
"socket_create() fehlgeschlagen: Grund: " socket_strerror(socket_last_error()) . "\n";
} else {
    echo 
"OK.\n";
}

echo 
"Versuche, zu '$address' auf Port '$service_port' zu verbinden ...";
$result socket_connect($socket$address$service_port);
if (
$result === false) {
    echo 
"socket_connect() fehlgeschlagen.\nGrund: ($result) " socket_strerror(socket_last_error($socket)) . "\n";
} else {
    echo 
"OK.\n";
}

$in "HEAD / HTTP/1.1\r\n";
$in .= "Host: www.example.com\r\n";
$in .= "Connection: Close\r\n\r\n";
$out '';

echo 
"HTTP HEAD request senden ...";
socket_write($socket$instrlen($in));
echo 
"OK.\n";

echo 
"Serverantwort lesen:\n\n";
while (
$out socket_read($socket2048)) {
    echo 
$out;
}

echo 
"Socket schließen ...";
socket_close($socket);
echo 
"OK.\n\n";
?>

add a note add a note

User Contributed Notes 3 notes

up
19
javier,javiern at gmail dot com
2 years ago
You can easily extend the first example to handle any number of connections instead of jsut one

#!/usr/bin/env php
<?php
error_reporting
(E_ALL);

/* Permitir al script esperar para conexiones. */
set_time_limit(0);

/* Activar el volcado de salida implícito, así veremos lo que estamo obteniendo
* mientras llega. */
ob_implicit_flush();

$address = '127.0.0.1';
$port = 10000;

if ((
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
    echo
"socket_create() falló: razón: " . socket_strerror(socket_last_error()) . "\n";
}

if (
socket_bind($sock, $address, $port) === false) {
    echo
"socket_bind() falló: razón: " . socket_strerror(socket_last_error($sock)) . "\n";
}

if (
socket_listen($sock, 5) === false) {
    echo
"socket_listen() falló: razón: " . socket_strerror(socket_last_error($sock)) . "\n";
}

//clients array
$clients = array();

do {
   
$read = array();
   
$read[] = $sock;
   
   
$read = array_merge($read,$clients);
   
   
// Set up a blocking call to socket_select
   
if(socket_select($read,$write = NULL, $except = NULL, $tv_sec = 5) < 1)
    {
       
//    SocketServer::debug("Problem blocking socket_select?");
       
continue;
    }
   
   
// Handle new Connections
   
if (in_array($sock, $read)) {       
       
        if ((
$msgsock = socket_accept($sock)) === false) {
            echo
"socket_accept() falló: razón: " . socket_strerror(socket_last_error($sock)) . "\n";
            break;
        }
       
$clients[] = $msgsock;
       
$key = array_keys($clients, $msgsock);
       
/* Enviar instrucciones. */
       
$msg = "\nBienvenido al Servidor De Prueba de PHP. \n" .
       
"Usted es el cliente numero: {$key[0]}\n" .
       
"Para salir, escriba 'quit'. Para cerrar el servidor escriba 'shutdown'.\n";
       
socket_write($msgsock, $msg, strlen($msg));
       
    }
   
   
// Handle Input
   
foreach ($clients as $key => $client) { // for each client       
       
if (in_array($client, $read)) {
            if (
false === ($buf = socket_read($client, 2048, PHP_NORMAL_READ))) {
                echo
"socket_read() falló: razón: " . socket_strerror(socket_last_error($client)) . "\n";
                break
2;
            }
            if (!
$buf = trim($buf)) {
                continue;
            }
            if (
$buf == 'quit') {
                unset(
$clients[$key]);
               
socket_close($client);
                break;
            }
            if (
$buf == 'shutdown') {
               
socket_close($client);
                break
2;
            }
           
$talkback = "Cliente {$key}: Usted dijo '$buf'.\n";
           
socket_write($client, $talkback, strlen($talkback));
            echo
"$buf\n";
        }
       
    }       
} while (
true);

socket_close($sock);
?>
up
-6
Anonymous
5 months ago
A more object oriented example of the server

#!/usr/bin/env php
<?php

class MySocketServer
{
    protected
$socket;
    protected
$clients = [];
    protected
$changed;
   
    function
__construct($host = 'localhost', $port = 9000)
    {
       
set_time_limit(0);
       
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
       
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);

       
//bind socket to specified host
       
socket_bind($socket, 0, $port);
       
//listen to port
       
socket_listen($socket);
       
$this->socket = $socket;
    }
   
    function
__destruct()
    {
        foreach(
$this->clients as $client) {
           
socket_close($client);
        }
       
socket_close($this->socket);
    }
   
    function
run()
    {
        while(
true) {
           
$this->waitForChange();
           
$this->checkNewClients();
           
$this->checkMessageRecieved();
           
$this->checkDisconnect();
        }
    }
   
    function
checkDisconnect()
    {
        foreach (
$this->changed as $changed_socket) {
           
$buf = @socket_read($changed_socket, 1024, PHP_NORMAL_READ);
            if (
$buf !== false) { // check disconnected client
               
continue;
            }
           
// remove client for $clients array
           
$found_socket = array_search($changed_socket, $this->clients);
           
socket_getpeername($changed_socket, $ip);
            unset(
$this->clients[$found_socket]);
           
$response = 'client ' . $ip . ' has disconnected';
           
$this->sendMessage($response);
        }
    }
   
    function
checkMessageRecieved()
    {
        foreach (
$this->changed as $key => $socket) {
           
$buffer = null;
            while(
socket_recv($socket, $buffer, 1024, 0) >= 1) {
               
$this->sendMessage(trim($buffer) . PHP_EOL);
                unset(
$this->changed[$key]);
                break;
            }
        }
    }
   
    function
waitForChange()
    {
       
//reset changed
       
$this->changed = array_merge([$this->socket], $this->clients);
       
//variable call time pass by reference req of socket_select
       
$null = null;
       
//this next part is blocking so that we dont run away with cpu
       
socket_select($this->changed, $null, $null, null);
    }
   
    function
checkNewClients()
    {
        if (!
in_array($this->socket, $this->changed)) {
            return;
//no new clients
       
}
       
$socket_new = socket_accept($this->socket); //accept new socket
       
$first_line = socket_read($socket_new, 1024);
       
$this->sendMessage('a new client has connected' . PHP_EOL);
       
$this->sendMessage('the new client says ' . trim($first_line) . PHP_EOL);
       
$this->clients[] = $socket_new;
        unset(
$this->changed[0]);
    }
   
   
    function
sendMessage($msg)
    {
        foreach(
$this->clients as $client)
        {
            @
socket_write($client,$msg,strlen($msg));
        }
        return
true;
    }
}

(new
MySocketServer())->run();
?>
up
-31
Anonymous
1 year ago
The variable $in in TCP client exampe really needs to end with '\n' or otherwise it doesn't fire the read event in the server side (at least in my Delphi program).
To Top