PHP Socket and TCP IP Command - php

I have a device with relays connected to my network. I am able to connect to device via the built in url host to turn on and off the relays. What I would like to do is be able to send commands to the device turning on and off the relays either via php, vb code or make my own ASP url's for each relay that will do that same thing. I am using Visual Studio 2013.
I have the IP of the device and the port number.
I need to send it a 6 byte command: example
0xFD,Ox2,020,1,0,0x5d
This command will tell Relay 1 to turn on.
0xFD,Ox2,020,1,1,0x5d
This command will tell Relay 1 to turn off.
Any help with this would be greatly appreciated Thank you!

I think you may want to check out fsockopen
You can do something like:
$socket = fsockopen($ip, $port);
if($socket) {
fwrite($socket, $string);
}

Instead of building an ASP web site just to turn on/off the device, you can simply create a very simple HTML page with 2 buttons (ON and OFF). If you put this page on the network, it can be opened by any browser.
Assuming that your command string is processed as an URL, the Javascript functions executed when clicking on a button would call the following procedure:
function httpGet(theUrl)
{
var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", theUrl, false );
xmlHttp.send( null );
return xmlHttp.responseText;
}
If the device is controlled by TCP/IP, you may need to code some C# functions, unless using a utility allowing to send data to TCP/IP (example "Packet sender").

Related

Trying to tcp connect Laravel app to workerman server

I have a server running and waiting/listening for connections. The server is based on Mark Framework which is using Workerman. So far I'm able to start the server and when I load the URL/host on the browser it shows content (in this case I'm expecting a simple Hello world).
This is index.php which I use to start the server
use Mark\App;
require 'vendor/autoload.php';
$api = new App('http://127.0.0.1:8080');
$api->count = 2; // process count
$api->any('/', function ($requst) {
return 'Hello world';
});
$api->start();
Now, I have a simple Laravel app that I want when I open a certain page to connect to that server and show the content from it.
I'm not sure how to do this. What I have so far in the controller is this
public function index() {
try {
$host = "127.0.0.1";
$port = 8080;
$resource = stream_socket_client("tcp://$host:$port", $error_no, $error_str, 20, STREAM_CLIENT_CONNECT);
$lines = stream_get_line($resource, 8192);
var_dump($lines);
} catch(Exception $e){
return response($e->getMessage(), 500);
}
var_dump($resource);
return View::make('index');
}
var_dump($resource) which is a variable for the connection shows
resource(10) of type (stream)
var_dump($lines); shows false which I guess is because the $resource doesn't make any connection
bool(false)
Any ideas here on how to approach this?
TCP connection does not rely on any protocol, it's just a pure data transfer protocol which enables you to transfer bytes with ACL confirmation. You name it TCP and you include some Mark Framework which is http protocol based process.
The docs say it helps you to quickly write APIs with php. It means it's not a TCP raw server with custom protocol but it is a http protocol oriented server which is simply a REST API ready for http GET/POST requests to make your life easier.
You can do the same things with laravel on both sides until you need realtime connection. Realtime socket connections are made via javascript because HTTP is not built for this.
From laravel side just read: https://laravel.com/docs/9.x/http-client#making-requests
I might overwatched something, but sockets are rarely used in web. By calling TCP you called for 'sockets' and your post seems to negate your need for them.

C++ WinSock Get Data From PHP Page?

Hello I'm quite new to using sockets and am not that familiar with them yet, Basically all i am trying to do is pass a string variable to a web address (e.g. www.example.com/index.php?Example=StringExample) and then get a response, so for example it would return "Test Example" if index.php looked like this:
<?php
if($_GET['Example'] == "StringExample")
{
echo "Test Example";
}
?>
Here is what I've tried in c++:
struct sockaddr_in SocketAddress;
hostent* addr = gethostbyname("www.example.com/index.php?Example=StringExample");
int sizeofaddr = sizeof(addr);
SocketAddress.sin_addr.s_addr = inet_addr(addr->h_name);
SocketAddress.sin_port = htons(80);
SocketAddress.sin_family = AF_INET;
SOCKET Connection = socket(AF_INET, SOCK_STREAM, NULL);
if (connect(Connection, (SOCKADDR*)&addr, sizeofaddr) != 0)
{
return 0; //Failed to Connect
}
char buffff[256];
recv(Connection, buffff, sizeof(buffff), NULL);
//"Test Example" now stored in buffff
What am i doing wrong?
Btw in my case i would not like to use any libraries like boost or anything like that. Thanks for the help :)
gethostbyname("www.example.com/index.php?Example=StringExample");
"www.example.com/index.php?Example=StringExample" is not a valid server name. This is an entire URL; a server name would be "www.example.com". gethostbyname() takes the name of a server, and not a URL, and returns its IP address. Additionally, gethostbyname() has been obsoleted. New code should use the getaddrinfo(3) function, instead.
This is obviously an HTTP URL. To download a document via HTTP it is a lot more work than just connecting a socket. Establishing a socket connection is just the first step in the process of downloading a document from an HTTP server. This must be followed by sending a valid HTTP request, and then receiving an HTTP response from the server.
There are many libraries, such as curl, that implement the entire client-side process needed to download an HTTP document, that will handle the socket connection themselves.
But there's nothing wrong with trying to implement this yourself, either. It's a good programming excersize.
So, after resolving www.example.com's IP address, you will need to
1) Connect to the server's port 80, the default HTTP port.
2) Send an HTTP request for "/index.php?Example=StringExample".
3) Parse the HTTP response.
The specification for HTTP requests and responses is defined by RFC 2616, which you can consult for complete documentation of how HTTP requests and responses are structured.
If you want to access a web server with sockets, you have to keep in mind:
You can open a tcp/ip connection to your web server
BUT afterwards you have to do the http protocol by yourself
In case of your example:
hostent* addr = gethostbyname("www.example.com");
//...
const char* request = "GET index.html"
send(Connection, request, strlen(request), NULL)
//fetch index.html with a recv and parse it
To be more precise, if you want to access your server, you have to take a look how GET, PUT, POST, etc. are implemented in the http protocol, send the proper commands to your web server and recv() the replies

connect to a server with PHP and see if that server can ping another

I personally don't see how this can be done even though these are my servers. But I want to know if my servers can reach external sites--ping a generic website for example--have outgoing communication. That is, I want to use execute a PHP script on one server, connecting to another of my servers, and test if the second server can ping a website, for example. So I know how to use PHP on the server my script is executing from to ping a website with fopensocket. I just don't know how to set this up to test another server's pingability. I mean I have the credentials but the only way is to have my script on each and every server and then reach the script and execute them. That is not what I want. I want to do this from the one/external server and just feed my script the ip/port/uid/pwd of the server I want to test.
An easy API would look something like:
SERVER1:
// get response from server2
$response = file_get_contents('http://www.server2.com/api.php?method=ping&ip=IP&port=PORT&uid=UID&pwd=PWD');
// do json_decode() if response is json string
SERVER2 (api.php):
// respond to API call
if (isset($_GET['method']) && $_GET['method'] == 'ping') {
// get other params and do your ping function
echo $pingresult; // perhaps a json encoded array
exit;
}
There is no security so you could send an API password or do it with OAuth or HMAC

Decoding network chars (HTML5 Websocket)

I'm trying to develop a webchat with HTML5 websocket (with hybi-17 protocol) but I've some problems with chars decoding.
This is what I send through the client (user-agent: Firefox 7):
var socket = new MozWebSocket ('ws://localhost/server.php');
socket.onopen = function () {
alert ('Opened!');
}
Then, I send these data:
socket.send ('Hello');
socket.send ('World');
And this is the server-side code:
$bytes = #socket_recv ($socket, $buffer, BUFSIZE, 0);
if (($bytes == 0) || ($bytes == 2)) {
this->disconnect ($socket);
}
else {
echo $buffer;
}
While this is the data recevied echoed:
��6S~g?Y (Hello)
���~����� (World)
As you can see, the socket is opened and data travels from the client to the server.
The server works with PHP5 and uses normal socket functions to build the connection.
How can I decode that unreadable string in a human readable one?
Thanks in advance.
You have made one of the most common errors people make when they first start writing code that uses TCP -- you forgot to implement the protocol!
In your case, you forgot it in the server. The client already has a WebSocket implementation, and you request it by creating a 'MozWebSocket' object. The WebSocket specification says, "Each frame starts with a 0x00 byte, ends with a 0xFF byte, and contains UTF-8 data in between." Where's the code in the server to find the start of a frame and the end of a frame? Where the code to discard the 0xFF byte?
You actually have to implement the protocol. The protocol specification tells you how to decode the received data. (In your case, the data you are seeing as junk is most likely part of the protocol handshake -- the part that looks like ^n:ds[4U in this description of the handkshake phase.)
I'm pretty sure your method of invoking a PHP script to handle the WebSocket call through the web server will not work. That is, unless your web server knows how to do this -- WaterSpout and phpdaemon do.
Using the base server.php and client.html from http://code.google.com/p/phpwebsocket/ along with modification from HTML5 WebSocket with hybi-17 to deal with the single key standard I can successfully send one message to the server before it closes unexpectedly. It's at least a step closer just not sure as of yet why it closes after one successful message.

PHP web service, send response before end of script execution

I have a web service written in PHP to which an iPhone app connects to. When the app calls the service, a series of notification messages are sent to Apple's APNs server so it can then send Push Notifications to other users of the app.
This process can be time consuming in some cases and my app has to wait a long time before getting a response. The response is totally independent of the result of the notification messages being sent to the APNs server.
Therefore, I would like the web service to send the response back to the app regardless of whether the messages to APNs have been sent.
I tried using pcntl_fork to solve the problem:
<?php
...
$pid = pcntl_fork();
if($pid == -1)
{
// Could not fork (send response anyway)
echo "response";
}
else if($pid)
{
// Parent process - send response to app
echo "response";
}
else
{
// Child process - send messages to APNs then die
sendMessageAPNs($token_array);
die();
}
?> // end of script
Unfortunately, the parent process seems to wait for the child process to end before sending the response even though I do not use pcntl_wait in the parent process. Am I doing something wrong or is this normal behaviour? If this is normal then is there another way I can solve this problem?
Thank you!
If you're hosting the PHP process in Apache then you really shouldn't use this: see this for the section that says *Process Control should not be enabled within a web server environment and unexpected results may happen if any Process Control functions are used within a web server environment. *.
You should probably set up a separate daemon in your preferred language of choice and hand the APNS communication tasks off to that. If you really really really must try using ob_flush().
I think you can send the response back before doing the "long" process. Take a look at the flush() function of PHP it'll maybe help

Categories