CXXVIII. 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.

Requirimientos

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.

Nota: 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

Esta extensión no tiene ningún tipo de recurso definido.

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)

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 éste código de error para recuperar una cadena que describe el error. Vea su descripción para más información.

Nota: 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

Ejemplo 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 implicito, 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_INET, SOCK_STREAM, SOL_TCP)) < 0) {
    echo
"socket_create() fall&oacute;: motivo: " . socket_strerror($sock) . "\n";
}

if ((
$ret = socket_bind($sock, $direccion, $puerto)) < 0) {
    echo
"socket_bind() fall&oacute;: motivo: " . socket_strerror($ret) . "\n";
}

if ((
$ret = socket_listen($sock, 5)) < 0) {
    echo
"socket_listen() fall&oacute;: motivo: " . socket_strerror($ret) . "\n";
}

do {
    if ((
$mens_sock = socket_accept($sock)) < 0) {
        echo
"socket_accept() fall&oacute;: motivo " . socket_strerror($mens_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, $mensaje, strlen($mensaje));

    do {
        if (
false === ($buf = socket_read($mens_sock, 2048, PHP_NORMAL_READ))) {
            echo
"socket_read() fall&oacute;: motivo: " . socket_strerror($ret) . "\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, $respuesta, strlen($respuesta));
        echo
"$buf\n";
    } while (
true);
    
socket_close($mens_sock);
} while (
true);

socket_close($sock);
?>

Ejemplo 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&oacute;n TCP/IP</h2>\n";

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

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

/* Crear un socket TCP/IP. */
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (
$socket < 0) {
    echo
"socket_create() fall&oacute;: motivo: " . socket_strerror($socket) . "\n";
} else {
    echo
"OK.\n";
}

echo
"Intentando una conexi&oacute;n con '$direccion' en el puerto '$puerto_servicio'...";
$resultado = socket_connect($socket, $direccion, $puerto_servicio);
if (
$resultado < 0) {
    echo
"socket_connect() fall&oacute;.\nMotivo: ($resultado) " .
         
socket_strerror($resultado) . "\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&oacute;n HTTP HEAD...";
socket_write($socket, $entrada, strlen($entrada));
echo
"OK.\n";

echo
"Leyendo respuesta:\n\n";
while (
$salida = socket_read($socket, 2048)) {
    echo
$salida;
}

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

Tabla de contenidos
socket_accept -- Accepts a connection on a socket
socket_bind -- Binds a name to a socket
socket_clear_error -- Clears the error on the socket or the last error code
socket_close -- Closes a socket resource
socket_connect -- Initiates a connection on a socket
socket_create_listen -- Opens a socket on port to accept connections
socket_create_pair -- Creates a pair of indistinguishable sockets and stores them in an array
socket_create -- Create a socket (endpoint for communication)
socket_get_option -- Gets socket options for the socket
socket_getpeername --  Queries the remote side of the given socket which may either result in host/port or in a Unix filesystem path, dependent on its type
socket_getsockname --  Queries the local side of the given socket which may either result in host/port or in a Unix filesystem path, dependent on its type
socket_last_error -- Returns the last error on the socket
socket_listen -- Listens for a connection on a socket
socket_read -- Reads a maximum of length bytes from a socket
socket_recv -- Receives data from a connected socket
socket_recvfrom -- Receives data from a socket, connected or not
socket_select --  Runs the select() system call on the given arrays of sockets with a specified timeout
socket_send -- Sends data to a connected socket
socket_sendto -- Sends a message to a socket, whether it is connected or not
socket_set_block --  Sets blocking mode on a socket resource
socket_set_nonblock -- Sets nonblocking mode for file descriptor fd
socket_set_option -- Sets socket options for the socket
socket_shutdown -- Shuts down a socket for receiving, sending, or both
socket_strerror -- Return a string describing a socket error
socket_write -- Write to a socket

Hosting by: hurra.com
Generated: 2007-01-26 18:00:53