Forum und email

Funciones de Socket

Introducción

La extensión de sockets implementa una interfaz de bajo nivel con las funciones de comunicación de sockets, basadas en los populares sockets BSD, ofreciendo la posibilidad de actuar como un servidor de sockets, así como cliente.

Para una interfaz más genérica de sockets del lado del cliene, vea stream_socket_client(), stream_socket_server(), fsockopen(), y pfsockopen().

Cuando use estas funciones, es importante recordar que, aunque muchas de ellas tienen nombres idénticos a sus contrapartes en C, usualmente cuentan con declaraciones distintas. Por favor, asegúrese de leer las descripciones, con el propósito de evitar confusiones.

Aquellos que no se encuentran familiarizados con programación de sockets, pueden encontrar una gran cantidad de material útil en las páginas man de Unix apropiadas, y existe una enorme cantidad de información estilo tutorial sobre programación de sockets en C en la web, mucha de la cual puede aplicarse, con ligeras modificaciones, a la programación de sockets en PHP. El » FAQ de Sockets Unix puede ser un buen comienzo.

Note: This extension has been moved to the » PECL repository and is no longer bundled with PHP as of PHP 5.3.0.

Requisitos

No se necesitan bibliotecas externas para construir esta extensión

Instalación

The socket functions described here are part of an extension to PHP which must be enabled at compile time by giving the --enable-sockets option to configure.

Note: El soporte para IPv6 fue agregado en PHP 5.0.0 .

Configuración en tiempo de ejecución

Esta extensión no tiene directivas de configuración en php.ini.

Tipos de recursos

socket_accept(), socket_create_listen() y socket_create() devuelven recursos de socket.

Constantes predefinidas

Estas constantes están definidas por esta extensión y estarán disponibles solamente cuando la extensión ha sido o bien compilada dentro de PHP o grabada dinámicamente en tiempo de ejecución.

AF_UNIX (integer)
AF_INET (integer)
AF_INET6 (integer)
SOCK_STREAM (integer)
SOCK_DGRAM (integer)
SOCK_RAW (integer)
SOCK_SEQPACKET (integer)
SOCK_RDM (integer)
MSG_OOB (integer)
MSG_WAITALL (integer)
MSG_PEEK (integer)
MSG_DONTROUTE (integer)
MSG_EOR (integer)
MSG_EOF (integer)
SO_DEBUG (integer)
SO_REUSEADDR (integer)
SO_KEEPALIVE (integer)
SO_DONTROUTE (integer)
SO_LINGER (integer)
SO_BROADCAST (integer)
SO_OOBINLINE (integer)
SO_SNDBUF (integer)
SO_RCVBUF (integer)
SO_SNDLOWAT (integer)
SO_RCVLOWAT (integer)
SO_SNDTIMEO (integer)
SO_RCVTIMEO (integer)
SO_TYPE (integer)
SO_ERROR (integer)
SOL_SOCKET (integer)
PHP_NORMAL_READ (integer)
PHP_BINARY_READ (integer)
SOL_TCP (integer)
SOL_UDP (integer)

Errores de Socket

La extensión de sockets fue escrita para ofrecer una interfaz usable a los poderosos sockets BSD. Se ha tenido cuidado para que las funciones trabajen igualmente bien en implementaciones Win32 y Unix. Casi todas las funciones de sockets pueden fallar bajo ciertas condiciones y por lo tanto emiten un mensaje E_WARNING que describe el error. Algunas veces esto no ocurre conforme al deseo del desarrollador. Por ejemplo, la función socket_read() puede emitir repentinamente un mensaje E_WARNING debido a que la conexión ha sido cerrada inesperadamente. Es común suprimir la advertencia con el operador @ y atrapar el código de error dentro de la aplicación con la función socket_last_error(). Puede llamar la función socket_strerror() con este código de error para recuperar una cadena que describe el error. Vea su descripción para más información.

Note: Los mensajes E_WARNING generados por la extensión de sockets se encuentran en inglés, aunque el mensaje de error recuperado aparecerá dependiendo de la localidad actual (LC_MESSAGES):

Warning - socket_bind() unable to bind address [98]: Die Adresse wird bereits verwendet

Ejemplos

Example#1 Ejemplo de Socket: Servidor TCP/IP simple

Este ejemplo le muestra un servidor simple que repite de vuelta su entrada. Modifique las variables direccion y puerto para que se acomoden a su configuración y ejecútelo. Puede entonces conectarse con el servidor mediante un comando similar a: telnet 192.168.1.53 10000 (en donde la dirección y el puerto se ajustan a su configuración). Cualquier cosa que escriba será entonces impresa en el lado del servidor, y devuelta a su lado. Para desconectarse, ingrese 'salir'.

#!/usr/local/bin/php -q
<?php
error_reporting
(E_ALL);

/* Permitir que el script permanezca en espera de conexiones. */
set_time_limit(0);

/* Habilitar vaciado de salida implícito, de modo que veamos lo que
 * obtenemos a medida que va llegando. */
ob_implicit_flush();

$direccion '192.168.1.53';
$puerto    10000;

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

if (
socket_bind($sock$direccion$puerto) === false) {
    echo 
"socket_bind() falló: motivo: " socket_strerror(socket_last_error($sock)) . "\n";
}

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

do {
    if ((
$mens_sock socket_accept($sock)) === false) {
        echo 
"socket_accept() falló: motivo " socket_strerror(socket_last_error($sock)) . "\n";
        break;
    }
    
/* Enviar instrucciones. */
    
$mensaje "\nBienvenido al Servidor de Prueba PHP. \n" .
               
"Para salir, escriba 'salir'. " .
               
"Para detener el servidor, escriba 'detener'.\n";
    
socket_write($mens_sock$mensajestrlen($mensaje));

    do {
        if (
false === ($buf socket_read($mens_sock2048PHP_NORMAL_READ))) {
            echo 
"socket_read() falló: motivo: " socket_strerror(socket_last_error($mens_sock)) . "\n";
            break 
2;
        }
        if (!
$buf trim($buf)) {
            continue;
        }
        if (
$buf == 'salir') {
            break;
        }
        if (
$buf == 'detener') {
            
socket_close($mens_sock);
            break 
2;
        }
        
$respuesta "PHP: Usted dijo '$buf'.\n";
        
socket_write($mens_sock$respuestastrlen($respuesta));
        echo 
"$buf\n";
    } while (
true);
    
socket_close($mens_sock);
} while (
true);

socket_close($sock);
?>

Example#2 Ejemplo de Socket: Cliente TCP/IP simple

Este ejemplo muestra un cliente HTTP simple, de un paso. Simplemente se conecta con una página, envia una petición HEAD, imprime la respuesta, y sale.

<?php
error_reporting
(E_ALL);

echo 
"<h2>Conexión TCP/IP</h2>\n";

/* Obtener el puerto para el servicio WWW. */
$puerto_servicio getservbyname('www''tcp');

/* Obtener la dirección IP del host de destino. */
$direccion gethostbyname('www.example.com');

/* Crear un socket TCP/IP. */
$socket socket_create(AF_INETSOCK_STREAMSOL_TCP);
if (
$socket === false) {
    echo 
"socket_create() falló: motivo: " socket_strerror(socket_last_error()) . "\n";
} else {
    echo 
"OK.\n";
}

echo 
"Intentando una conexión con '$direccion' en el puerto '$puerto_servicio'...";
$resultado socket_connect($socket$direccion$puerto_servicio);
if (
$resultado === false) {
    echo 
"socket_connect() falló.\nMotivo: ($resultado) " .
         
socket_strerror(socket_last_error($socket)) . "\n";
} else {
    echo 
"OK.\n";
}

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

echo 
"Enviando petición HTTP HEAD...";
socket_write($socket$entradastrlen($entrada));
echo 
"OK.\n";

echo 
"Leyendo respuesta:\n\n";
while (
$salida socket_read($socket2048)) {
    echo 
$salida;
}

echo 
"Cerrando socket...";
socket_close($socket);
echo 
"OK.\n\n";
?>

Table of Contents