PHP function fsockopen never returning false - php

Could somebody help me with the php function fsockopen?
if I call the function like this :
$fp = fsockopen('xywqnda.com', 80, $errno, $errstr, 10);
With an unavailable host domain, it will never return false and I don't understand why!

Ah, you are using UDP. Your original example didn't show this. This changes things. From the PHP manual:
Warning
UDP sockets will sometimes appear to have opened without an error, even if the remote host is unreachable. The error will only
become apparent when you read or write data to/from the socket. The
reason for this is because UDP is a "connectionless" protocol, which
means that the operating system does not try to establish a link for
the socket until it actually needs to send or receive data.

try this
ini_set("display_errors","on")
it will show up a warning if the domain is invalid, other than that the function will return TRUE because the file pointer is returned, meaning file was created with success, FALSE will be returned only if it can't create the file.

// displays all warnings, notices and errors
ini_set('display_errors', 1);
error_reporting(E_ALL);
$fp = fsockopen('xywqnda.com', 80, $errno, $errstr, 10);
The connection attempt will timeout after 10 seconds.
You will get a warning because the domain is unavailable.
$errno and $errstr will contain the system error number and error message.
The function will return false, so $fp will be equal to false.
Documentation: fsockopen

Related

PHP Checking if a port is Active

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.)

How to find error code/reason when stream_socket_accept() fails

I have a stream socket server written in PHP.
To see how many connections it can handle at a time,I wrote a simulator in C to create 1000 different clients to connect to the server.
stream_socket_accept was returning false a few times.
I need to find out the reason for this failure.
I tried socket_last_error() and socket_strerror() to get the error codes, but they returned 'Success'. These functions don't seem to be working on stream-sockets. Is there any way/ method to find out the actual error codes
My code:
$socket = #stream_socket_accept($this->master, "-1", $clientIp);
$ip = str_getcsv($clientIp, ":");
//socket accept error
if($socket === FALSE)
{
$this->logservice->log($this->module_name, "ERROR", "cannot accept the device connection");
***// Need to find error code here ***
}
I am able to see PHP level error messages in my logs now. # operator before stream_socket_accept was suppressing the error messages. (# symbol in php )

how to check if a mail server exists or not?

my PHP page currently doesnot have a mail server, instead of throwing an error, is it possible to catch this error and print it out to the user?
this is what I have so far, it just gives an error.
<?php
$foo = mail('test#test.com', 'subject', 'message');
if ( $foo == false )
{
echo "no mail server";
}
?>
thanks!
You could open a port to the mail server in question using fsockopen('servername/ipaddres', 25); If it returns content, it means the port is open and that you could ASSUME that there is a mail server.
$errno = 0;
$errstr = '';
$fp = fsockopen("localhost", 25, $errno, $errstr, 5);
if (!$fp) {
echo "No mail server responded on this server on port 25, validate your configuration";
}
This is by all means very experimental, you need to involve yourself in more work but it should get you started :)
mail() could fail for other reasons than just a non-existant mail server. I think the best you can do is fail gracefully and show the user the message you got, and even that has limitations.
In PHP 5.1 and above, you could catch the error in the following way:
error_reporting(0); // Don't display errors
$success = mail(....);
if (!$success)
{
echo "Mailing failed: Error message: ".error_get_last();
}
if you need to support older versions than that, I think you'll have no option than showing the raw error message from mail() - you could theoretically suppress it, but that will not show the user what exactly went wrong.

socket connection issue+php

I am using PHP socket programming and able to write data to open socket but i have to wait for a long time(or stuck it)for the response or some time getting error like "Maximum execution time of 30 seconds exceeded line number where this code is placed fgets($fp, 128), i have check the server it seems it has sent the response as expected but i am not getting why i m unable to get response.following the code using for socket connection and reading data.
functon scoket_connection() {
$fp = fsockopen(CLIENT_HOST,CLIENT_PORT, $errno, $errstr);
fwrite($fp,$packet);
$msg = fgets($fp, 128);
fclose($fp)
return $msg;
}
any idea???
Is by any chance your client on a different platform than the server? When I say different I mean Windows/Linux/Mac. These each have different line endings. fgets() is supposed to read a line which means it expects to find a certain line ending before it returns anything. If one system is sending for example \n and the other expects \r\n it could cause this problem.

Detecting early failure in php fwrite

Earlier today I noticed some calls to php fwrite failing as the destination socket was in a mixed state. There were numerous connections stuck in SYN_SENT and were seemingly not coming back as failures.
What is the best way to detect this and simply time out the connection if x bits haven't bit transmitted over the wire?
I believe you are looking for stream_set_timeout. An example:
stream_set_timeout($fp, 2);
fwrite($fp, "GET / HTTP/1.0\r\n\r\n");
You can check whether a time-out happens by checking the meta data of the stream:
$info = stream_get_meta_data($fp);
// $info['timed_out'] == true : time-out has happened

Categories