Introducción a los Socket y PHP (1)

Los Socket se utilizan para poder enviar ordenes a un servidor que está atendiendo nuestras peticiones.

Socket designa un concepto abstracto por el cual dos programas (posiblemente situados en computadoras distintas) pueden intercambiarse cualquier flujo de datos, generalmente de manera fiable y ordenada.Wikipedia

Pensemos pues en un servidor encargado de servir los diferentes tipos de datos que sus clientes le solicitan utilizando los diferentes servicios de los que se disponen (FTP, telnet, HTTP …). ¿Como saber que servicio se le está solicitando al Servidor en ese momento?; muy fácil, para esto utilizamos los puertos.

Por lo tanto, un socket quedaría definido por una dirección IP (La del equipo que actúa como servidor), un protocolo y un número de puerto (El utilizado para acceder a un servicio determinado).

A su ve, los Sockets están basados en el famoso protocolo de comunicaciones utilizado en Internet: TCP (Transmision Control Protocol).

La función del protocolo TCP es, ni mas ni menos que la de traer y llevar información desde un servidor a un cliente y viceversa utilizando los diferentes protocolos utilizados por cada Servicio: POP3 y SMTP para el correo, HTTP para la web.

PHP proporciona acceso a lo que se denomina los Socket de Berkeley. Se trata pues, de «un conjunto de funciones (API) que nos permitiría establecer comunicación con otro sistema que puede recibir y enviar información utilizando ésta técnica».. (Esteban Trigos García PHP4. Ed.Anaya Multimedia).

Para abrir una conexion utilizando los socket con PHP echaremos mano de la funcion fsockopen ();

fsockopen (string {nombre del servidor} , int {nº del Puerto});

Por ejemplo:
$Socket = fsockopen («peachep.wordpress.com», 80);

El manejo del contenido almacenado en nuestro caso en la variable $Socket es muy parecido al que se haría con un fichero en PHP. El sistema es el mismo, salvo que en esta ocasión, en vez de un fichero, se trata de una conexión TCP.

Podemos realizar las mismas operaciones que realizamos con un fichero:

– Leer / fread ();
– Escribir / fputs ();
– Recibir Información / fgets();

Para terminar esta introducción vamos a realizar un ejemplo de conexión al puerto POP3 del servidor de Euskaltel.

<?
$conexion = fsockopen («pop3.euskalnet.net», 110);

if ($conexion) {
echo «Conexion realiaza con éxito»;

//recibimos los primeros 1024 caracteres de la respuesta del servidor POP.
$respuesta = fgets ($conexion, 100);

//Volcamos en pantalla la respuesta del Servidor.
echo $respuesta;

//cerramos la conexión.
fclose ($conexion);

}

?>

Próximamente veremos un ejemplo completo de conexión con un servidor de Correo y el desglose de la conversación que con éste se realiza al realizar las peticiones.

Links Externos:
C++ Sockets Library
Socket en Wikipedia
Berkeley Sockets en Wikipedia (En Inglés)

14 Responses to Introducción a los Socket y PHP (1)

  1. […] Para intentar establecer la conexión a cada uno de los puertos abiertos de la máquina utilizaremos la ya conocida función fsockopen (). […]

  2. Gabriel dice:

    hola!!!!!!!!!! soy nuevo en eso de los socket apenas me estoy aprendiendo, pero me gustaria saber por que me manda estos errores el socket_bind:
    Warning: socket_bind() [function.socket-bind]: unable to bind address [0]: Sólo se permite un uso de cada dirección de socket (protocolo/dirección de red/puerto). Primero lo tenia el puerto en el 80 y me fije que lo utiliza el apache pues utilizo el xampp, y lo estoy corriendo en windows. Despues lo cambie a varios puertos y me manda lo mismo este es mi codigo:

  3. Ruben dice:

    No creo que sea un problema de puertos. Tal vez no hayas creado la conexión (el Socket) antes de asociarle el nombre mediante socket_bind.

    Aquí te dejo algo de información.

    bool socket_bind ( resource socket, string address [, int port] )

    Esta función asocia el nombre definido en «address» con la dirección definida en socket. El puerto es un parámetro opcional. Sólo puede ser usado cuando se realiza una conexión a un Socket de la familia AF_INET, es decir, la dirección está definida por una dirección IP (eg. 127.0.0.1)

    La función socket_bind debe ser utilizada antes de establecer una conexión mediante socket_connect o socket_listen.

    Un ejemplo que he podido encontrar sobre el uso de socket_bind() que quizás te pueda ayudar.

    <?php
    // Create a new socket
    $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

    // An example list of IP addresses owned by the computer
    $sourceips[‘kevin’] = ‘127.0.0.1’;
    $sourceips[‘madcoder’] = ‘127.0.0.2’;

    // Bind the source address
    socket_bind($sock, $sourceips[‘madcoder’]);

    // Connect to destination address
    socket_connect($sock, ‘127.0.0.1’, 80);

    // Write
    $request = ‘GET / HTTP/1.1’ . «\r\n» .
    ‘Host: example.com’ . «\r\n\r\n»;
    socket_write($sock, $request);

    // Close
    socket_close($sock);

    ?>

    Échale un vistazo a esta dirección: http://www.respuestas-php.com.ar/function.socket-bind.html

  4. Gabriel dice:

    Gracias por haberme constestado me ayudo mucho lo que mandastes!!! 🙂 me sirvio de mucho ya logre que funcionara. gracias!!!!!!!!!!!!!!!!!!

  5. Gabriel dice:

    Bueno molestando otra vez!!!! :), me gustaria saber si se pueden enviar archivos que pesen mas de 1MB a traves de socket en php, no he encontrado ningun ejemplo sobre si se puede enviar o no y me gustaria saber si se puede, he podido enviar archivos de texto plano q pesan a lo mucho 2 kb, pero cuando intento enviar por ejemplo una imagen, en el lado del servidor solo recibe menos 8 KB, cuando la imagen pesa 100 KB, si se puede me gustaria q me orienten en que tengo q hacer para poder enviarlo.

  6. Gabriel dice:

    Bueno lo que pasa es q yo lo envio con un socket cliente y otro servidor este es el codigo de mi cliente:

  7. Gabriel dice:

    Antes que nada gracias por contestar, ahora lo primero q hago con mi socket cliente es abrir el archivo con Fopen y lo paso todo con Fgets despues con un fwrite, del lado del servidor lo recibo con un socket_read, pero esto solo llega a leer hasta 8kb y no se por que,si no es mucha molestia me podrias mandar un ejemplo de como enviar el archivo con formularios pues en internet casi no hay muchos ejemplos de como enviar archivos a traves de socket.

  8. Susana dice:

    Hola! me ha resultado de mucha ayuda estos comentarios, pero aun tengo una duda existencial…
    ¿en que se diferencia el código del lado del cliente y el del lado del servidor? ¿tengo que abrir/cerrar los sockets en ambos lados?

    Espero una respuesta, muchas gracias

  9. fernando dice:

    ¿En que se diferencian el codigo del cliente y el del lado del servidor?
    En respuesta a tu pregunta te puedo decir que son codigos totalmente diferentes aunque en el manejo del socket hay varias funciones que son iguales.
    El servidor es un programa o aplicacion que esta constantemente escuchando a las peticiones de varios clientes. En cambio un cliente solo se conecta al servidor para pedirle halgo.
    Por Ejemplo.
    Servidor: irc.arnet.com.ar 6667 (Servidor de canal de chat de arnet)
    Cliente: Puede ser un applet en java, el programa MIRC, un script PHP, ETC.

    Como veras el servidor es una entidad que provee acceso al canal de chat. y los clientes pueden estar implementados en cualquier lenguaje de programacion y lo mismo se entienden. esto se deve a que existe un protocolo de comunicacion de alto nivel que permite que estas aplicaciones puedan entenderse y coexistir.

  10. rodiv dice:

    Hola haber si me pueden ayudar, tengo la siguiente duda, se requiere enviar informacion a un puerto X udp que depues almacenare en bd mysql entiendo que si un programa deposita datos en x puerto estos se almacenan en un buffer hasta que una aplicacion los recoja, bien ahora en un script php al usar la funcion fsockopen lo que hace el script es conectarse a ese puerto y tomar los datos si uso la funcion fgets cierto? si la aplicacion que envia los datos tomando encuenta que estara instalada en varios equipos que estaran enviando datos, como gestionar ese trafico es decir suponiendo que hay 2 equipos que al mismo tiempo envian datos o que por un periodo largo dejan todos de enviar informacion, como evito que mi script php se detenga ya que pensaba meter en un bucle while(!eof($sock)) el codigo de tratamiento, pero si no mal entiendo este se saldra por lo tanto terminara al detectar que ya no estan enviando datos en el caso que puse (de que dejaran de enviar datos todos los equipos por un periodo X) ya que mi script debera estar al tanto de la informacion que llega al puerto y entiendo que un script se sirve una sola vez y ya (la parte de automatizar el script ya la tengo e estado investigando como automatizar la ejecucion de un script incluso en segundo plano en un servidor con lo que me evito tener que ejecutar un navegador para poder funcionar el script) pero esto seria basicamente el problema no hay una funcion que este esperando a recibir datos y entonces enviarlos o algo parecido y como gestionar el caso en que 2 equipos envien al mismo tiempo

    gracias de antemano, saludos.

  11. Jabonn dice:

    Gracias por compartir sus conocimientos.

    De mucha utilidad.

  12. […] Introducción a los Socket y PHP (1) mayo, 2007 12 comentários 5 […]

  13. Luciano Pagano dice:

    Buenas… yo estoy intentando imprimir la info que viaja atravez de un puerto (4585). El tema es que cuando pongo «echo $respuesta;» no me imprime el dato que yo le mando al socket si no que me imprime esto: «SSH-2.0-OpenSSH_4.3» supongo que eso sera la respuesta de que el socket esta abierto para recibir el dato… ahora el problema es como hago para imprimir ese dato

Deja un comentario