2011-02-04 14 views
7

Por lo tanto, tengo mIRC haciendo una escucha (paciencia conmigo en este) en el puerto 1235 y traté de hacer un script php para conectarme a dicho puerto en mi servidor localhost.PHP Sockets está trabajando a medias

Mi localhost es un Apache + PHP limpio con mIRC ejecutándose en otra computadora (dentro de lan).

El script funciona la mitad derecha como: 1) que se conecta al puerto 1235 2) que envía el $ i 2.1), pero por otro lado se recibe ninguna msg (también conocido como consigo un evento leído calcetín, pero no hay texto aparece) 3) que lee todos los mensajes entrantes correclty 4) se cierra cuando 'fin' es el mensaje redoble 5) sólo funciona si la función mientras no está presente. 5.1) aka Inifi-cargando. sólo muestra eco cuando socket está cerrado por medio de 'fin'

aquí es el código, que es un ejemplo sencillo que encontré en php.net, gracias de antemano :)

<?php 
//The Client 
error_reporting(E_ALL); 

$address = "192.168.1.101"; 
$port = 1235; 

/* Create a TCP/IP socket. */ 
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); 
if ($socket === false) { 
    echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n"; 
} else { 
    echo "socket successfully created.\n"; 
} 

echo "Attempting to connect to '$address' on port '$port'..."; 
$result = socket_connect($socket, $address, $port); 
if ($result === false) { 
    echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n"; 
} else { 
    echo "successfully connected to $address.\n<br>"; 
} 
$allow = true; 
$i = 0; 
while ($allow == true) 
{ 
    $i++; 
    echo "Sending $i to server.\n<br>"; 
    socket_write($socket, $i, strlen($i)); 

    $input = socket_read($socket, 2048); 
    if ($input == 'end') { 
     $allow = false; 
    } 
    echo "Response from server is: $input\n"; 
    sleep(5); 
} 

echo "Closing socket..."; 
socket_close($socket); 
?> 

esto es lo que me sale en el navegador, después de decir 'fin'

socket creado con éxito. Intentando conectar a '192.168.1.101' en el puerto '1235' ... conectado con éxito con 192.168.1.101. Enviando 1 al servidor. Respuesta del servidor es: ok respuesta del servidor es: fin

esto está en mIRC:

prueba: 89.152.172.21 está en! leer cerca cita en bloque

si hubiera dejado de trabajar durante una hora, se multiplica "leer" el 60 y "el envío de N + 1 con el servidor" pero esto sólo presenta después de calcetín cerca (o por stoping al mismo tiempo)

+1

¿Puedes publicar qué 'echos' está escupiendo cuando lo ejecutas? Podría ser útil para depurarlo. – xil3

+0

actualizó la publicación para que se escuche el 'echos' :) – MoshMage

Respuesta

2

usted tiene "claro" y socket_write()socket_read() llamadas.Desafortunadamente las funciones de socket son no confiables por diseño (comportamiento heredado de los conectores BSD). No se puede simplemente llamar socket_write() y esperar que en realidad escribir bytes (por extraño que suene ...) manual de

PHP cita:

socket_write() no necesariamente escribir todos los bytes desde el buffer dado. Es válido que, dependiendo de los búferes de red, etc., solo se escribe una cierta cantidad de datos, incluso un byte, aunque el búfer sea mayor. Tienes que tener cuidado para no olvidarte involuntariamente de transmitir el resto de tus datos.

Debes comprobar cuántos bytes se han escrito y seguir intentándolo hasta que se haya enviado todo lo que querías.

Lo mismo ocurre con la lectura. La llamada de lectura puede leer tanto como solicitó o menos y se espera que intente de nuevo la llamada.

Asegúrese de establecer tomas de bloquear y luego llamar a leer/escribir en un bucle, o uso (igual de horrible) select() llamada para averiguar qué conectores puede tienen algunos datos o puede haber terminado de enviar.


Si desea API que no es tal PITA, a continuación, utilizar streams lugar, que tienen lecturas fiables/escribe.

Si no necesita necesariamente PHP, eche un vistazo a Node JS, que es un servidor/entorno especialmente diseñado para programas con conexiones de red duraderas.

+0

Eso explica mucho. Además, gracias por una respuesta tan detallada: había perdido la esperanza de tener este funcionamiento :) Hará y verificará las transmisiones, ya que parece ser más fácil y también comprobará Node.js porque suena exactamente como quiero – MoshMage

0

Cambio

socket_write($socket, $i, strlen($i)); 

Para:

socket_write($socket, strval($i), strlen(strval($i))); 

Está proporcionando un número entero donde PHP espera una cadena.

+3

¿Esto no debería importar? – zanlok

+0

, incluso si lo hizo, todavía obtengo 0Rcvd bytes en mIRC – MoshMage

0

Desde una de las notas en la documentación: http://php.net/manual/en/function.socket-write.php

Algunos clientes (XMLSocket de flash, por ejemplo) no se disparará un evento de lectura hasta que se reciba una nueva línea.

Así que trate de cambiar su código:

socket_write($socket, $i, strlen($i)); a: socket_write($socket, $i.'\n', strlen($i)+1);

+0

comillas dobles para una nueva línea real. – igorw

Cuestiones relacionadas