(PHP 4 >= 4.1.0, PHP 5)
socket_create_listen — Öffnet einen Socket, um Verbindungen über einem gegebenen Port aufzubauen
socket_create_listen() erzeugt einen neuen Socket-Deskriptor vom Typ AF_INET, der an allen lokalen Schnittstellen eines gegebenen Ports auf neue Verbindungen wartet.
Diese Funktion soll die Erzeugung eines neuen Sockets erleichtern, der nur auf neue Verbindungsanforderungen wartet, um sie zu akzeptieren.
Der Port, den alle Schnittstellen abhören.
Der Parameter backlog gibt an, wie groß die Warteschlange mit wartenden Verbindungen maximal werden darf. SOMAXCONN kann als backlog übergeben werden. Mehr Informationen hierzu finden Sie bei socket_listen().
socket_create_listen() gibt bei Erfolg einen neuen Socket-Deskriptor zurück oder FALSE, falls ein Fehler aufgetreten ist. Der Fehlercode kann mit der Funktion socket_last_error() abgefragt werden. Dieser Fehlercode kann an die Funktion socket_strerror() übergeben werden, um eine textuelle Beschreibung des Fehlers zu erhalten.
Hinweis:
Falls Sie einen Socket erzeugen möchten, der nur bestimmte Schnittstellen abhört, müssen Sie socket_create(), socket_bind() und socket_listen() verwenden.
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 "";
}
?>
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.
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);
?>