Zoeken…


TCP-client socket

Een socket maken die het TCP (Transmission Control Protocol) gebruikt

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

Zorg ervoor dat de socket met succes is gemaakt. De functie onSocketFailure komt uit het voorbeeld van socketfouten in dit onderwerp.

if(!is_resource($socket)) onSocketFailure("Failed to create socket");

Verbind de aansluiting met een gespecificeerd adres

De tweede regel mislukt netjes als de verbinding is mislukt.

socket_connect($socket, "chat.stackoverflow.com", 6667)
        or onSocketFailure("Failed to connect to chat.stackoverflow.com:6667", $socket);

Gegevens naar de server verzenden

De functie socket_write verzendt bytes door een socket. In PHP wordt een bytearray voorgesteld door een string, die normaal niet coderingsongevoelig is.

socket_write($socket, "NICK Alice\r\nUSER alice 0 * :Alice\r\n");

Gegevens ontvangen van de server

Het volgende fragment ontvangt enkele gegevens van de server met behulp van de socket_read functie.

Doorgeven van PHP_NORMAL_READ als de derde parameter leest tot een \r / \n byte, en deze byte is opgenomen in de retourwaarde.

Als u PHP_BINARY_READ , wordt daarentegen de vereiste hoeveelheid gegevens uit de stream gelezen.

Als socket_set_nonblock werd aangeroepen en PHP_BINARY_READ wordt gebruikt, zal socket_read onmiddellijk false retourneren. Anders blokkeert de methode totdat er voldoende gegevens zijn ontvangen (om de lengte in de tweede parameter te bereiken of om een einde van de lijn te bereiken) of de socket wordt gesloten.

Dit voorbeeld leest gegevens van een zogenaamd IRC-server.

while(true) {
    // read a line from the socket
    $line = socket_read($socket, 1024, PHP_NORMAL_READ);
    if(substr($line, -1) === "\r") {
        // read/skip one byte from the socket
        // we assume that the next byte in the stream must be a \n.
        // this is actually bad in practice; the script is vulnerable to unexpected values
        socket_read($socket, 1, PHP_BINARY_READ);
    }

    $message = parseLine($line);
    if($message->type === "QUIT") break;
}

Contactdoos sluiten

Het sluiten van de socket maakt de socket en de bijbehorende bronnen vrij.

socket_close($socket);

TCP-serveraansluiting

Socket creatie

Maak een socket die TCP gebruikt. Het is hetzelfde als het maken van een client-socket.

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

Socket binding

Verbind verbindingen van een bepaald netwerk (parameter 2) voor een specifieke poort (parameter 3) met de socket.

De tweede parameter is meestal "0.0.0.0" , die verbinding van alle netwerken accepteert. Het kan ook

Een veel voorkomende oorzaak van fouten van socket_bind is dat het opgegeven adres al aan een ander proces is gebonden . Andere processen worden meestal gedood (meestal handmatig om te voorkomen dat per ongeluk kritieke processen worden gedood) zodat de sockets worden vrijgemaakt.

socket_bind($socket, "0.0.0.0", 6667) or onSocketFailure("Failed to bind to 0.0.0.0:6667");

Zet een aansluiting op luisteren

Laat de socket naar binnenkomende verbindingen luisteren met socket_listen . De tweede parameter is het maximale aantal verbindingen dat wachtrijen mogelijk maakt voordat ze worden geaccepteerd.

socket_listen($socket, 5);

Behandeling verbinding

Een TCP-server is eigenlijk een server die onderliggende verbindingen verwerkt. socket_accept maakt een nieuwe onderliggende verbinding.

$conn = socket_accept($socket);

Gegevensoverdracht voor een verbinding van socket_accept is hetzelfde als die voor een TCP-clientsocket .

Wanneer deze verbinding moet worden gesloten, roept u socket_close($conn); direct. Dit heeft geen invloed op de oorspronkelijke TCP-server-socket.

Server wordt gesloten

Aan de andere kant, socket_close($socket); moet worden aangeroepen wanneer de server niet meer wordt gebruikt. Hiermee wordt ook het TCP-adres vrijgegeven, waardoor andere processen kunnen binden aan het adres.

Omgaan met socketfouten

socket_last_error kan worden gebruikt om de fout-ID van de laatste fout van de sockets-extensie te krijgen.

socket_strerror kan worden gebruikt om de ID om te zetten in voor mensen leesbare tekenreeksen.

function onSocketFailure(string $message, $socket = null) {
    if(is_resource($socket)) {
        $message .= ": " . socket_strerror(socket_last_error($socket));
    }
    die($message);
}

UDP-serveraansluiting

Een UDP-server (user datagram protocol) is, in tegenstelling tot TCP, niet streamgebaseerd. Het is op pakketten gebaseerd, dat wil zeggen een client verzendt gegevens in eenheden die "pakketten" worden genoemd naar de server en de client identificeert clients aan de hand van hun adres. Er is geen ingebouwde functie die betrekking heeft op verschillende pakketten die vanaf dezelfde client worden verzonden (in tegenstelling tot TCP, waarbij gegevens van dezelfde client worden verwerkt door een specifieke bron die is gemaakt door socket_accept ). Het kan worden gedacht als een nieuwe TCP-verbinding wordt geaccepteerd en gesloten telkens wanneer een UDP-pakket arriveert.

Een UDP-server socket maken

$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);

Een socket aan een adres binden

De parameters zijn dezelfde als die voor een TCP-server.

socket_bind($socket, "0.0.0.0", 9000) or onSocketFailure("Failed to bind to 0.0.0.0:9000", $socket);

Een pakket versturen

Deze regel verzendt $data in een UDP-pakket naar $address : $port .

socket_sendto($socket, $data, strlen($data), 0, $address, $port);

Een pakket ontvangen

Het volgende fragment probeert UDP-pakketten op een client-geïndexeerde manier te beheren.

$clients = [];
while (true){
    socket_recvfrom($socket, $buffer, 32768, 0, $ip, $port) === true
            or onSocketFailure("Failed to receive packet", $socket);
    $address = "$ip:$port";
    if (!isset($clients[$address])) $clients[$address] = new Client();
    $clients[$address]->handlePacket($buffer);
}

Server wordt gesloten

socket_close kan worden gebruikt op de socket_close van de UDP-server. Hiermee wordt het UDP-adres vrijgemaakt, waardoor andere processen kunnen binden aan dit adres.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow