◆ Conceptos básicos del zócalo
PHP utiliza la biblioteca de sockets de Berkley para crear sus conexiones. Un socket no es más que una estructura de datos. Utilice esta estructura de datos de socket para iniciar una sesión entre el cliente y el servidor. Este servidor siempre está escuchando y preparándose para generar una nueva sesión. Cuando un cliente se conecta al servidor, abre un puerto en el que el servidor está escuchando una sesión. En este momento, el servidor acepta la solicitud de conexión del cliente y luego realiza un ciclo. Ahora el cliente puede enviar información al servidor y el servidor puede enviar información al cliente.
Para generar un Socket, necesita tres variables: un protocolo, un tipo de socket y un tipo de protocolo público. Hay tres protocolos para elegir al generar un socket. Continúe leyendo a continuación para obtener contenido detallado del protocolo.
Definir un tipo de protocolo público es un elemento esencial de conexión. En la siguiente tabla echamos un vistazo a los tipos de protocolos comunes.
Tabla 1: Nombre del protocolo/Descripción constante
AF_INET Este es el protocolo utilizado por la mayoría de los sockets, utiliza TCP o UDP para la transmisión y se utiliza en direcciones IPv4.
AF_INET6 es similar al anterior, pero se usa para direcciones IPv6.
Protocolo local AF_UNIX, utilizado en sistemas Unix y Linux. Rara vez se utiliza. Generalmente se utiliza cuando el cliente y el servidor están en la misma máquina. Tabla 2: Nombre del tipo de socket/descripción de constante.
SOCK_STREAM Este protocolo es una conexión secuencial, confiable y basada en flujo de bytes integrados en datos. Este es el tipo de socket más utilizado. Este socket utiliza TCP para la transmisión.
SOCK_DGRAM Este protocolo es una llamada de transferencia de longitud fija y sin conexión. Este protocolo no es confiable y utiliza UDP para sus conexiones.
SOCK_SEQPACKET Este protocolo es una conexión confiable de dos líneas que envía paquetes de datos de longitud fija para su transmisión. Este paquete debe aceptarse por completo antes de poder leerlo.
SOCK_RAW Este tipo de socket proporciona acceso único a la red. Este tipo de socket utiliza el protocolo público ICMP. (ping y traceroute utilizan este protocolo)
SOCK_RDM Este tipo rara vez se utiliza y no se implementa en la mayoría de los sistemas operativos. Se proporciona para que lo utilice la capa de enlace de datos y no garantiza el orden de los paquetes. Tabla 3: Nombre de protocolo público/descripción constante.
Protocolo de mensajes de control de Internet ICMP, utilizado principalmente en puertas de enlace y hosts para verificar las condiciones de la red e informar mensajes de error.
Protocolo de datagramas de usuario UDP, que es un protocolo de transmisión sin conexión y poco confiable
El protocolo de control de transmisión TCP, que es el protocolo público confiable más utilizado, puede garantizar que el paquete de datos pueda llegar al destinatario. Si ocurre un error durante el proceso de transmisión, reenviará el paquete de error.
Ahora que conoce los tres elementos que generan un socket, usamos la función socket_create() en PHP para generar un socket. Esta función socket_create() requiere tres parámetros: un protocolo, un tipo de socket y un protocolo público. La función socket_create() devuelve un tipo de recurso que contiene el socket si se ejecuta correctamente. Si falla, devuelve falso.
Recurso socket_create(int protocolo, int socketType, int commonProtocol);
Ahora creas un socket, ¿y luego qué? PHP proporciona varias funciones para manipular sockets. Puede vincular un socket a una IP, escuchar la comunicación de un socket y aceptar un socket. Ahora veamos un ejemplo para comprender cómo la función genera, acepta y escucha un socket.
<?php
$commonProtocol = getprotobyname("tcp");//Utilice el nombre del protocolo público para obtener un tipo de protocolo
$socket = socket_create(AF_INET, SOCK_STREAM, $commonProtocol);// Genera un socket y devuelve una instancia del recurso de socket
socket_bind($socket, 'localhost', 1337);//Vincular socket a la computadora local
socket_listen($socket);//Escuche todas las conexiones de socket entrantes
// Más funciones de socket por venir
?>
El ejemplo anterior genera su propio lado del servidor. La primera línea del ejemplo,
$commonProtocol = getprotobyname("tcp");
Utilice el nombre del protocolo público para obtener un tipo de protocolo. Aquí se utiliza el protocolo público TCP. Si desea utilizar el protocolo UDP o ICMP, debe cambiar los parámetros de la función getprotobyname() a "udp" o "icmp". Otra alternativa es especificar SOL_TCP o SOL_UDP en la función socket_create() en lugar de utilizar la función getprotobyname().
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
La segunda línea del ejemplo crea un socket y devuelve una instancia del recurso del socket. Una vez que tenga una instancia del recurso de socket, debe vincular el socket a una dirección IP y un puerto.
socket_bind($socket, 'localhost', 1337);
Aquí vincula el socket a la computadora local (127.0.0.1) y vincula el socket a su puerto 1337. Entonces necesitas escuchar todas las conexiones de socket entrantes.
socket_listen($socket);
Después de la cuarta línea, es necesario comprender todas las funciones del socket y su uso.
Tabla 4: Descripción del nombre de la función de función de socket
socket_accept() acepta una conexión Socket
socket_bind() vincula el socket a una dirección IP y un puerto
socket_clear_error() borra el error del socket o el último código de error
socket_close() cierra un recurso de socket
socket_connect() inicia una conexión de socket
socket_create_listen() abre un socket escuchando en el puerto especificado
socket_create_pair() genera un par de sockets indistinguibles en una matriz
socket_create () genera un socket, lo que equivale a generar una estructura de datos de socket
socket_get_option() Obtener opciones de socket
socket_getpeername() Obtiene la dirección IP de un host remoto similar
socket_getsockname() obtiene la dirección IP del socket local
socket_iovec_add() agrega un nuevo vector a una matriz dispersa/agregada
socket_iovec_alloc() Esta función crea una estructura de datos iovec que puede enviar, recibir, leer y escribir
socket_iovec_delete() elimina un iovec asignado
socket_iovec_fetch() devuelve los datos del recurso iovec especificado
socket_iovec_free() libera un recurso iovec
socket_iovec_set() establece el nuevo valor de los datos de iovec
socket_last_error() obtiene el último código de error del socket actual
socket_listen() escucha todas las conexiones desde el socket especificado
socket_read() lee datos de longitud especificada
socket_readv() lee datos de la matriz dispersa/agregada
socket_recv() finaliza los datos del socket al caché
socket_recvfrom() acepta datos del socket especificado. Si no se especifica, el valor predeterminado es el socket actual.
socket_recvmsg() recibe mensajes de iovec
socket_select() selección múltiple
socket_send() Esta función envía datos al socket conectado
socket_sendmsg() envía mensaje al socket
socket_sendto() envía un mensaje al socket en la dirección especificada
socket_set_block() establece el socket en modo bloque
socket_set_nonblock() Establece el socket en modo sin bloqueo
socket_set_option() establece opciones de socket
socket_shutdown() Esta función le permite cerrar la lectura, la escritura o el socket especificado
socket_strerror() devuelve el error detallado con el número de error especificado
socket_write() escribe datos en el caché del socket
socket_writev() escribe datos en matrices dispersas/agregadas. Todas las funciones anteriores están relacionadas con sockets en PHP. Para usar estas funciones, debe abrir su socket. Si no lo ha abierto, edite su archivo php.ini. siguiente comentario antes de esta línea:
extensión=php_sockets.dll
Si no puede eliminar el comentario, use el siguiente código para cargar la biblioteca de extensiones:
<?php
if(!extension_loaded('sockets')) {
if(strtoupper(substr(PHP_OS, 3)) == “GANAR”) {
dl('php_sockets.dll');
}demás{
dl('sockets.así');
}
}
?>
Si no sabe si su socket está abierto, puede usar la función phpinfo() para determinar si el socket está abierto. Puede comprobar si el socket está abierto consultando la información de phpinfo.
Ver la información de phpinfo() sobre el socket ◆ Generar un servidor Ahora mejoremos el primer ejemplo. Necesita escuchar un socket específico y manejar las conexiones de los usuarios.
<?php
$commonProtocol = getprotobyname("tcp");
$socket = socket_create(AF_INET, SOCK_STREAM, $commonProtocol);
socket_bind($socket, 'localhost', 1337);
socket_listen($socket);
//Aceptamos cualquier conexión entrante al servidor
$conexión = socket_accept($socket);
si($conexión){
socket_write($conexión, "Te has conectado al socket...nr");
}
?>
Debe utilizar su símbolo del sistema para ejecutar este ejemplo. La razón es que aquí se generará un servidor, no una página web. Si intenta ejecutar este script utilizando un navegador web, es muy probable que supere el límite de 30 segundos. Puede usar el siguiente código para establecer un tiempo de ejecución infinito, pero se recomienda usar el símbolo del sistema para ejecutar.
set_time_limit(0);
Simplemente pruebe este script en su símbolo del sistema:
PHP.exe ejemplo01_server.php
Si no ha establecido la ruta al intérprete de php en las variables de entorno de su sistema, deberá especificar la ruta a php.exe. Cuando ejecuta el servidor, puede probarlo conectándose al puerto 1337 a través de telnet.
Hay tres problemas con el lado del servidor anterior: 1. No puede aceptar múltiples conexiones. 2. Sólo completa un comando. 3. No puede conectarse a este servidor a través de un navegador web.
Este primer problema es más fácil de solucionar, puedes utilizar una aplicación para conectarte al servidor cada vez. Pero el siguiente problema es que necesita utilizar una página web para conectarse al servidor, lo cual es más difícil. Puede hacer que su servidor acepte la conexión, escriba algunos datos al cliente (si debe escribirlos), cierre la conexión y espere la siguiente conexión.
Mejore el código anterior y genere el siguiente código para crear su nuevo servidor:
<?php
// Configuramos nuestro socket
$commonProtocol = getprotobyname("tcp");
$socket = socket_create(AF_INET, SOCK_STREAM, $commonProtocol);
socket_bind($socket, 'localhost', 1337); //socket_bind() vincula el socket a una dirección IP y un puerto
socket_listen($socket);
//Inicializa el buffer
$buffer = "SIN DATOS";
mientras (verdadero) {
// Acepta cualquier conexión que entre en este socket
$conexión = socket_accept($socket);//socket_accept() acepta una conexión Socket
printf("Enchufe conectadorn");
//Comprueba si hay algo en el buffer
si($buffer!= ""){
printf("Hay algo en el buffer...enviando datos...rn");
socket_write($conexión, $buffer. "rn"); //socket_write() escribe datos en la caché del socket
printf("Escribió en el socketrn");
}demás {
printf("No hay datos en el bufferrn");
}
//Obtener la entrada
while($data = socket_read($connection, 1024, PHP_NORMAL_READ))//socket_read() lee datos de longitud especificada
{
$búfer = $datos;
socket_write($conexión, "Información recibidarn");
printf("Búfer: " . $búfer . "rn");
}
socket_close($conexión); //socket_close() cierra un recurso de socket
printf("Cerré el socketrnrn");
}
?>
¿Qué debería hacer este servidor? Inicializa un socket y abre un caché para enviar y recibir datos. Espera una conexión y una vez realizada, imprime "Socket conectado" en la pantalla del lado del servidor. Este servidor verifica el búfer y, si hay datos en el búfer, los envía a la computadora conectada. Luego envía un mensaje de aceptación para estos datos. Una vez que acepta el mensaje, lo guarda en los datos, informa a la computadora conectada del mensaje y finalmente cierra la conexión. Cuando se cierra la conexión, el servidor comienza a procesar la siguiente conexión.
◆ Es fácil generar un cliente para manejar el segundo problema. Necesita generar una página php, conectarse a un socket, enviar algunos datos a su caché y procesarlos. Luego tienes los datos procesados esperando y puedes enviar tus datos al servidor. En otra conexión de cliente, procesará esos datos.
El siguiente ejemplo demuestra el uso de sockets:
<?php
// Crea el socket y conecta
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$conexión = socket_connect($socket,'localhost', 1337);
while($buffer = socket_read($socket, 1024, PHP_NORMAL_READ)) {
if($búfer == "SIN DATOS") {
echo(“<p>SIN DATOS</p>”);
romper;
}demás{
//Hacer algo con los datos en el buffer
echo(“<p>Datos del búfer: “ . $búfer . “</p>”);
}
}
echo(“<p>Escribiendo en Socket</p>”);
// Escribe algunos datos de prueba en nuestro socket.
if(!socket_write($socket, “ALGUNOS DATOSrn”)){
echo(“<p>Error de escritura</p>”);
}
// Lee cualquier respuesta del socket
while($buffer = socket_read($socket, 1024, PHP_NORMAL_READ)){
echo(“<p>Los datos enviados fueron: ALGUNOS DATOS<br> La respuesta fue:” . $buffer . “</p>”);
}
echo(“<p>Lectura finalizada desde el socket</p>”);
?>
Este código de ejemplo muestra cómo el cliente se conecta al servidor. El cliente lee los datos. Si esta es la primera conexión que llega en este ciclo, el servidor enviará "SIN DATOS" al cliente. Si esto sucede, el cliente está por encima de la conexión. El cliente envía sus datos al servidor, los datos se envían al servidor y el cliente espera una respuesta. Una vez recibida la respuesta, escribe la respuesta en la pantalla.