Ce face stream_socket_server
stream_socket_server deschide un port pe care alte programe se pot conecta. Conexiunile se primesc apoi cu stream_socket_accept. Așa se scriu în PHP servere mici: un serviciu de chat, un server de test, un worker care primește comenzi.
Adresa tcp://127.0.0.1:8000 acceptă doar conexiuni de pe aceeași mașină, iar tcp://0.0.0.0:8000 din toată rețeaua. Portul 0 cere sistemului un port liber. Flag-urile implicite (12) sunt STREAM_SERVER_BIND | STREAM_SERVER_LISTEN; pentru UDP folosește doar STREAM_SERVER_BIND.
Parametri
| Parametru | Descriere |
|---|---|
$address |
Adresa de ascultare, de exemplu tcp://0.0.0.0:8000 sau udp://127.0.0.1:9000. |
$error_code |
Opțional. Variabilă pentru codul erorii. |
$error_message |
Opțional. Variabilă pentru mesajul erorii. |
$flags |
Opțional. Implicit STREAM_SERVER_BIND | STREAM_SERVER_LISTEN. |
$context |
Opțional. Context, de exemplu cu certificatul pentru un server tls://. |
Ce returnează
Socket-ul serverului sau false la eroare (de exemplu port ocupat).
Exemple
Exemplul 1: Server pe un port ales de sistem
<?php
$server = stream_socket_server("tcp://127.0.0.1:0", $cod, $mesaj);
[$ip, $port] = explode(":", stream_socket_get_name($server, false));
echo "Ascult pe $ip\n";
echo "Port valid: " . ($port > 0 ? "da" : "nu");
Rezultat
Ascult pe 127.0.0.1
Port valid: da
Exemplul 2: Un server care răspunde cu majuscule
Ca exemplul să ruleze singur, clientul este în același script. Într-un server real, stream_socket_accept stă într-o buclă și așteaptă clienți din alte programe.
<?php
$server = stream_socket_server("tcp://127.0.0.1:0", $cod, $mesaj);
$client = stream_socket_client("tcp://" . stream_socket_get_name($server, false));
fwrite($client, "salut din arad\n");
$conexiune = stream_socket_accept($server);
$cerere = fgets($conexiune);
fwrite($conexiune, strtoupper($cerere));
fclose($conexiune);
echo fgets($client);
Rezultat
SALUT DIN ARAD
Exemplul 3: Port deja ocupat
<?php
$primul = stream_socket_server("tcp://127.0.0.1:0");
$adresa = stream_socket_get_name($primul, false);
$al_doilea = @stream_socket_server("tcp://$adresa", $cod, $mesaj);
var_dump($al_doilea);
echo $mesaj;
Rezultat
bool(false)
Address already in use
Greșeli frecvente
- Asculți pe
0.0.0.0pentru un serviciu intern. Portul devine accesibil din toată rețeaua. Pentru servicii locale, folosește127.0.0.1. - Alegi un port sub 1024 (de exemplu 80). Pe Linux și macOS ai nevoie de drepturi de root; folosește un port peste 1024.
- Creezi un server UDP cu flag-urile implicite.
STREAM_SERVER_LISTENnu are sens la UDP și funcția eșuează. DăSTREAM_SERVER_BIND.
Comenzi înrudite
stream_socket_accept: Așteaptă și acceptă o conexiune nouă pe un socket de server; returnează stream-ul pentru acel client.stream_socket_client: Deschide o conexiune către un server dată ca adresă completă (tcp://, udp://, tls://, unix://) și o returnează ca stream.stream_socket_get_name: Returnează adresa locală sau adresa celuilalt capăt al unui socket, în forma ip:port.stream_select: Așteaptă până când unul sau mai multe stream-uri (socket-uri, pipe-uri) au date de citit sau pot primi date.