If you specify no port number, or 0, a random free port will be chosen.
To use ports for ipc between client/server on the same machine you can use (minus error checking)
server.php:
<?php
$sock = socket_create_listen(0);
socket_getsockname($sock, $addr, $port);
print "Server Listening on $addr:$port\n";
$fp = fopen($port_file, 'w');
fwrite($fp, $port);
fclose($fp);
while($c = socket_accept($sock)) {
/* do something useful */
socket_getpeername($c, $raddr, $rport);
print "Received Connection from $raddr:$rport\n";
}
socket_close($sock);
?>
client.php:
<?php
$fp = fopen($port_file, 'r');
$port = fgets($fp, 1024);
fclose($fp);
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($sock, '127.0.0.1', $port);
socket_close($sock);
?>
socket_create_listen
(PHP 4 >= 4.1.0, PHP 5)
socket_create_listen — Apre un socket per accettare connessioni su una porta
Descrizione
$porta
[, int $backlog
] )Questa funzione è SPERIMENTALE. Ovvero, il comportamento di questa funzione, il nome di questa funzione, in definitiva tutto ciò che è documentato qui può cambiare nei futuri rilasci del PHP senza preavviso. Siete avvisati, l'uso di questa funzione è a vostro rischio.
Questa funzione è stata concepita per rendere semplice il compito di creare un nuovo socket che sia in attesa di nuove connessioni.
La funzione socket_create_listen() crea una nuova risorsa socket
di tipo AF_INET in attesa su una data porta
in tutte le interfacce locali di una nuova connessione.
Il parametro backlog indica la lunghezza massima
della coda delle connessioni pendenti.
Come valore per backlog, può essere
passata la costante SOMAXCONN, vedere
socket_listen() per maggiori dettagli.
socket_create_listen() restituisce una nuova risorsa di tipo socket
se ha successo, oppure FALSE su errore. Il codice dell'errore può essere recuperato con
la funzione socket_last_error(). Questo codice può essere passato alla funzione
socket_strerror() per ottenere una descrizione
dell'errore.
Nota:
Se si desidera creare un socket che sia in attesa solo su certe interfacce, occorre utilizzare socket_create(), socket_bind() e socket_listen().
Vedere anche socket_create(), socket_bind(), socket_listen(), socket_last_error() e socket_strerror().
I believe that on some systems this may not bind to some or all public interfaces.
On my Windows system, I could not connect on the public interface using this, but could when I made the individual calls to create, bind, and listen.
Dustin Oprea
Please note that port 1 to and with 1024 on linux and bsd system require root privileges. So it is recommended to choose a higher port for your own application.
A simple Class for Socket Server.
<?php
/**
* Description of socketclass
*
* @author daniell
*/
class Socket {
// Sockets
private $sock;
private $lister;
// Wait, Porta, Ack
private $wait;
private $porta;
private $ack;
// Usuario
private $user;
function __construct($wait, $porta, $ack) {
$this->wait = $wait;
$this->porta = $porta;
$this->ack = $ack;
$this->user['ip'] = $this->user['port'] = NULL;
// Cria o servidor
$this->socketListen();
}
function __destruct() {
$this->close();
}
// Cria o Servidor
public function socketListen(){
while( !( $this->lister = @socket_create_listen($this->porta) ) ){
echo 'Aguarde..';
sleep($this->wait);
}
}
// Aguarda um Cliente conectar.
public function waitClient(){
$r = array($this->lister);
if( socket_select($r,$w = NULL,$e = NULL, $this->wait) ){
// Conectado
$this->sock = socket_accept($this->lister);
socket_getpeername($this->sock, $raddr, $rport);
$this->user = array('ip'=>$raddr,'port'=>$rport);
return true;
} else {
// [Time out] - Não conectado a tempo.
return false;
}
}
// Fecha a conexão
public function close(){
if( is_resource($this->lister) )
socket_close($this->lister);
}
// Obtem as informações do usuário
public function getUserInfo(){
return $this->user;
}
// Le todo o sock a cada 1 Byte.
public function write($message){
$num = 0;
$length = strlen($message);
do{
$buff = substr($message, $num);
$num += socket_write($this->sock,$buff);
}while( $num != $length );
}
// Envia o ACK
public function sendAck(){
do{
$num = socket_write($this->sock,$this->ack);
}while( $num == 0 );
}
// Recebe o ACK
public function waitAck(){
do {
$buff = socket_read($this->sock,1,PHP_BINARY_READ);
}while( $buff != $this->ack );
}
// Le todo o sock a cada 1 Byte.
public function read(){
$message = '';
do {
$buff = socket_read($this->sock,1,PHP_BINARY_READ);
$message .= $buff;
}while( $buff != "\n" );
return $message;
}
}
?>
I use this script to listen on 3 ports, but with 'netstat -a' in other console reports only the last one is 'LISTEN'.
#!/usr/bin/php -q
<?php
$services = array(
56700 => 'daemon1',
56701 => 'daemon2',
56703 => 'daemon3',
);
// --- Marca el Tiempo Ilimitado para pararse ---
set_time_limit (0);
$sockets = array();
foreach($services as $port => $daemon)
{
// --- Abre el socket ---
if ($sock = @socket_create_listen($port))
{
$sockets[$sock] = $daemon;
}
else
{
echo("error\n");
}
}
print_r($sockets);
while (1)
{
echo "";
}
?>
