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 — Abre un socket en un puerto para aceptar conxiones
Descripción
$port
[, int $backlog = 128
] )
socket_create_listen() crea un nuevo recurso socket de
tipo AF_INET que escucha en todas
las interfaces locales del puerto dado esperando para nuevas conexiones.
Esta función tiene la intención de facilitar la tarea de crear un nuevo socket que sólo escuche para aceptar nuevas conexiones.
Parámetros
-
port -
El puerto en el que escuchar todas las interfaces.
-
backlog -
El parámetro
backlogdefine la longitud máxima a la que puede aumentar la cola de conexiones pendientes. Se puede pasarSOMAXCONNcomo el parámetrobacklog, véase socket_listen() para más información.
Valores devueltos
socket_create_listen() devuelve un nuevo recurso socket
en caso de éxito o FALSE en caso de error. El código de error de puede recuperar con
socket_last_error(). Este código se puede pasar a
socket_strerror() para obtener una explicación textual del
error.
Notas
Nota:
Si quiere crear un socket que sólo escuche una cierta interfaz tiene que usar socket_create(), socket_bind() y socket_listen().
Ver también
- socket_create() - Crear un socket (extremo de comunicación)
- socket_create_pair() - Crea un par de sockets indistinguibles y los almacena en una matriz
- socket_bind() - Vincula un nombre a un socket
- socket_listen() - Escucha una conexión sobre un socket
- socket_last_error() - Devuelve el último error sobre un socket
- socket_strerror() - Devuelve una cadena que describe un error de socket
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 "";
}
?>
