La mayoría de las veces picaremos código en php para acceder a una base de datos, hacer una consulta y construir una salida html. Esto es lo fundamental que todo programador php debería saber. Pero por otro lado también hay que conocer cómo trabaja php con los sockets, y digo esto porque me lo han preguntado hoy en una breve tanda de preguntas para un puesto en una empresa de mi ciudad y no he dado la talla. Desde luego sabía lo que era un socket y para qué se usan, la teoría básica, pero nunca había practicado con ellos bajo php. Así que si alguna vez os hacen esta pregunta agradeceréis haber perdido dos minutos en leer este articulillo ;)
Antes de nada, ¿qué es un socket?. Bueno, el término de socket se engloba en el ámbito de las redes de comunicación y se podría definir como una librería TCP/IP cuya función es controlar el tráfico de paquetes entre dos nodos interconectados. A groso modo se puede interpretar como un canal a través del cual se comunican dos computadoras. Cada vez que nos conectamos a nuestro servidor de correo, chateamos con nuestra novia o navegamos por la web nuestro ordenador abre uno o más sockets a través de los cuales envía y recibe información.
Sockets hay de varios tipos (de flujo, de datagrama, puros…) aunque no voy a profundizar en esto ahora porque me eternizaría. Para más información podéis ver la Guía Beej de Programación en Redes.
Y ¿puede php trabajar con sockets?. Pues sí, a tamaños altares llega su magnificencia ^_^ Quien haya trabajado alguna vez con php o alguno de sus frameworks de desarrollo habrá comprobado que php permite hacer cosas realmente potentes, entre ellas conectarse a un servidor de correo y comunicarse con él.
Vale vale, ¿y cómo abro una conexión desde php para leer mi correo?. Evidentemente con un par de funciones la mar de sencillas: fsockopen(), fclose(), fgets() y fputs(). Sabiendo un poco de inglés se puede intuír qué hace cada una de ellas: fsockopen abre el socket y fclose lo cierra mientras que con fgets y fputs podemos sacar o pasar datos respectivamente. Para abrir el socket necesitaremos una ip o un nombre (si disponemos de servicio DNS) así como un puerto de conexión que dependerá del protocolo con el que queramos trabajar: 80 para HTTP, 25 para SMTP…
En la práctica, para comunicarnos con nuestro servidor de correo (target.com), sería algo tal que así:
1.- ABRIMOS EL SOCKET CON EL SERVIDOR/MÁQUINA REMOTA:
$objetivo = "target.com";
$puerto = "25";
$conexion = fsockopen($objetivo,$puerto);
if (!$conexion) {
echo "Connection failed!. Cannot open socket.\\n";
exit();
} else {
echo "Connection accepted!. Socket opened successfully.\\n";
$str_data = fgets($conexion,1024);
print_r($str_data); //Mostramos la salida del servidor
}
2.- ENVIAMOS EL SALUDO EHLO AL SERVER:
$str_saludo = "EHLO target.com\\r\\n";
if(!fputs($conexion,$str_saludo)) {
echo "EHLO refused by server.\\n";
exit();
} else { //Si lo acepta podemos continuar trabajando por aquí
echo "EHLO accepted by server.\\n";
$str_data = fgets($conexion,1024);
print_r($str_data); //Mostramos la salida del servidor
}
3.- UNA VEZ HAYAMOS OPERADO CON EL SERVIDOR CERRAMOS LA CONEXIÓN:
if(!fputs($conexion,"QUIT\\r\\n")) {
echo "Disconnection failed!. Cannot say QUIT to server.\\n";
exit();
} else {
fclose($conexion);
echo "End of connection to server.\\n";
exit();
}
Como véis no hay que hacer gran cosa. Es bastante sencillo abrir, comunicar y cerrar un socket. La mayor complicación reside en saber cómo se comunica un determinado protocolo, qué comandos acepta y qué estructura debemos seguir a la hora de manipularlo.
En el ejemplo, justo después de enviar el saludo, podríamos haber usado cualquier comando SMTP para por ejemplo enviar un correo a una cuenta a través del servidor target.com, a saber:
MAIL FROM: correo@dominio //Para especificar el correo de origen
RCPT TO: correo@dominio //Para especificar el correo de destino
DATA\r\n Mensaje \r\n.\r\n //Para el cuerpo del mensaje