Cannot receive data from socket using PHP - php

I'm new to php and I need to receive data from a socket in order to parse the song title from a given IP. In order to learn and test sockets I first tried to connect and receive data from the given IP.
Here's my code:
#!/usr/bin/php -q
<?php
//$sock = fsockopen('205.164.35.5:80');
$sock = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
$result = socket_connect($sock, "205.164.35.5", 80);
$request = "GET / HTTP/1.1\r\n";
$request .= "Icy-MetaData: 1\r\n";
socket_write($sock,$request,strlen($request));
echo "OK";
$out = " ";
while($out = socket_read($sock,2048)){
echo $out;
}
socket_close($sock);
?>
When I run it from the terminal it does not generate any errors, however it displays nothing. I tried to connect to that ip with "telnet" command and sent the same request and on the terminal I had a response. Any kind of help would be really appreciated.
Thank you...

You should terminate the request with two CRLFs:
- $request .= "Icy-MetaData: 1\r\n";
+ $request .= "Icy-MetaData: 1\r\n\r\n";
Hope it helps.

Related

Is there a way to listen for new socket connections while doing a do, while loop in PHP?

I am trying to make a simple PHP, javascript websocket test project and I ran into the issue where PHP would not continue the while(true) loop once I call the socket accept function. It waits for an actual connection before continuing the loop. Is there a way to call this asynchronously so the while loop can continue? Or is there a way to immediately accept more incoming connections after one is accepted?
Here is my code
<?php
error_reporting(E_ALL);
/* Allow the script to hang around waiting for connections.
set_time_limit(0);
/* Turn on implicit output flushing so we see what we're getting
as it comes in.
ob_implicit_flush();*/
$address = 'localhost';
$port = 8080;
$clients = [];
$server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($server, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind($server, $address, $port);
socket_listen($server);
/*$client = acceptConn($server);
$clients[0] = $client;*/
// Send WebSocket handshake headers.
$newclient = socket_accept($server);
handshake($server, $newclient);
$clients[count($clients)] = $newclient;
function handshake($server, $client){
$request = socket_read($client, 5000);
preg_match('#Sec-WebSocket-Key: (.*)\r\n#', $request, $matches);
$key = base64_encode(pack(
'H*',
sha1($matches[1] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')
));
$headers = "HTTP/1.1 101 Switching Protocols\r\n";
$headers .= "Upgrade: websocket\r\n";
$headers .= "Connection: Upgrade\r\n";
$headers .= "Sec-WebSocket-Version: 13\r\n";
$headers .= "Sec-WebSocket-Accept: $key\r\n\r\n";
socket_write($client, $headers, strlen($headers));
}
// Send messages into WebSocket in a loop.
do {
sleep(1);
//echo "next";
$content = 'Now: ' . time();
$response = chr(129) . chr(strlen($content)) . $content;
foreach($clients as $key => $item){
if(socket_write($item, $response) != 17){
socket_close($item);
unset($clients[$key]);
continue;
//echo json_encode($clients);
}
continue;
}
/*echo count($clients);
$newclient = socket_accept($server);
echo gettype($newclient);
$clients[count($clients)] = $client;*/
}while (true);
?>
I found the solution.
To anyone who was wondering what it was, use:
socket_set_nonblock($socketservervariable);
to make the server not wait for a client to connect before proceeding. That creates a new error though. When doing the client handshake the socket_read wanted a socket but it got the boolean value of false when the socket_accept function didn't detect a client connecting. So this was my solution to that:
$newclient = socket_accept($server);
if($newclient != false){
handshake($server, $newclient);
$clients[count($clients)] = $newclient;
echo "\n\nNew client connected!\n\n";
}
and that solved all of my problems.

webpage not printing winsock information

I am trying to send data from a winsock application to a PHP script. I have already tried various header types without any success and I can't seem to find enough information.
Data is sent, but the PHP script is not printing any results, so I think the error is headers types.
C Winsock code
int main()
{
SOCKADDR_IN sock;
SOCKET s;
WSADATA wsa;
int lengthofrequest = 0;
char httprequest[180] =
"POST /test.php?name=alex&password=secret HTTP/1.1\r\n"
"Host: 127.0.0.1\r\n"
"Pragma: no-cache\r\n"
"Content-type: text/html\r\n"
"Connection: close\r\n"
"Content-Length: 25\r\n"
"\r\n";
lengthofrequest = strlen(httprequest);
// init winsock
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
return WSASYSNOTREADY;
sock.sin_addr.s_addr = inet_addr("127.0.0.1");
sock.sin_family = AF_INET;
sock.sin_port = htons(80);
// create socket
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET)
return 1;
// connect to the http panel
int conn = connect(s, (SOCKADDR*)&sock, sizeof(sock));
if (conn < 0)
return 1;
// send http header
send(s, httprequest, lengthofrequest, 0);
// close socket
closesocket(s);
WSACleanup();
return 0;
}
PHP script
<?php
if(isset($_POST['name'], $_POST['password']))
{
echo $_POST['name'];
echo $_POST['password'];
}
?>
I would appreciate any help or guidance. Thanks.
You are mixing post and get
Use $_GET to access your data because your data is appended to the url
Try this:
<?php
if(isset($_GET['name'], $_GET['password']))
{
echo $_GET['name'];
echo $_GET['password'];
}
this should work but you should consider changing your request type to GET in the C code as well to make your code clear and simple
What you are doin here is ambiguous:
"POST /test.php?name=alex&password=secret HTTP/1.1\r\n"
Because you are sending get parameters using post and the post body is actually empty.
Also you should omit ?> at the end of your php script.

Google Sitemap Ping Success [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 11 months ago.
Improve this question
I have a php script that creates an xml sitemap. At the end, I use
shell_exec('ping -c1 www.google.com/webmasters/tools/ping?sitemap=sitemapurl');
to submit the updated sitemap to Google Webmaster tools.
Having read the Google documentation, I'm unsure whether I need to do this each time or not. Entering the link in the code manually, results in a success page from google, but using the ping command I receive no confirmation. I would also like to know if there is any way of checking if the command has actually worked.
Here is a script to automatically submit your site map to google, bing/msn and ask:
/*
* Sitemap Submitter
* Use this script to submit your site maps automatically to Google, Bing.MSN and Ask
* Trigger this script on a schedule of your choosing or after your site map gets updated.
*/
//Set this to be your site map URL
$sitemapUrl = "http://www.example.com/sitemap.xml";
// cUrl handler to ping the Sitemap submission URLs for Search Engines…
function myCurl($url){
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return $httpCode;
}
//Google
$url = "http://www.google.com/webmasters/sitemaps/ping?sitemap=".$sitemapUrl;
$returnCode = myCurl($url);
echo "<p>Google Sitemaps has been pinged (return code: $returnCode).</p>";
//Bing / MSN
$url = " https://www.bing.com/webmaster/ping.aspx?siteMap=".$sitemapUrl;
$returnCode = myCurl($url);
echo "<p>Bing / MSN Sitemaps has been pinged (return code: $returnCode).</p>";
//ASK
$url = "http://submissions.ask.com/ping?sitemap=".$sitemapUrl;
$returnCode = myCurl($url);
echo "<p>ASK.com Sitemaps has been pinged (return code: $returnCode).</p>";
you can also send yourself an email if the submission fails:
function return_code_check($pingedURL, $returnedCode) {
$to = "webmaster#yoursite.com";
$subject = "Sitemap ping fail: ".$pingedURL;
$message = "Error code ".$returnedCode.". Go check it out!";
$headers = "From: hello#yoursite.com";
if($returnedCode != "200") {
mail($to, $subject, $message, $headers);
}
}
Hope that helps
Since commands like shell_exec(), exec(), passthru() etc. are blocked by many hosters, you should use curl and check for a response code of 200.
You could also use fsockopen if curl is not available. I'm going to check for the code snippet and update the answer when I found it.
UPDATE:
Found it. I knew I used it somewhere. The funny coincedence: It was in my Sitemap class xD
You can find it here on github: https://github.com/func0der/Sitemap. It is in the Sitemap\SitemapOrg class.
There is a also an example for the curl call implemented.
Either way, here is the code for stand alone implementation.
/**
* Call url with fsockopen and return the response status.
*
* #param string $url
* The url to call.
*
* #return mixed(boolean|int)
* The http status code of the response. FALSE if something went wrong.
*/
function _callWithFSockOpen($url) {
$result = FALSE;
// Parse url.
$url = parse_url($url);
// Append query to path.
$url['path'] .= '?'.$url['query'];
// Setup fsockopen.
$port = 80;
$timeout = 10;
$fso = fsockopen($url['host'], $port, $errno, $errstr, $timeout);
// Proceed if connection was successfully opened.
if ($fso) {
// Create headers.
$headers = 'GET ' . $url['path'] . 'HTTP/1.0' . "\r\n";
$headers .= 'Host: ' . $url['host'] . "\r\n";
$headers .= 'Connection: closed' . "\r\n";
$headers .= "\r\n";
// Write headers to socket.
fwrite($fso, $headers);
// Set timeout for stream read/write.
stream_set_timeout($fso, $timeout);
// Use a loop in case something unexpected happens.
// I do not know what, but that why it is unexpected.
while (!feof($fso)){
// 128 bytes is getting the header with the http response code in it.
$buffer = fread($fso, 128);
// Filter only the http status line (first line) and break loop on success.
if(!empty($buffer) && ($buffer = substr($buffer, 0, strpos($buffer, "\r\n")))){
break;
}
}
// Match status.
preg_match('/^HTTP.+\s(\d{3})/', $buffer, $match);
// Extract status.
list(, $status) = $match;
$result = $status;
}
else {
// #XXX: Throw exception here??
}
return (int) $result;
}
If you guys find any harm or improvement in this code, do not hesitate to open up a ticket/pull request on GitHub, please. ;)
Simplest solution: file_get_contents("https://www.google.com/webmasters/tools/ping?sitemap={$sitemap}");
That will work on every major hosting provider. If you want optional error reporting, here's a start:
$data = file_get_contents("https://www.google.com/webmasters/tools/ping?sitemap={$sitemap}");
$status = ( strpos($data,"Sitemap Notification Received") !== false ) ? "OK" : "ERROR";
echo "Submitting Google Sitemap: {$status}\n";
As for how often you should do it, as long as your site can handle the extra traffic from Google's bots without slowing down, you should do this every time a change has been made.

Connecting by php to a python websocket server

I have a working websocket Server (python + Tornado) which accepts Connections on port 8973. I can connect by a easy JavaScript / jquery instruction like:
ws = new WebSocket("ws://192.168.41.170:8973/rt");
But I need my php script to connect to this websocket server and send a message. I tried all most available solutions like
https://github.com/lemmingzshadow/php-websocket/
$host = '192.168.41.170'; //where is the websocket server
$port = 8973;
$local = "http://192.168.41.2/"; //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);
But this all dont work. Has anybody a working code snippet? I dont need a php-websocket server! Thanks
I think your problem is in how you are packing the data. Without knowing which protocol you are trying to use, I can't tell you how to pack it! But, there is a working code snippet in one answer to this question.

How do you get the HTTP status code for a remote domain in php?

I would like to create a batch script, to go through 20,000 links in a DB, and weed out all the 404s and such. How would I get the HTTP status code for a remote url?
Preferably not using curl, since I dont have it installed.
CURL would be perfect but since you don't have it, you'll have to get down and dirty with sockets. The technique is:
Open a socket to the server.
Send an HTTP HEAD request.
Parse the response.
Here is a quick example:
<?php
$url = parse_url('http://www.example.com/index.html');
$host = $url['host'];
$port = $url['port'];
$path = $url['path'];
$query = $url['query'];
if(!$port)
$port = 80;
$request = "HEAD $path?$query HTTP/1.1\r\n"
."Host: $host\r\n"
."Connection: close\r\n"
."\r\n";
$address = gethostbyname($host);
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, $address, $port);
socket_write($socket, $request, strlen($request));
$response = split(' ', socket_read($socket, 1024));
print "<p>Response: ". $response[1] ."</p>\r\n";
socket_close($socket);
?>
UPDATE: I've added a few lines to parse the URL
If im not mistaken none of the php built-in functions return the http status of a remote url, so the best option would be to use sockets to open a connection to the server, send a request and parse the response status:
pseudo code:
parse url => $host, $port, $path
$http_request = "GET $path HTTP/1.0\nHhost: $host\n\n";
$fp = fsockopen($host, $port, $errno, $errstr, $timeout), check for any errors
fwrite($fp, $request)
while (!feof($fp)) {
$headers .= fgets($fp, 4096);
$status = <parse $headers >
if (<status read>)
break;
}
fclose($fp)
Another option is to use an already build http client class in php that can return the headers without fetching the full page content, there should be a few open source classes available on the net...
This page looks like it has a pretty good setup to download a page using either curl or fsockopen, and can get the HTTP headers using either method (which is what you want, really).
After using that method, you'd want to check $output['info']['http_code'] to get the data you want.
Hope that helps.
You can use PEAR's HTTP::head function.
http://pear.php.net/manual/en/package.http.http.head.php

Categories