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;
}
}
?>
socket_create_listen
(PHP 4 >= 4.1.0, PHP 5)
socket_create_listen — Bağlantı kabul etmek için port üzerinde bir soket açar
Açıklama
$port
[, int $kuyruk = 128
] )
socket_create_listen() işlevi, yeni bağlantıları
beklemek için belirtilen port üzerindeki tüm arabilirimleri dinleyen
AF_INET türünde yeni bir soket özkaynağı oluşturur.
Bu işlev yeni bağlantı kabul etmek için sadece dinleme yapacak yeni bir soket oluşturmayı kolaylaştırmak için tasarlanmıştır.
Değiştirgeler
-
port -
Tüm arabirimlerde dinlenecek port.
-
backlog -
İşlem için kuyruğa alınacak azami gelen bağlantı sayısı. Bu değiştirgeye
SOMAXCONNatanabilir. Daha fazla bilgi için socket_listen() işlevine bakınız.
Dönen Değerler
Hata durumunda FALSE, yoksa yeni bir soket özkaynağı döner. Hata kodu
socket_last_error() işlevi ile alınabilir. Bu hata
kodunu socket_strerror() işlevine aktararak hatayı
açıklayan dizgeyi alabilirsiniz.
Notlar
Bilginize:
Sadece belli bir arabirimi dinleyecek bir soket oluşturmak isterseniz socket_create(), socket_bind() ve socket_listen() işlevlerini kullanın.
Ayrıca Bakınız
- socket_create() - Bir soket oluşturur (iletişim için bir uç)
- socket_create_pair() - Ayrılması olanaksız bir soket çifti oluşturur ve bunları bir dizide saklar
- socket_bind() - Soketi bir isimle ilişkilendirir
- socket_listen() - Bir soketi bağlantı kabul etmek için dinler
- socket_last_error() - Soket üzerindeki son hatanın kodunu döndürür
- socket_strerror() - Bir soket hatasıyla ilgili açıklamayı döndürür
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);
?>
Remember that ports are only valid from 1 - 65536
