简体   繁体   中英

Socket connection on same machine, PHP to C++ and back

I had to implement a communication between an application written in c++ and a web server scripted with PHP. The basic idea was to create a socket with the c++ application, binding it and listen for the PHP connection to it. The PHP would then send a message over TCP asking for data and the c++ would send back the answer. Single header request, single string(JSON) answer. So far, so good. This is the code I used for the PHP side:

<?php
error_reporting(E_ALL);

$service_port = 8080;
$address = 'localhost';


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

echo "Attempting to connect to '$address' on port '$service_port'...";
$result = socket_connect($socket, $address, $service_port);
if ($result === false) {
    echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n";
} 


$in = "request1";

$out = '';

socket_write($socket, $in, strlen($in));

$buf = 'This is my buffer.';
if (false !== ($bytes = socket_recv($socket, $buf, 2048, MSG_WAITALL))) {
    echo "Read $bytes bytes from socket_recv(). Closing socket...";
} else {
    echo "socket_recv() failed; reason: " . socket_strerror(socket_last_error($socket)) . "\n";
}
socket_close($socket);

echo $buf . "\n";
//elaborate the $buf
?>

Now I would like to implement also an auto-update of the data, with the c++ (server side) sending data and the PHP side(client side) to collect them. The data update should be done every minute. Sadly I don't have much experience with web developing, so I'm kindly asking some advices on that.

The easiest thing I could do was looping the PHP code untill a known message got received. The problem I faced is that I don't get data untill the loop is over and the PHP script ends. To overcome the problem I tried to set PHP side the socket to be non-blocking replacing in the socket_recv the option MSG_WAITALL with MSG_DONTWAIT but nothing changed. Then I tried to break out of the PHP script, but it can't be done since I need to cycle it to get the data every second. Plus I get another problem, during the loop cycles, the apache server the PHP is running on is getting a 503 error, Server Unavailable. I don't know why it happens, maybe the received message buffer is full, or the script takes too many resources. Due to my lack of experience I can't understand why. I know there are good libraries to perform what I need but I'm working on an embedded machine so I'm limited to work with basic libraries.

How can I achieve the PHP on the Apache server to get timed data from the c++ application ? What am I overlooking ? Thanks a lot in advance for your help.

Edit: Deleted rhetorical question.

Using php to obtain data from another process via tcp/ip will require a bit more effort compared to sending data from a php script executed via apache to another process using tcp/ip sockets.

Your php script will need to be started outside of apache and will require an infinite loop that continuously listens to the given port to read input data. The following post outlines what I believe you are after.

EDIT

In order to display the results on the web page you could use an in memory data store such as Redis. The php server application would update a data structure in redis, then the webpage onload could pull the latest value from redis and display it on screen, however this would require a page refresh.

If you require that the data be refreshed immediately once received without server postback, this will require some javascript. When a user loads the page you would initialize a websocket connection with a websocket server (people generally use node.js and socket.io for implementing this but you can code a websocket server in anything that supports the technology). The websocket server would be subscribed to a redis channel that when updated would send the new values to all connected clients. I suppose this could be done without redis as well depending on what your requirements are. The program for the websocket server could also be the server that accepts the information from your c++ program using a separate thread. When data comes in from the c++ program you could then send it directly to the clients connected via websocket.

Don't reinvent the wheel. Use a websockets. It's designed to do this async communication and you can send JSON over it just fine.

There are libraries for C++ and PHP, meaning this should be pretty easy.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM