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

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 )

Related

php mail error handling when no smtp server

I make a php page to send email. I will give this page to multiple users, but I have no control of the server they will use. And some of them should have no SMTP server. So I try to handle this error.
For example, on my own computer, if I deactivate my SMTP server, I receive a "PHP Warning: mail(): Failed to connect to mailserver at ..." error message.
My code :
try
{
$okmail=mail($to,$Subject,$texte,$headers);
}
catch (Exception $ex)
{
...
}
But this code doesn't throw an exception, it only write the error message (like an "echo(...)" statement).
I use this code in a xmlhttprequest page and use an xml type response. But the original page receive the error message before the xml text :
PHP Warning: mail(): Failed to connect to mailserver at ... \n1Email not send
How can I handle this "no SMTP" error ?
Thanks!
If I understand the problem correctly, the following directive will hide the warnings.
ini_set('display_errors', 0);
Instead of "try/catch" you can use the following approach.
set_error_handler("warningHandler", E_USER_WARNING);
// Trigger some warning here for testing purposes only (this is just an example).
trigger_error('This here is the message from some warning ...', E_USER_WARNING);
// If you need DNS Resource Records associated with a hostname.
// $result = dns_get_record($_SERVER['HTTP_HOST']);
// Restores the previous error handler function.
restore_error_handler();
// This is your custom warning handler.
function warningHandler($errno, $errstr) {
// Do what you want here ...
echo $errno, ' ::: ', $errstr;
}
Thanks for your answers, but nothing works :(
I find a solution by cleaning the output buffer by using ob_start(null,0,PHP_OUTPUT_HANDLER_CLEANABLE) and ob_clean() just after the mail() function.
I don't understand why the mail function writes an error into the output buffer

how to custom error msg with PHP if can't connect to web service (JSON)

i'm connecting to a webservice using PHP and JSON. the connection is good but i want to add 2 error messages when (1) connection to the webservice is lost and (2) if webservice returns a http 500 error.
any ideas on how to do that?? i'm new to json so not sure how to do that...
this is how i connect and get data form the webservice
$url = "http://webservice.com/{$account}?loc={$loc}";
$content = file_get_contents($url);
$json = json_decode($content, true);
For error 1:
file_get_contents will return FALSE if what it is trying to load fails.
For error 2:
Depending on what your HTTP Error 500 outputs on the page, you can simply use file_get_contents and look for a certain string indicating the error using strpos and act accordingly.
Reference: http://php.net/manual/en/function.strpos.php

PHP function fsockopen never returning false

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

PHP:Stomp - Is it possible to catch errors on "send()"?

I'm using the PHP Stomp client to send a stomp message.
I would like to leave a persistent connection open, in the background, and send messages occasionally.
However, I can't find a way to handle connection errors if they happen after opening the connection (on send()).
For example, when running:
<?php
$stomp = new Stomp('tcp://localhost:61613');
sleep(5); // Connection goes down in the meantime
$result = $stomp->send('/topic/test', 'TEST');
print "send " . ($result ? "successful\n": "failed\n");
?>
Output: send successful
Even if the connection goes down while in sleep(), send() always returns true.
The docs weren't very helpful, Stomp::error() and stomp_connect_error() also don't help much as they return false.
As a temporary solution, I'm reconnecting before every send().
Is there a better way to catch connection errors?
Found the answer in the specification of the stomp protocol itself:
Any client frame other than CONNECT MAY specify a receipt header with an arbitrary value. This will cause the server to acknowledge receipt of the frame with a RECEIPT frame which contains the value of this header as the value of the receipt-id header in the RECEIPT frame.
So setting a "receipt" header makes the request synchronous, so the connection to the server must be alive.
So the code:
$result = $stomp->send('/topic/test', 'TEST');
print "send " . ($result ? "successful\n": "failed\n");
$result = $stomp->send('/topic/test', 'TEST', array('receipt' => 'message-123'));
print "send " . ($result ? "successful\n": "failed\n");
Gives output:
send successful
send failed
It doesn't seem like the best solution for this case, but it works for me.
If anyone knows a better way I'll be happy to hear it.
Update:
Eventually I switched to Stomp-PHP (a pure PHP client) instead of the Pecl stomp client, which handles it much better.

PHP fatal error: Uncaught exception 'Exception' with message

I have a PHP script that connects to an api and posts information to their systems, but when its trying to connect it throws a fatal error:
Fatal error: Uncaught exception 'Exception' with message 'Problem with
'http://apitestserver.co.uk:9000/Service.svc/Items' in
/var/www/html/e/connect_test.php:17 Stack trace: #0
/var/www/html/e/connect_test.php(39):
do_http_request('http://apitest....', 'hello') #1 {main} thrown in
/var/www/html/e/connect_test.php on line 17
If I send it to a PHP script which just grabs the IP then it works, but if I send it to the API it doesn't. My PHP script creates XML and then forwards to the server. I was getting errors so I just created the following smaller script purely to test the connection:
function do_http_request($url, $data, $method = 'POST',
$optional_headers = 'Content-Type: application/atom+xml') {
$params = array(
'http' => array(
'method' => $method,
'content' => $data
)
);
if ($optional_headers !== null) {
$params['http']['header'] = $optional_headers;
}
$ctx = stream_context_create($params);
$fp = fopen($url, 'rb', false, $ctx);
if (!$fp) {
throw new Exception("Problem with $url");
}
$response = #stream_get_contents($fp);
if ($response === false) {
throw new Exception("Problem reading data from $url");
}
$metaData = stream_get_meta_data($fp);
fclose($fp);
if(!preg_match('~^HTTP.*([0-9]{3})~',
$metaData['wrapper_data'][0], $matches)){
throw new Exception('MALFORED RESPONSE - COULD NOT UNDERSTAND HTTP CODE');
}
if (substr($matches[1], 0, 1) != '2') {
throw new Exception('SERVER REPORTED HTTP ERROR ' . $matches[1]);
}
return $response;
}
$data = 'hello';
$paul =
do_http_request('http://apitestserver.co.uk:9000/Service.svc/Items',$data);
echo $paul;
If I change the URL to a simple script on another one of our servers which just grabs the IP of the incoming connection and returns it:
$ip=$_SERVER['REMOTE_ADDR'];
echo 'IP equals = ' . $ip;
Then it works fine with no errors.
Update -
with errors on it throws the following warning, probably because the script is not sending the correct info to the API
Warning: fopen(http://apitestserver.co.uk:9000/Service.svc/Items)
[function.fopen]: failed to open stream: HTTP request failed! HTTP/1.1
500 Data at the root level is invalid. Line 1, position 1.
Also note that I can access the api server fine using fiddler to send manually created items across, its just when this script tries to connect and send data there is an issue. I wrote another quick script which connects and prints out the default response (an rss feed of submitted items)
When I run the 'main' connector script it throws the following two errors
Warning: fopen() [function.fopen]: php_network_getaddresses:
getaddrinfo failed: Name or service not known in
/var/www/html/e/sequence.php on line 65
Warning: fopen(http://apitestserver.co.uk:9000/Service.svc/Items)
[function.fopen]: failed to open stream: Operation now in progress
in /var/www/html/e/sequence.php on line 65
I would suggest using curl instead of fopen(). curl is both more flexible, and more secure. Many servers disable allow_url_fopen, curl also fails more gracefully when there are problems on the remote server.
I just tested the URL in my browser and got a connection error.
Maybe the problem is with their server (or you have the wrong URL)?
Edit:
Looks like ther server is throwing a 500 error - maybe because the data you're posting is invalid.
You could use a packet sniffer and check the exact data you're sending to the server (or use cURL as suggested by #acrosman)
apitestserver.co.uk doesn't respond to ping and the url is inaccessable. The API-server doesn't seem to be up.
or You can change the headers:
$optional_headers = 'Content-Type: application/json')
First error message suggests problems with apitestserver - it returns error code 500, which states for "Internal server error".
Second one informs that PHP can't resolve host name into IP address - I'd look into DNS configuration and/or hosts file.
Apparently 'fopen' function does not return proper stream. There can be many possibilities when that happens, but according to PHP manual, fopen function on fail should present E_WARNING message with proper commentary. It is possible that you have errors of that class silenced - call error_reporting(E_ALL) at the beginning of your script and look for some relevant error messages.

Categories