0

currently I am writing an opencv C++ application. I want this c++ program keeps running at all time in a waiting status and once user clicks a button on the php code(Jquery) and the program will be activated. I have decided to use socket to active the program and I don't know how to pass the value back to php after this program finish running. Anyone suggest any solution. I have search quite a lot on internet but most of them have to restart the program every time to get the data, like Passing data from C++ to PHP. Thanks

Community
  • 1
  • 1
JHJL
  • 3
  • 4
  • The best solution depends on whether the two programs will run on the same machine or not. – Christian Hackl Oct 11 '14 at 09:13
  • But in any case, if you use sockets, then what's the problem? You do then have established a completely flexible form of communication already, don't you? – Christian Hackl Oct 11 '14 at 09:14
  • i am new in socket communication.. is it a way to use socket to pass back the value to the php..? Both are running on the same machine. @ChristianHackl – JHJL Oct 11 '14 at 09:16

1 Answers1

1

I don't know how to pass the value back to php after this program finish running

I think after is the keyword here. I suspect your confusion stems from the fact that you somehow want to pass the return value of the C++ program to your PHP program, i.e. something like:

int main()
{
    // ...
    return value; // to PHP
}

This is the wrong approach. Your C++ program must use the socket to pass data to PHP while it is running.

I recommend you try Boost.Asio to develop the C++ socket part. Have a look at the examples, especially at one of the most simple ones, blocking_tcp_echo_server.cpp. Go to http://www.boost.org/users/download/ to find out how to install Boost on your machine.

Here is a very short C++ program based on the Boost example:

#include <iostream>
#include <string>
#include <sstream>
#include <boost/bind.hpp>
#include <boost/smart_ptr.hpp>
#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>

using boost::asio::ip::tcp;

typedef boost::shared_ptr<tcp::socket> socket_ptr;

void session(socket_ptr sock)
{
    std::cout << "session...\n";
    try
    {
        boost::system::error_code error;
        boost::asio::streambuf buffer;
        boost::asio::read_until(*sock, buffer, "\n", error);
        if (error)
        {
            throw boost::system::system_error(error);
        }
        std::istream str(&buffer);
        std::string from_php;
        std::getline(str, from_php);

        std::cout << from_php << "\n";
        std::string const from_cpp = "from C++";
        boost::asio::write(*sock, boost::asio::buffer(from_cpp));
        std::cout << "finished\n";
    }
    catch (std::exception const &e)
    {
        std::cerr << "Exception in thread: " << e.what() << "\n";
    }
}

void server(boost::asio::io_service &io_service)
{
    tcp::acceptor a(io_service, tcp::endpoint(tcp::v4(), 1234));
    for (;;)
    {
        socket_ptr sock(new tcp::socket(io_service));
        a.accept(*sock);
        boost::thread t(boost::bind(session, sock));
    }
}

int main()
{
    try
    {
        boost::asio::io_service io_service;
        server(io_service);
    }
    catch (std::exception const &e)
    {
        std::cerr << "Exception: " << e.what() << "\n";
    }
}

It receives a string on port 1234 and saves it in a std::string called from_php. The string from PHP must be terminated with a '\n'. It then sends the string "from C++" back, upon which the socket is eventually closed.

Now look at the PHP documentation's socket examples (look for "Example #2 Socket example: Simple TCP/IP client"). Again, here is a simplified version:

<?php
error_reporting(E_ALL);

$service_port = 1234;
$address = gethostbyname('localhost');

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
    die("socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n");
}

$result = socket_connect($socket, $address, $service_port);
if ($result === false) {
    die("socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n");
}

$in = "from PHP\n";
socket_write($socket, $in, strlen($in));

$from_cpp = "";
while ($data = socket_read($socket, 2048)) {
    $from_cpp .= $data;
}

echo $from_cpp;

socket_close($socket);
?>

It sends the string "from PHP\n" to port 1234 on localhost and receives a string back from it, which it stores in variable from_cpp.

This should give you enough information to play with and do further research.

Christian Hackl
  • 27,051
  • 3
  • 32
  • 62
  • @JHJL: No, why would it? Just turn it into a string and make sure the C++ and PHP parts use the same convention. For example, if your calculation value is just a simple `int`, turn it into a string with `boost::lexical_cast` (or `std::to_string` if you use C++11). – Christian Hackl Oct 11 '14 at 10:54
  • std::string const from_cpp = std::to_string(a number); is it right? – JHJL Oct 11 '14 at 10:57
  • @JHJL: Yes. I must say that perhaps socket programming might come a bit early; it might be more productive in the long run if you got a firm grasp on such C++ basics first. Socket programming, due to its inherent low-level nature, just isn't a beginners' topic. Of course I don't mean to discourage you. But you should expect some further rather big obstacles on the road... – Christian Hackl Oct 11 '14 at 11:02
  • thank you for your advice... if i have further question, i may post here and i hope you are willing to help me. – JHJL Oct 11 '14 at 11:05