php-upnp/src/HTTPU/Endpoint.php

103 lines
2.9 KiB
PHP

<?php
namespace NoccyLabs\UPnP\HTTPU;
class Endpoint
{
protected $socket;
/**
*
* @param string $bind The IP to bind to (0.0.0.0 for all)
* @throws EndpointException
*/
public function __construct($bind='0.0.0.0', $port=0, $reuse_port=false)
{
//Create the socket.
$socket = @socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
// Handle errors on failure
if (!$socket) {
$errno = socket_last_error();
$errmsg = socket_error($errno);
throw new EndpointException("Could not create socket: {$errmsg} ({$errno})");
}
//Set socket options.
socket_set_nonblock($socket);
socket_set_option($socket, SOL_SOCKET, SO_BROADCAST, 1);
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
if ($reuse_port) {
socket_set_option($socket, SOL_SOCKET, SO_REUSEPORT, 1);
}
if(!socket_bind($socket, $bind, $port)) {
$errno = socket_last_error();
$errmsg = socket_error($errno);
throw new EndpointException("Could not bind socket to {$bind}:{$port}: {$errmsg} ({$errno})");
}
$this->socket = $socket;
}
public function __destruct()
{
if ($this->socket) {
@socket_close($this->socket);
}
}
/**
*
*
* @param Request $request The request to send
* @return Response[] The received responses if any
*/
public function send(Request $request, $wait_time=5)
{
// Get the details from the request
$buffer = $request->getBuffer();
$addr = $request->getAddress();
$port = $request->getPort();
if (false === socket_sendto($this->socket, $buffer, strlen($buffer), 0, $addr, $port)) {
$errno = socket_last_error();
$errmsg = socket_error($errno);
throw new EndpointException("Send failed: {$errmsg} ({$errno})");
}
// Wait $wait_time seconds for responses to arrive
$read_expires = microtime(true) + $wait_time;
$responses = [];
while (microtime(true) < $read_expires) {
if (socket_recvfrom($this->socket, $data, 5120, MSG_DONTWAIT, $raddr, $rport)) {
//while(is_string($data = socket_read($this->socket, 5120))) {
$response = Response::createFromString($data, $raddr);
if ($response) {
$responses[] = $response;
}
}
usleep(10000);
}
return $responses;
/*
while(socket_select($read, $write, $except, 3)) {
//Read received packets with a maximum size of 5120 bytes.
while(is_string($data = socket_read($this->socket, 5120))) {
echo "READ: {$data}\n";
return $data;
}
}
*/
}
}