Update SocketClient to support UDP. Change DNS queries to use SocketClient

This commit is contained in:
2023-04-23 23:08:30 +10:00
parent 073be20ceb
commit b1c62ae227
5 changed files with 262 additions and 164 deletions

View File

@@ -56,11 +56,13 @@ final class SocketClient {
private string $rx_buf = '';
public function __construct (\Socket $connection) {
socket_getsockname($connection,$this->address_local,$this->port_local);
socket_getpeername($connection,$this->address_remote,$this->port_remote);
Log::info(sprintf('%s:+ Connection host [%s] on port [%d]',self::LOGKEY,$this->address_remote,$this->port_remote));
$this->connection = $connection;
if ($this->type === 'TCP') {
socket_getsockname($connection,$this->address_local,$this->port_local);
socket_getpeername($connection,$this->address_remote,$this->port_remote);
Log::info(sprintf('%s:+ Connection host [%s] on port [%d] (%s)',self::LOGKEY,$this->address_remote,$this->port_remote,$this->type));
}
}
public function __get($key) {
@@ -73,6 +75,17 @@ final class SocketClient {
case 'speed':
return Arr::get($this->session,$key);
case 'type':
switch ($x=socket_get_option($this->connection,SOL_SOCKET,SO_TYPE)) {
case SOCK_STREAM:
return 'TCP';
case SOCK_DGRAM:
return 'UDP';
default:
return sprintf('UNKNOWN [%d]',$x);
}
default:
throw new \Exception(sprintf('%s:! Unknown key [%s]:',self::LOGKEY,$key));
}
@@ -226,6 +239,7 @@ final class SocketClient {
/**
* Create a client socket
*
* @param string $address
* @param int $port
* @return static
@@ -292,24 +306,43 @@ final class SocketClient {
/**
* Read data from the socket.
* If we only want 1 character, we'll return the ASCII value of the data received
*
* @param int $timeout
* @param int $len
* @return int|string
* @param int $size
* @return string
* @throws SocketException
*/
public function read(int $timeout,int $len=1024)
public function read(int $timeout,int $len=1024,int $size=1024): string
{
if ($this->DEBUG)
Log::debug(sprintf('%s:+ Start [%d] (%d)',self::LOGKEY,$len,$timeout));
// We have data in our buffer
if ($this->rx_left >= $len) {
$result = substr($this->rx_buf,$this->rx_ptr,$len);
$this->rx_ptr += $len;
$this->rx_left -= $len;
if ($this->rx_left === 0) {
$this->rx_buf = '';
$this->rx_ptr = 0;
}
return $result;
}
if ($timeout AND ($this->hasData($timeout) === 0))
return '';
$buf = '';
try {
$rc = socket_recv($this->connection,$buf, $len,MSG_DONTWAIT);
if ($this->type === 'TCP')
$rc = socket_recv($this->connection,$buf, $size,MSG_DONTWAIT);
else {
$rc = socket_recvfrom($this->connection,$buf, $size,MSG_DONTWAIT,$this->address_remote,$this->port_remote);
}
} catch (\Exception $e) {
Log::error(sprintf('%s: - socket_recv Exception [%s]',self::LOGKEY,$e->getMessage()));
@@ -320,8 +353,23 @@ final class SocketClient {
if ($this->DEBUG)
Log::debug(sprintf('%s: - Read [%d]',self::LOGKEY,$rc));
if ($rc === FALSE)
if ($rc === FALSE) {
// If we have something in the buffer, we'll send it
if ($this->rx_left && $this->rx_left < $len) {
$return = substr($this->rx_buf,$this->rx_ptr);
$this->rx_left = 0;
$this->rx_ptr = 0;
$this->rx_buf = '';
return $return;
}
throw new SocketException($x=socket_last_error($this->connection),socket_strerror($x));
}
$this->rx_buf .= $buf;
$this->rx_left += strlen($buf);
// If our buffer is null, see if we have any out of band data.
// @todo We throw an errorexception when the socket is closed by the remote I think.
@@ -334,7 +382,7 @@ final class SocketClient {
}
}
return is_null($buf) ? '' : $buf;
return $this->read($timeout,$len,$size);
}
/**
@@ -343,7 +391,7 @@ final class SocketClient {
*
* @param int $timeout
* @return int
* @throws SocketException
* @throws \Exception
*/
public function read_ch(int $timeout): int
{
@@ -410,7 +458,9 @@ final class SocketClient {
if (is_null($length))
$length = strlen($message);
return socket_write($this->connection,$message,$length);
return ($this->type === 'TCP')
? socket_write($this->connection,$message,$length)
: socket_sendto($this->connection,$message,$length,0,$this->address_remote,$this->port_remote);
}
/**

View File

@@ -138,14 +138,15 @@ final class SocketServer {
private function loop_udp()
{
$buf = '';
$remote = [];
$remote['ip'] = NULL;
$remote['port'] = NULL;
while (TRUE) {
if (socket_recvfrom($this->server,$buf,512,MSG_WAITALL,$remote['ip'],$remote['port']))
$this->handler[0]->{$this->handler[1]}($remote,$buf,$this->server);
$r = new SocketClient($this->server);
if ($r->hasData(30)) {
$this->handler[0]->{$this->handler[1]}($r);
// Sleep so our thread has a chance to pick up the data from our connection
usleep(50000);
}
}
}