0

I have a device 192.168.1.113 that transmits its data to 192.168.1.100

I would like PHP to listen to this incoming data and then extract it and enter into a MySQL database.

I have tried the code below to try and get the data to echo out into the browser for starters just to see if I can see the data that is being sent between the two:

<?php
error_reporting(~E_NOTICE);
set_time_limit (0);

$address = "192.168.1.100"; //ip here
$port = 8996; //port number  here
$max_clients = 10;

if(!($sock = socket_create(AF_INET, SOCK_STREAM, 0)))
{
$errorcode = socket_last_error();
$errormsg = socket_strerror($errorcode);

die("Couldn't create socket: [$errorcode] $errormsg \n");
}

echo "Socket created \n";

// Bind the source address
if( !socket_bind($sock, $address , 5000) )
{
$errorcode = socket_last_error();
$errormsg = socket_strerror($errorcode);

die("Could not bind socket : [$errorcode] $errormsg \n");
}

echo "Socket bind OK \n";

if(!socket_listen ($sock , 10))
{
$errorcode = socket_last_error();
$errormsg = socket_strerror($errorcode);

die("Could not listen on socket : [$errorcode] $errormsg \n");
}

echo "Socket listen OK \n";

echo "Waiting for incoming connections... \n";

//array of client sockets
$client_socks = array();

//array of sockets to read
$read = array();

//start loop to listen for incoming connections and process existing 
connections
while (true) 
{
//prepare array of readable client sockets
$read = array();

//first socket is the master socket
$read[0] = $sock;

//now add the existing client sockets
for ($i = 0; $i < $max_clients; $i++)
{
    if($client_socks[$i] != null)
    {
        $read[$i+1] = $client_socks[$i];
    }
}

//now call select - blocking call
if(socket_select($read , $write , $except , null) === false)
{
    $errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);

    die("Could not listen on socket : [$errorcode] $errormsg \n");
}

//if ready contains the master socket, then a new connection has come in
if (in_array($sock, $read)) 
{
    for ($i = 0; $i < $max_clients; $i++)
    {
        if ($client_socks[$i] == null) 
        {
            $client_socks[$i] = socket_accept($sock);

            //display information about the client who is connected
            if(socket_getpeername($client_socks[$i], $address, $port))
            {
                echo "Client $address : $port is now connected to us. \n";
            }

            //Send Welcome message to client
            $message = "Welcome to php socket server version 1.0 \n";
            $message .= "Enter a message and press enter, and i shall reply 
back \n";


            socket_write($client_socks[$i] , $message);
            break;
        }
    }
  }

//check each client if they send any data
for ($i = 0; $i < $max_clients; $i++)
{
    if (in_array($client_socks[$i] , $read))
    {
        $input = socket_read($client_socks[$i] , 1024);

        if ($input == null) 
        {
            //zero length string meaning disconnected, remove and close the 
socket
            unset($client_socks[$i]);
            socket_close($client_socks[$i]);
        }

        $n = trim($input);

        $output = "OK ... $input";

        echo "Sending output to client \n";

        //send response to client
        socket_write($client_socks[$i] , $output);
    }
   }
}
?>

But it just hangs in the browser and doesn't do anything. I know there is data coming across as I have a tool in Windows that listens to the data (see pic).

What am I doing wrong and how do I extract this data and get it into my MySQL database? click here for picture

Sloan Thrasher
  • 4,953
  • 3
  • 22
  • 40
nitro23456
  • 15
  • 6
  • I don't think you ever break out of your `while (true) ` loop, so you're never finishing the script. By default, PHP only sends output upon completion of the script. If you want incremental output, see questions like [this one](https://stackoverflow.com/questions/4399549/display-output-in-parts-in-php) and similar. – Patrick Q Apr 03 '18 at 17:58
  • Thank you for taking the time to help. Would you be able to suggest direct changes to my script? I'm new to this. – nitro23456 Apr 03 '18 at 18:06
  • 1
    Not really, as I don't know exactly what you're trying to do. I suggest you do some research on output buffering and flushing, outputting before completion of the script, etc. To be honest, the code you've included above is quite advanced for someone saying they're new to PHP. If this isn't something that you've written yourself, I'd suggest that you stop, learn the basics, and then make sure you really understand what you're doing before you go any further. Running code that you don't understand is how you get yourself in really bad situations. – Patrick Q Apr 03 '18 at 18:10
  • I'm trying to grab the data that is coming over (as shown in the Windows GUI tool) and then put this data into MySQL database on my webserver. But thankyou for your advice – nitro23456 Apr 03 '18 at 18:35
  • what do you mean by *"it just hangs in the browser"*? how do you start this script? you know you should start it from command line? can you ask the person that wrote this code for some assistance? – rsm Apr 04 '18 at 00:10

1 Answers1

1

Binary socket_read is blocking, see the top 2 comment on http://php.net/manual/en/function.socket-read.php. They both confirm that a PHP_BINARY_READ socket_read is blocking.

I would suggest to use a socket_select with a read timeout. Some snippets:

 $defaultRecvTimeout=750;

socket_set_option($socket6,SOL_SOCKET,SO_RCVTIMEO,$this->millisecToSolArray(self::$defaultRecvTimeout));

        // wait for data to be available, up to timeout
        $r1 = array($this->socket);
        $w = null;
        $e = array($this->socket);
        $readTimeout = socket_get_option($this->socket,SOL_SOCKET,SO_RCVTIMEO);
        $res = socket_select($r1,$w,$e,$readTimeout['sec'],$readTimeout['usec']);

        // check
        if ($res === false) throw new SocketTransportException('Could not examine socket; '.socket_strerror(socket_last_error()), socket_last_error());
        if (!empty($e)) throw new SocketTransportException('Socket exception while waiting for data; '.socket_strerror(socket_last_error()), socket_last_error());
        if (empty($r1)) return false; // Nothing to read, return;
        $d = "";
        $r = 0;
        $buf = '';
        $r += socket_recv($this->socket,$buf,1000,MSG_DONTWAIT);
        if ($r === false) throw new SocketTransportException('Could not read '.$length.' bytes from socket; '.socket_strerror(socket_last_error()), socket_last_error());
        $d .= $buf;
        return $d;

This is not my code, I found it somewhere and unfortunately forgot whom to credit for it. However sockettransport.class.php is a nice class for socket handling: https://github.com/paulv888/cronjobs/blob/3f8683ed1dff0a343dff7114fa2edc50a525c190/myclasses/sockettransport.class.php

Actually the original came from here: https://github.com/onlinecity/php-smpp

PaulV
  • 129
  • 3