2011-02-04 2 views
7

Donc, j'ai mIRC faire une écoute (ours avec moi sur celui-ci) sur le port 1235 et j'ai essayé de faire un script PHP pour se connecter à un tel port sur mon serveur localhost.PHP Sockets est à mi-travail

Mon localhost est un Apache + PHP propre avec mIRC étant exécuté sur un autre ordinateur (à l'intérieur de lan).

Le script fonctionne demi-droite: 1) il se connecte au port 1235 2), il envoie le i 2,1 $), mais de l'autre côté sans msg est reçu (aka je reçois un événement de lecture de chaussette, mais aucun texte apparaît) 3), il lit tous les messages entrants correclty 4), il se ferme lorsque « fin » est le message drumroll 5) il ne fonctionne que si la fonction while n'est pas présente. 5.1) aka Inifi-chargement. il ne montre que l'écho lorsque socket est fermée par « fin »

est le code ici, qui est un exemple simple je l'ai trouvé sur php.net, merci à l'avance :)

<?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); 
?> 

ce que je reçois dans le navigateur, après avoir dit 'fin'

socket créé avec succès. Tentative de connexion à '192.168.1.101' sur le port '1235' ... connecté avec succès à 192.168.1.101. Envoi 1 au serveur. Réponse du serveur est: ok réponse du serveur est: fin

c'est mIRC:

test: 89.152.172.21 est en! lire près Blockquote

si je l'avais laissé travailler pendant une heure, multipliez-vous « lire » 60 et « envoi N + 1 au serveur » mais cela ne se manifeste après la fermeture de chaussette (ou par stoping pendant ce temps)

+1

Pouvez-vous publier les 'echos' qu'il crache quand vous lancez ça? Cela pourrait être utile pour le déboguer. – xil3

+0

mis à jour le poste pour avoir le 'echos' craché :) – MoshMage

Répondre

2

Vous avez "plaine" socket_write() et socket_read() appels.Malheureusement, les fonctions de socket sont peu fiable par conception (comportement hérité des sockets BSD). Vous ne pouvez pas simplement appeler socket_write() et attendre à écrire réellement octets (aussi étrange que cela puisse paraître ...)

PHP devis manuel:

socket_write() ne pas écrire nécessairement tous les octets du buffer fourni. Il est vrai que, selon les tampons de réseau, etc., seule une certaine quantité de données, même un octet, est écrite bien que votre tampon soit plus grand. Vous devez faire attention à ne pas oublier involontairement de transmettre le reste de vos données.

Vous devez vérifier combien d'octets ont été écrits et continuer à réessayer jusqu'à ce que tout ce que vous vouliez a été envoyé.

La même chose vaut pour la lecture. Lire appel peut lire autant que vous avez demandé ou moins et vous devez réessayer l'appel.

Assurez-vous de mettre des prises pour bloquer et ensuite appeler lecture/écriture dans une boucle, ou (tout aussi terrible) select() appel pour trouver douilles peut ont des données ou peut avoir fini d'envoyer.


Si vous voulez API qui est pas un tel PITA, puis utiliser à la place streams, qui sont très fiables lecture/écriture.

Si vous n'avez pas forcément besoin de PHP, jetez un oeil à Node JS, qui est spécialement conçu pour les programmes/environnement avec des connexions réseau de longue durée.

+0

Cela explique beaucoup. En outre, merci pour une réponse si détaillée - j'avais perdu l'espoir de jamais avoir ce fonctionnement :) Va faire et vérifier les flux, comme il semble être plus facile et vérifiera aussi Node.js parce que ça ressemble exactement à ce que je veux – MoshMage

0

changement

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

Pour:

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

Vous fournissez un entier où PHP attend une chaîne.

+3

cela ne devrait pas importer? – zanlok

+0

même si c'est le cas, je reçois toujours 0Rcvd octets sur mIRC – MoshMage

0

D'une des notes dans la documentation: http://php.net/manual/en/function.socket-write.php

Certains clients (la XMLSocket de flash par exemple) ne se déclenche pas un événement de lecture jusqu'à ce qu'une nouvelle ligne est reçu.

Alors essayez de changer votre code:

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

+0

Guillemets doubles pour une nouvelle ligne réelle. – igorw