ping a server thru a specific port (fsockopen) in php - php

function checkServer($domain, $port=80)
{
global $checkTimeout, $testServer;
$status = 0;
$starttime = microtime(true);
$file = #fsockopen ($domain, $port, $errno, $errstr, $checkTimeout);
$stoptime = microtime(true);
if($file)
{
fclose($file);
$status = ($stoptime - $starttime) * 1000;
$status = floor($status);
}
else
{
$testfile = #fsockopen ($testServer, 80, $errno, $errstr, $checkTimeout);
if($testfile)
{
fclose($testfile);
$status = -1;
}
else
{
$status = -2;
}
}
return $status;
}
the testserver is google.sk, and checkTimeout is 10 seconds. This actually works, but when i try to run it in a loop for about 50 times, and do other stuff (mysql queries and things like that), it's not slow, but it causes 100% load of my CPU until the script ends. It's a single apache proccess that drives my cpu crazy ... So i wanted to ask you if you have any ideas about it. maybe some tip how to do the same in python or bash or so will be appreciated.
Thank you for the responses :)

Use CURL
this is an example how to conversion fsockopen to CURL
PHP fsockopen to curl conversion
Good luck

Related

How to use fsockopen to check internet on/off and not stop for error?

I am simply trying to see if I have internet or not but fsockopen always returns an error when internet is down that stops my script.
I am using the following code in a function
$starttime = microtime(true);
$file = #fsockopen ($domain, 80);
$stoptime = microtime(true);
$status = 0;
if (is_resource($file)) {
fclose($file);
$status = ($stoptime - $starttime) * 1000;
$status = floor($status);
} else {
$status = -1; // site is down
}
return $status;
...called in a script that reload the page every 10 sec and save the status with a timestamp in a file.
I tried $domain = #"ip address".
How can I avoid fsockopen to stops for error and be able to test it instead?

stream_select timeout on newly opened socket

I use thrift php client to connect to java thrift server. But got the error of
TSocket: timed out writing 78 bytes from 10.0.1.151:1234
I dig into the php source of thrift and find it was caused from timeout on function stream_select.
/**
* Write to the socket.
*
* #param string $buf The data to write
*/
public function write($buf)
{
$null = null;
$write = array($this->handle_);
// keep writing until all the data has been written
while (TStringFuncFactory::create()->strlen($buf) > 0) {
// wait for stream to become available for writing
$writable = #stream_select($null, $write, $null, $this->sendTimeoutSec_, $this->sendTimeoutUsec_);
if ($writable > 0) {
// write buffer to stream
$written = #stream_socket_sendto($this->handle_, $buf);
if ($written === -1 || $written === false) {
throw new TTransportException('TSocket: Could not write '.TStringFuncFactory::create()->strlen($buf).' bytes '.
$this->host_.':'.$this->port_);
}
// determine how much of the buffer is left to write
$buf = TStringFuncFactory::create()->substr($buf, $written);
} elseif ($writable === 0) {
throw new TTransportException('TSocket: timed out writing '.TStringFuncFactory::create()->strlen($buf).' bytes from '.
$this->host_.':'.$this->port_);
} else {
throw new TTransportException('TSocket: Could not write '.TStringFuncFactory::create()->strlen($buf).' bytes '.
$this->host_.':'.$this->port_);
}
}
}
That means the socket was blocked and was not able to write. But the socket is just open and should not be blocked. I try select immediately after pfsockopen
if ($this->persist_) {
$this->handle_ = #pfsockopen($this->host_,
$this->port_,
$errno,
$errstr,
$this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000));
} else {
$this->handle_ = #fsockopen($this->host_,
$this->port_,
$errno,
$errstr,
$this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000));
}
// Connect failed?
if ($this->handle_ === FALSE) {
$error = 'TSocket: Could not connect to '.$this->host_.':'.$this->port_.' ('.$errstr.' ['.$errno.'])';
if ($this->debug_) {
call_user_func($this->debugHandler_, $error);
}
throw new TException($error);
}
$write = array($this->handle_);
$writable = #stream_select($null, $write, $null, $this->sendTimeoutSec_, $this->sendTimeoutUsec_);
if ($writable === 0) {
die('123');
}
The result show that it is block right after it is opened!
When restart php-fpm, the error disappear for a while and come up again.
Here is the client code:
$socket = new TSocket('10.0.1.151', 1234, true);
$framedSocket = new TFramedTransport($socket);
$transport = $framedSocket;
$protocol = new TCompactProtocol($transport);
$transport->open();
$client= new userservice\UserServiceProxyClient($protocol);
$result = $client->findUser($id);
If I adjust the php-fpm configuration pm.max_children from 200 to 2, the error also disappear.
I tried increase timeout to 10 seconds and it timeout after 10 seconds.
Any idea for what's the cause of the problem and how to fix it?
I modify the php thrift lib. Change from
$writable = #stream_select($null, $write, $null, $this->sendTimeoutSec_, $this->sendTimeoutUsec_);
to
$writable = 1;
And the same for read.
The problem get fixed.
That means the connection is established ( I even use tcpdump to confirm the tcp connection is established) and writable, but select timeout. Strange things!

Query DHT Server

I'm trying to make a simple query to a DHT server.
I'm trying to make a simple simple example to test queries to the servers, but I don't get a response from the server in any form...
Little example:
$socket = fsockopen("udp://router.bittorrent.com", 6881, $errno, $errstr, 3);
fwrite($socket, 'p'); $Head = fread($socket, 4);
$CheckStatus = socket_get_status($socket);
if($CheckStatus["unread_bytes"] == 0)
{
return 0;
}
$do = 1;
while($do)
{
$str = fread($socket,1);
$stats .= $str;
$status = socket_get_status($socket);
if($status["unread_bytes"] == 0)
{
$do = 0;
}
}
fclose($socket);
The info about the queries in DHT server is here: http://www.bittorrent.org/beps/bep_0005.html#dht-queries
But I don't understand how make this with PHP.
Is this possible? What's the problem with my code?
As the8472 mentions, your client is sending p, which is not a valid query. To see valid query formats, look here: bep 005

PHP - Restricting socket connection period

I'm fetching data from a socket that pumps data at unknown intervals. There could be nothing for minutes (or even hours) and then tens of thousands of rows can be queued ready for reading.
Because I don't know what to expect, I was hoping to build something that connects for 2-5 seconds slurping in however much it can, irrespective of how much is queued up at the server end.
This is what I have at the moment.
<?php
set_time_limit(2);
ini_set('max_input_time', 2);
$timeout = 3;
$host = 'data.host.com';
$port = 6543;
$fp = fsockopen($host, $port, $errno, $errstr, $timeout);
stream_set_timeout($fp, 2);
if( !$fp ){
echo "Connection to '$host' failed.\n$errstr ($errno)\n";
exit;
}
while( !feof($fp) ){
$xml = trim(fgets($fp));
if(empty($xml)) continue;
echo "XML=$xml\n";
}
echo "DONE\n";
function shutdown(){
echo "SHUTDOWN!\n";
}
register_shutdown_function('shutdown');
However this never finishes at all. The while loop appears to be as infinite as one might expect (out of context). How do I put in and capture some exit/break/kill?
This may not be the best/correct way to do it, but it should work (untested)
$startTime = time();
$executionTime = 180; //180 Seconds - 2 Minutes
while( !feof($fp) ){
if ((time() - $startTime) > $executionTime) {
//If time has been longer than the execution time, break
//out of loop
break;
}
$xml = trim(fgets($fp));
if(empty($xml)) continue;
echo "XML=$xml\n";
}
I believe this is a mysql connection, if so use the default port. Restricting the socket connection is not advisable unless you can store all transaction in a temp db and push else where at the time alloted.
$start_time = time();
while( !feof($fp) ){
$xml = trim(fgets($fp));
if(empty($xml)) continue;
echo "XML=$xml\n";
if ( time() - $star_time > 320 ) break;
}

PHP: Want fsockopen to retrieve portion only of remote xml file

I need to retrieve a small amount of data from a very large remote XML file that I access via http. I only need a portion of the file at the beginning, but the files I am accessing can often be so large that downloading them all will cause a timeout. It seems like it should be possible with fsockopen to pull only as much as needed before closing the connection, but nothing I have tried has worked.
Below is a simplified version of what I have been trying. Can anyone tell me what I need to do differently?
<?php
$k = 0;
function socketopen($funcsite, $funcheader){
$fp = fsockopen ($funcsite, 80, $errno, $errstr, 5);
$buffer = NULL;
if ($fp) {
fwrite($fp, "GET " . $funcheader . " HTTP/1.0\r\nHost: " . $funcsite. "\r\n\r\n");
while (!feof($fp)) {
$buffer = fgets($fp, 4096);
echo $buffer;
if($k == 200){
break;
}
$k++;
}
fclose ($fp);
} else {
print "No Response:";
}
return ( html_entity_decode($buffer));
}
$site = "www.remotesite.com";
$header = "/bigdatafile.xml";
$data = socketopen($site, $header);
?>
This works fine, but always opens and downloads the entire remote file. (I actually use a different conditional than the if($k = x), but that shouldn't matter).
Any help greatly appreciated. -Jim
Any reason not to use file_get_contents() instead?
$buffer = html_entity_decode(file_get_contents('http://www.remotesite.com/bigdatafile.xml', 0, null, $offsetBytes, $maxlenBytes));
You just need to specify $offsetBytes and $maxlenBytes.
Try this:
set_time_limit(0);
echo $buffer = html_entity_decode(file_get_contents('http://www.remotesite.com/bigdatafile.xml', 0, null, 1024, 4096));
with this code you could download the entire rss
if (!$xml = simplexml_load_file("http://remotesite.com/bigrss.rss))
{
throw new RuntimeException('Unable to load or parse feed');
}
else
{
file_put_contents($xml,'mybigrss.rss');
}
but if you want to get just some parts then do the following;
$limit = 512000; // set here a limit
$sourceData = fread($s_handle,$limit);
// your code ect..
Or with eof
$source='';
while (!feof($s_handle))
$source.=fread($s_handle,1024); // set limit

Categories