stream_socket_server

(PHP 5)

stream_socket_serverBir Genel Ağ veya Unix alan sunucusu soketi oluşturur

Açıklama

resource stream_socket_server ( string $yerel_soket [, int &$hatanum [, string &$ileti [, int $seçenekler = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN [, resource $bağlam ]]]] )

Belirtilen yerel_soket üzerinde bir akım veya verikatarı soketi oluşturur.

Bu işlev, stream_socket_accept() kullanarak veri kabul etmek üzere bir soket oluşturmaktan başka bir şey yapmaz.

Değiştirgeler

yerel_soket

Oluşturulacak soketin türü standart URL biçemi kullanılarak belirtilir: şema://hedef.

TCP ve UDP gibi Genel Ağ Alanı soketleri (AF_INET) için, uzak_soket'in hedef parçası bir konak ismi veya IP adresinden sonra gelen bir ikinokta imi ve bir port numarasından oluşur. Unix alan soketleri için hedef parçası ise dosya sistemi üstündeki bir soket dosyasını göstermelidir.

Platforma bağlı olarak, Unix alan soketleri mevcut olmayabilir. Kullanılabilecek aktarım çeşitlerinin listesi stream_get_transports() işlevi ile alınabilir. Yerleşik aktarım türlerinin tam listesini Desteklenen Soket Aktarımlarının Listesi sayfasında bulabilirsiniz.

hatanum

Seçimlik hatanum ve ileti değiştirgeleri belirtilmişse, bunlara socket(), bind() ve listen() sistem çağrılarında oluşan sistem seviyesindeki hatanın bilgisi atanır. Eğer hatanum değiştirgesinde 0 döndüğünde işlev FALSE döndürmüşse hata, bind() çağrısından önce oluşmuş demektir. Bu sorunla çoğunlukla soketin ilklendirilmesi sırasında karşılaşılır. hatanum ve ileti değiştirgelerinin daima gönderimli aktarıldıklarına dikkat ediniz.

ileti

hatanum değiştirgesinin açıklamasına bakınız.

seçenekler

Soket oluşturma seçeneklerinden oluşan bir bit maskesi. Öntanımlı değer: STREAM_SERVER_BIND | STREAM_SERVER_LISTEN.

Bilginize:

UDP soketleri için, bu değiştirgeyle STREAM_SERVER_BIND değerini aktarmalısınız.

bağlam

stream_context_create() ile oluşturulmuş geçerli bir bağlam özkaynağı.

Dönen Değerler

Bir hata durumunda FALSE, aksi takdirde oluşturulan soketi döndürür.

Örnekler

Örnek 1 - TCP sunucu soketlerinin kullanımı

<?php
$socket 
stream_socket_server("tcp://0.0.0.0:8000"$errno$errstr);
if (!
$socket) {
  echo 
"$errstr ($errno)<br />\n";
} else {
  while (
$conn stream_socket_accept($socket)) {
    
fwrite($conn'Yerel zaman: ' date('n/j/Y g:i a') . "\n");
    
fclose($conn);
  }
  
fclose($socket);
}
?>

Aşağıdaki örnekte, stream_socket_client() işleviyle ilgili örneklerden birinde yapılan bir zaman sorgusuna bir zaman sunucusunun yanıt vermesi için neler yapıldığı gösterilmiştir.

Bilginize: Çoğu sistem, 1024'ten küçük portları oluşturmak için root yetkisine ihtiyaç duyar.

Örnek 2 - UDP sunucu soketlerinin kullanımı

<?php
$socket 
stream_socket_server("udp://127.0.0.1:1113"$errno$errstrSTREAM_SERVER_BIND);
if (!
$socket) {
    die(
"$errstr ($errno)");
}

do {
    
$pkt stream_socket_recvfrom($socket10$peer);
    echo 
"$peer\n";
    
stream_socket_sendto($socketdate("D M j H:i:s Y\r\n"), 0$peer);
} while (
$pkt !== false);

?>

Notlar

Bilginize: Bir sayısal IPv6 adresi (fe80::1 gibi) belirtirken port numarasıda belirtmek isterseniz IP adresini köşeli ayraçlar arasına almalısınız. Örnek: tcp://[fe80::1]:80.

Ayrıca Bakınız

add a note add a note

User Contributed Notes 7 notes

up
4
andrey at php dot net
9 years ago
Just a small example how to use this function and also stream_select() to make a server that accepts more than one connections (can have many clients connected):
In master we hold all opened connections. Just before calling stream select we copy the array to $read and then pass it ot stream_select(). In case that we may read from at least one socket, $read will contain socket descriptors. $master is needed not to lose references to the opened connections we have.
stream_server.php :
<?php

$master
= array();
$socket = stream_socket_server("tcp://0.0.0.0:8000", $errno, $errstr);
if (!
$socket) {
    echo
"$errstr ($errno)<br />\n";
} else {
   
$master[] = $socket;
   
$read = $master;
    while (
1) {
       
$read = $master;
       
$mod_fd = stream_select($read, $_w = NULL, $_e = NULL, 5);
        if (
$mod_fd === FALSE) {
            break;
        }
        for (
$i = 0; $i < $mod_fd; ++$i) {
            if (
$read[$i] === $socket) {
               
$conn = stream_socket_accept($socket);
               
fwrite($conn, "Hello! The time is ".date("n/j/Y g:i a")."\n");
               
$master[] = $conn;
            } else {
               
$sock_data = fread($read[$i], 1024);
               
var_dump($sock_data);
                if (
strlen($sock_data) === 0) { // connection closed
                   
$key_to_del = array_search($read[$i], $master, TRUE);
                   
fclose($read[$i]);
                    unset(
$master[$key_to_del]);
                } else if (
$sock_data === FALSE) {
                    echo
"Something bad happened";
                   
$key_to_del = array_search($read[$i], $master, TRUE);
                    unset(
$master[$key_to_del]);
                } else {
                    echo
"The client has sent :"; var_dump($sock_data);
                   
fwrite($read[$i], "You have sent :[".$sock_data."]\n");
                   
fclose($read[$i]);
                     unset(
$master[array_search($read[$i], $master)]);
                }
            }
        }
    }
}
?>
stream_client.php:
<?php
$fp
= stream_socket_client("tcp://127.0.0.1:8000", $errno, $errstr, 30);
if (!
$fp) {
    echo
"$errstr ($errno)<br />\n";
} else {
   
fwrite($fp, "Aloha");
    while (!
feof($fp)) {
       
var_dump(fgets($fp, 1024));
    }
   
fclose($fp);
}
?>

Thanks
up
2
frxstrem
4 years ago
Using the OpenSSL extension, PHP can automatically generate self-signed SSL certificates, which can be used for basic authentication and encryption (although I would recommend to use a signed certificate instead) for SSL servers.

I have extended the script by 'e at osterman dot com' to automatically create self-signed certificates:

<?php
// Hello World! SSL HTTP Server.
// Tested on PHP 5.1.2-1+b1 (cli) (built: Mar 20 2006 04:17:24)

// Certificate data:
$dn = array(
   
"countryName" => "UK",
   
"stateOrProvinceName" => "Somerset",
   
"localityName" => "Glastonbury",
   
"organizationName" => "The Brain Room Limited",
   
"organizationalUnitName" => "PHP Documentation Team",
   
"commonName" => "Wez Furlong",
   
"emailAddress" => "wez@example.com"
);

// Generate certificate
$privkey = openssl_pkey_new();
$cert    = openssl_csr_new($dn, $privkey);
$cert    = openssl_csr_sign($cert, null, $privkey, 365);

// Generate PEM file
# Optionally change the passphrase from 'comet' to whatever you want, or leave it empty for no passphrase
$pem_passphrase = 'comet';
$pem = array();
openssl_x509_export($cert, $pem[0]);
openssl_pkey_export($privkey, $pem[1], $pem_passphrase);
$pem = implode($pem);

// Save PEM file
$pemfile = './server.pem';
file_put_contents($pemfile, $pem);

$context = stream_context_create();

// local_cert must be in PEM format
stream_context_set_option($context, 'ssl', 'local_cert', $pemfile);
// Pass Phrase (password) of private key
stream_context_set_option($context, 'ssl', 'passphrase', $pem_passphrase);

stream_context_set_option($context, 'ssl', 'allow_self_signed', true);
stream_context_set_option($context, 'ssl', 'verify_peer', false);

// Create the server socket
$server = stream_socket_server('ssl://0.0.0.0:9001', $errno, $errstr, STREAM_SERVER_BIND|STREAM_SERVER_LISTEN, $context);

while(
true)
{
   
$buffer = '';
    print
"waiting...";
   
$client = stream_socket_accept($server);
    print
"accepted " . stream_socket_get_name( $client, true) . "\n";
    if(
$client )
    {
       
// Read until double CRLF
       
while( !preg_match('/\r?\n\r?\n/', $buffer) )
           
$buffer .= fread($client, 2046);
       
// Respond to client
       
fwrite($client"200 OK HTTP/1.1\r\n"
                        
. "Connection: close\r\n"
                        
. "Content-Type: text/html\r\n"
                        
. "\r\n"
                        
. "Hello World! " . microtime(true)
                         .
"<pre>{$buffer}</pre>");
       
fclose($client);
    } else {
        print
"error.\n";
    }
}

?>
up
1
peterjb at me dot com
4 years ago
I had a horrible time trying to shove a TLS socket into an existing TCP program.  It appears to me that functions like stream_socket_recvfrom and stream_socket_sendto don't work with TLS/SSL (which may be obvious to PHP gurus...sorry if it is, I'm in a bit over my head here).

In the end I ended up doing all my IO with fread() and fwrite(), which solved all my problems.
up
1
davidm at marketo dot com
4 years ago
In some specialized scenarios, you may want to create an AF_INET socket (UDP or TCP) but let the system select an unused port for you.  This is a standard feature of internet sockets but it doesn't seem to be documented how to do this for the stream_socket_server function.  It appears you can get this behavior by selecting zero for the port number, for example, my test below printed "127.0.0.1:4960".

<?php
  $sock
= stream_socket_server("udp://127.0.0.1:0");
 
$name = stream_socket_get_name($sock);
  echo
$name;
?>
up
0
Aurelien Marchand
3 years ago
In the case of AF_UNIX sockets, note the named sockets that will be created respects your umask(). So if you wanted your named socket to be writeable to all, do umask(0) prior to calling stream_socket_server().

AM
up
0
Julien Picalausa
5 years ago
You may have noticed that, unlike socket_listen, stream_socket_server doesn't have a backlog parameter. From the source code of php 5.2.9, it looks like the backlog parameter to the actual listen call is hardcoded to be 5. If this value doesn't suit your needs, you'll have to use the lower-level socket functions.
up
-2
Neil Munro
8 years ago
If you want a high speed socket server, use the low-level sockets instead (socket_create/bind/listen). The stream_socket_server version appears to have internal fixed 8k buffers that will overflow if you don't keep up by reading.

This is a serious problem if you an application that reads the socket for messages and then, say, saves the result in a database. The delay while it is busy processing means you can't read the data in time unless you get involved in muti-threading.

With the the low-level functions, the OS quietly buffers TCP/IP packets so there is no problem (tested on Windows XP Professional).
To Top