I know that PHP does allow you to create a server but what about client? I would need a script that connects to my TCP/IP server on given port and send some data. Is that possible in PHP and if so, could you help me please? I did not find anything useful.
I have my TCP/IP server running on port 1301 and I would need users to be able by clicking on web page send one char to the server.
It's similar to how you would create a server. I'd recommend taking a look at the documentation for socket_connect.
Summaries:
socket_create
socket_bind
socket_connect
socket_write
socket_read
socket_close
Workflow:
Create the socket
Optionally bind it
Connect to the server
Read/write data
Close the socket
I've used this piece before. It's fairly simple; it connects to $ip_address on port $port, and sends the $sendData data to the server, and then reads the response and returns the response.
$sendData = chr(6).chr(0).chr(255).chr(255).'info';
function sendAndGetResponse($ip_address, $port, $sendData){
$socketHandler=#fsockopen($ip_address, $port, $errno, $errstr, 1);
if(!$socketHandler)
{
return false; //offline
}
else
{
$response = '';
stream_set_timeout($socketHandler, 2);
fwrite($socketHandler, $sendData);
while (!feof($socketHandler))
{
stream_set_timeout($socketHandler, 2);
$response .= fgets($socketHandler, 1024);
}
fclose($socketHandler);
return $response;
}
}
You can use CURL if it is HTTP server or create a socket connection http://php.net/manual/en/function.socket-connect.php
Yes, php can act as a HTTP-client with CURL, fsockopen and most easiest way to fetch URL - with file_get_contents()
Related
I'm trying to receive UDP data from a game. And update it on the page constantly. Using JSON to retrieve the data from a function.
Is it possible to separate socket_create/socket_bind from socket_recvfrom?
(I've cut some unnecessary code out of it)
private $socket;
public function socketConnect($port)
{
$ip = '0.0.0.0'; // local IP
$port = 20777; // port to listen
$this->socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_bind($this->socket, $ip, $port) or die("Could not connect");
return view('telemetry');
}
public function getData()
{
while (socket_recvfrom($this->socket, $buf, $bytes, 0, $remote_ip, $remote_port)) {
// do something
return response()->json($data);
}
}
I've tried setting $this->socket to keep the data but that doesn't seem to work.
You cannot do that, no. Sockets created with the socket_* methods are not persistent, since they are low level sockets. And here your two functions are executed in two different page calls that are independent from each other (this is how PHP works).
Furthermore, what you are trying to do right now is a socket server (binding a socket is for server purposes usually), and socket servers need to be open continually to receive data. I would advise you to try to do a CLI program (that can still be done in PHP) and use the socket_recvfrom and socket_sendto methods to get and send your data (after doing your bind), and then store the received data in a database or in a file, to then have your website read from that to send it to your browser. Here is a howto that shows how to create a simple UDP server in PHP.
I'm in the process of creating my own service status script as both a chance to become more familiar with the PHP language and to design it from the ground up as being as efficient as possible for my needs.
A section of my code used in both my cron job and testing a connection parts queries the IP/Port of a service to make sure it is online. My issue is that the script simply queries whether the port is "Unblocked" on that IP so if for instance I was querying port 21 with an FTP server and that FTP server crashed my script would not detect any changes meaning its not doing what I want it to do. Instead I would be wanting the IP and port to be queried and for my script to see if there is actually something running on that port, if there is show online if not error out. I've had a look on google and it seems like I would have to send a packet/receive a response so PHP can tell there's something active? I'm not sure.
This is my current code below:
<?php
$host = $_POST['servip'];
$port = $_POST['servport'];
if (!$socket = #fsockopen($host, $port, $errno, $errstr, 3)) {
echo "Offline!";
} else {
echo "Online!";
fclose($socket);
}
?>
http://php.net/manual/en/function.fsockopen.php
fsockopen — Open Internet or Unix domain socket connection The socket
will by default be opened in blocking mode. You can switch it to
non-blocking mode by using stream_set_blocking(). The function
stream_socket_client() is similar but provides a richer set of
options, including non-blocking connection and the ability to provide
a stream context.
Since fsockopen will either connect or not connect (timeout) then that tells you whether or not a connection is available ("open") or being blocked (firewall, etc).
// Ping by website domain name, IP address or Hostname
function example_pingDomain($domain){
$starttime = microtime(true);
$file = #fsockopen($domain, 80, $errno, $errstr, 10);
$stoptime = microtime(true);
$status = 0;
if (!$file) {
$status = -1; // Site is down
} else {
fclose($file);
$status = ($stoptime - $starttime) * 1000;
$status = floor($status);
}
return $status;
}
If you really want to know if the FTP server is working or not, your best option is to actually send FTP commands through to it.
An FTP server, upon connect, should typically reply with the first three bytes "220" or "120". 220 is a "greeting". You can read more in RFC 959.
To be completely sure, you might be better off using ftp:// handling in PHP, e.g. actually authenticating a user (maybe user authentication is broken, but it's still able to send a greeting - does that count is "down"?)
Anyway, if you want better than "was I able to connect on that port?" or "did the connect succeed in a timely fashion?", you have to delve into actual communication over the socket. Ultimately, this means you have to do something special for each type of service (for some, read bytes, for others write bytes, etc.)
I have a client-server application, in which the server may require to send information back to clients.
As the client-server pattern does not allow the server to "request" the client, there are 2 solutions:
The client pull the server every few time (which is a bad solution)
The client maintain an open socket with the server, that allow the server to send new information back when required.
Currently, the client (Web app with JavaScript and Html/Css) open a streaming connection to the server (A C++ server) which may send information back to the client.
I would like to implement a PHP version of this feature to allow low-cost hosting to work with my program (low-cost hosting usually does not provide access to install/run binaries).
The idea is that the client make a request that establish the streaming socket, it save the socket and then, an other request may retrieve this socket and send new information through it.
So, my question is:
How to save an http socket in PHP, so a further request may retrieve it?
How to finish the PHP script without closing the socket?
How to save socket information?
How to retrieve the socket from a new thread/request?
I do not know even if that is possible, I read about pfsockopen, but it seem a bit different to what I need ( I may be wrong ).
So, you need two connections for each client, one persist for get data from server, and other to send data to.
Something like:
in persist.php:
$socket = stream_socket_server('unix:///tmp/unique.sock', $errno, $errstr);
if (!$socket) {
echo "$errstr ($errno)<br />\n";
} else {
while ($conn = stream_socket_accept($socket)) {
$buffer = "";
// Read until double CRLF
while( !preg_match('/\r?\n\r?\n/', $buffer) )
$buffer .= fread($client, 2046);
//Operate with our listener
echo $buffer;
flush();
// Respond to socket client
fwrite($conn, "200 OK HTTP/1.1\r\n\r\n");
fclose($conn);
}
fclose($socket);
}
in senddata.php:
$sock = stream_socket_client('unix:///tmp/unique.sock', $errno, $errstr);
fwrite($sock, $data);
fflush($sock);
fclose($sock);
One way to solve it - forget about sockets.
Pseudocode:
// receive request, set some session_id if not exists
// request contains last_timestamp, so we know which data client already have
// check have we any dataset for this session_id after last_timestamp
// return this dataset, or no_new_data signature
Data can be stored in database, for example.
Good Day,
I have a hardware device (an RN-XV WiFi chip) which has successfully connected to my server IP address through port 80. I am able to send junk data and it responds with a "server is unable to serve this request", meaning there is a connection.
Now, I need to talk to this device/send it data/strings. I know some basic PHP, but I have no idea how to approach this problem. My device is connected to the server but:
To send data to it, I have to know the IP/Port of the device connected right? How do I find that out?
If I am able to obtain this..is sending data a matter of opening a TCP connection via PHP and sending a string?
Now that I am connected to the server, I am somehow able to send strings, but it returns with a server unable to serve this request. How do I actually send data to a particular PHP file to read?
Please Help!
Thanks in advance!
you must write program for socket .see this page for php socket programming http://php.net/manual/en/book.sockets.php
with this function you can connect to every port , send data and get response with every format that you want .
sample:for connect to Device
<?php
$fp = fsockopen("udp://127.0.0.1", 2000, $errno, $errstr);
if (!$fp) {
echo "ERROR: $errno - $errstr<br />\n";
} else {
fwrite($fp, "data for send");
while ( !feof( $fp ) ) {
$ret .= fgets( $fp, 4096 );
}
echo $ret;
fclose($fp);
}
?>
more sample http://php.net/manual/en/function.fsockopen.php
I have a situation where I need to update one browser window based on input from the other. Right now I'm using WebSockets and it's working great.
Now I want to send data to the WebSocket using PHP instead of the browser (so instead of ws://, use PHP code). In other words, I want to simulate the WebSocket.send() call using PHP instead of JavaScript.
I have the following code which doesn't seem to work (the onmessage is not being called):
if (
function_exists('socket_create') AND
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP) AND
$sock_data = socket_connect($sock, "127.0.0.1", 12345)
) {
$msg = "hello world";
$sock_data = socket_set_option($sock, SOL_SOCKET, SO_BROADCAST, 1); //Set
$sock_data = socket_write($sock, $msg, strlen($msg)); //Send data
socket_close($sock); //Close socket
}
Here's how it's done:
http://permalink.gmane.org/gmane.comp.lang.javascript.nodejs/18088
$host = 'localhost'; //where is the websocket server
$port = 9000;
$local = "http://localhost/"; //url where this script run
$data = 'hello world!'; //data to be send
$head = "GET / HTTP/1.1"."\r\n".
"Upgrade: WebSocket"."\r\n".
"Connection: Upgrade"."\r\n".
"Origin: $local"."\r\n".
"Host: $host"."\r\n".
"Content-Length: ".strlen($data)."\r\n"."\r\n";
//WebSocket handshake
$sock = fsockopen($host, $port, $errno, $errstr, 2);
fwrite($sock, $head ) or die('error:'.$errno.':'.$errstr);
$headers = fread($sock, 2000);
fwrite($sock, "\x00$data\xff" ) or die('error:'.$errno.':'.$errstr);
$wsdata = fread($sock, 2000); //receives the data included in the websocket package "\x00DATA\xff"
fclose($sock);
In order to send data to the socket, you need to use fsockopen to open the connection to the socket at specified port. If the connection is successfully, all you need to do is use fwrite
However, you are going to be sending the data to the WebSocket server. The server will treat you as a client, and since you are not providing HTTP headers it expects for successful authentication - your connection will be refused.
Since you didn't say who is supposed to receive the message you are trying to send (all users or a specific user or something entirely different), without knowing what your goal is - it's hard to explain any further what you should do.
There is a lot more to WebSockets than just sending the raw data to a TCP socket.
Ok, to start, you're using a UDP socket, where WebSockets use TCP. WebSockets is an entire protocol for communication, similar to HTTP, so you need to follow that protocol, there is a handshake step that you need to perform first and headers you need to add to all communication. It's not difficult, but I'm not going to go into detail here.
You have two options from here, implement the WebSockets protocol in php, or use a pre-built library like this one: http://code.google.com/p/phpwebsocket/
I'm not being rude, or mean, but in the future, try a quick Google search. That library I linked was found after googling "PHP WebSockets".
The most important part is that the message needs to be sent on the existing socket, meaning you cant call socket_connect, fsockopen, or any other function within PHP that will attempt an unsolicited connection to the client. This isn't a websocket thing - that's a fundamental concept in network programing.
On phpwebsocket it would be somethin like:
$msg = "hello world";
$phpwebsocket->send($user->socket, $msg);
where '$phpwebsocket' is the PHP WebSocket object, $user->socket is a connected user who connected priory using with a javascript WebSocket(), and send() is a method within the WebSocket object that will properly encode the message into a frame (or should as it will soon be required).
However, if for any reason you want to connect to the websocket server using websockets from PHP, you'll want to check out https://github.com/nicokaiser/php-websocket. The server in the link wont be of any importance if your happy with your current solution, but the package also contains a PHP Websocket client class which is what you would need.
Checkout ratchet
You can use something like telnet with popen/proc_open to communicate with the socket server.