Hoy en el curso de Redeszone vamos a continuar aprendiendo cosas sobre sockets, en concreto hoy toca establecimiento y consulta de opciones y control de errores. Os recordamos que tenéis el índice del curso por si alguno quiere encontrar un volumen pasado, o por si alguien acaba de empezar a seguir el curso y quiere ponerse al día, lo actualizamos periódicamente. Vamos a empezar con los temas referidos a las opciones del socket. Podéis leer sobre qué es un socket TCP y UDP y para qué sirven.
Estableciendo opciones
Los sockets, como sabemos, tienen un serie de opciones que configuramos al crearlos, al conectarlos o al vincularos, lo que no sabíamos, es que los sockets a parte de esas opciones tienen otras opciones que podemos configurar a nuestro gusto.
Para configurar estas opciones podemos utilizar la función:
socket_set_option(resource $socket , int $level , int $optname ,[]$optval);
Donde:
$socket es el socket sobre el que se va a aplicar la función.
$level es el nivel del protocolo .
$optname es el nombre de la opción a configurar (normalmente el nombre está representado por una constante en texto aunque el argumento sea integer).
$optval es el valor.
El nivel puede ser representado con SOL_SOCKET,SOL_TCP,…, o mediante la función getprotobyname().
Consultando opciones
Igual que podemos configurar las opciones para los sockets podemos consultar el valor de esas opciones, esto lo haremos mediante la función.
[] socket_get_option ( resource $socket , int $level , int $optname );
Donde:
$socket es el socket del cual vamos a consultar su opción.
$level es el nivel del protocolo.
$optname es el nombre de la opción a consultar (normalmente el nombre está representado por una constante en texto aunque el argumento sea integer).
Esta función puede devolver un valor de diferentes tipos.
NOTA: La lista de opciones la podemos encontrar completa en la web oficial de PHP en la sección dedicada da la funcion socket_get_option( resource $socket , int $level , int $optname), no las listamos aquí, ya que son una serie considerable de opciones.
Vamos a ver unos ejemplos con esto que acabamos de ver.
[php]
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($sock,»localhost»,»8000″);
socket_listen($sock, 5);
$socket=socket_accept($sock);
#Establece la opción
socket_set_option($socket,SOL_TCP,SO_RCVBUF,12);
$opcion = socket_get_option($socket,SOL_TCP,SO_RCVBUF);
#Muestra el valor de la opción
echo ‘La opción tiene el valor ‘.$opcion.’;
$mensaje = socket_read($socket,1024,PHP_NORMAL_READ);
echo $mensaje;
socket_close($sock);
socket_close($socket);
?>;
[/php]
Nota: Para que este código funcione, es necesario conectarse mediante telnet o netcat a nuestra IP local y al puerto 8000 para enviar el mensaje al que está escuchando.
Para conectar por netcat, una vez instalado, debemos ejecutar lo siguiente en una consola nc localhost 8000.
Si estamos en Windows debemos cambiar al directorio donde tenemos alojado el netcat, esto lo podemos hacer con el comando cd.
Con telnet debemos abrir un terminal (o cmd en Windows) y teclear telnet, pulsar intro. Una vez hecho esto estaremos en telnet. Para abrir la conexión es necesario teclear:
open localhost 8000
Una vez que estamos conectado escribimos cualquier mensaje que queramos enviar y observaremos el resultado donde estemos ejecutando el script (ya sea en consola o en el servidor xampp).
Tratamiento de errores sockets
Como muchas funciones, las encargadas de manejar sockets pueden fallar en un determinado momento, dando como resultado un error que habría que gestionar.
En esta parte del volumen, vamos a explicar como identificar el error para gestionarlo (en el manual nos vamos a limitar a identificar el error e imprimirlo por pantalla, ya que la gestión del mismo depende de cada uno).
Para detectar error en sockets vamos a utilizar la función:
integer socket_last_error ([ resource $socket ] );
Esta función tiene una peculiaridad bastante interesante, veamos.
En el caso de pasarle un socket como argumento, la función devuelve el último error que se ha producido en el socket, sin embargo si no se le pasa ningún argumento, lo que hará será devolver el último error que ha causado la ultima función relacionada con sockets que ha sido llamada
Como podéis observar el error devuelto es de tipo integer(int) es decir un tipo numérico, por tanto la verdad no nos proporciona mucha información como tal un número de error (código de error). Para solventar esta situación usaremos la función:
string socket_strerror ( int $cerror);
Donde:
$cerror es un código de error.
La función lo que hará será “traducir” ese código de error y mostrar un texto con el error de forma más o menos detallada.
Como veis, en este caso la función falla cuando devuelve false, no obstante no con todas las funciones es así, para saber que valor devuelven en caso de error es necesario buscar la función en la referencia de PHP.
Vamos a ver un ejemplo [A ejecutar en consola]:
[php]
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ((socket_bind($sock,3525632532,»8000″)==false))
{
#Como podéis ver la dirección no es válida, generará un error
echo «Fallo en la vinculación del socket: » . socket_strerror(socket_last_error($sock)) . «n»;
}
if ((socket_listen($sock, 5) ==false))
{
echo «Fallo en la escucha: » . socket_strerror(socket_last_error($sock)) . «n»;
}
$socket=socket_accept($sock);
$mensaje = socket_read($socket,1024,PHP_NORMAL_READ);
echo $mensaje;
socket_close($sock);
socket_close($socket);
?>
[/php]
Esto ha sido todo por hoy, volveremos la semana que viene y empezaremos nuevo tema. ¡Esperadnos!