Using UDP fsockopen to get info from file on gameserver - php

I got a file on a gameserver called "current_map.tmp".
This file contains a number depending on the current map.
What I need is to read that number.
This is what I got so far:
<?php
$server_ip = '213.239.207.85';
$server_port = 27960;
$server_timeout = 2;
$server_addr = "udp://" . $server_ip;
$fp = fsockopen($server_addr, $server_port, $errno, $errstr, $server_timeout);
socket_set_timeout ($fp, $server_timeout);
if (!$fp) {
echo "ERROR: $errno - $errstr<br />\n";
} else {
$File = "current_map.tmp";
$filesize = filesize($File);
$handle = fopen($File, "r");
$map_id = fread($handle, $filesize);
fclose($handle);
}
fclose($fp);
?>
$fp returns "Resource id #2".
So that works.
Then there is nothing.
1) How do I know wich folder I connected to with $fp?
2) How can I read the content of this file?

$fp returns "Resource id #2". So that works.
No; this doesn't actually mean anything! Since UDP sockets are connectionless, there is no such thing as a UDP "connection"; calling fsockopen() only initializes sockets to prepare to send packets.
In any case, sending and receiving UDP packets does not allow you to access files on a remote server, unless that server has implemented a protocol to allow you to do so, and you are making use of that protocol. It certainly will not allow you to use fopen() to access remote files — this code is essentially just nonsense.

Related

PHP: Read from socket or STDIN

I am learning socket programming in PHP and so I am trying a simple echo-chat server.
I wrote a server and it works. I can connect two netcats to it and when I write in the one netcat, I recive it at the other. Now, I want to implement what NC does in PHP
I want to use stream_select to see if I have data on STDIN or on the socket to either send the message from STDIN to the server or reading the incoming message from the server.
Unfortunately the example at the php manual doesn't give me any clue how to do that.
I tried to simply $line = fgets(STDIN) and socket_write($socket, $line) but it doesnt work. So I started to go down and just want stream_select to act up when the user typed the message.
$read = array(STDIN);
$write = NULL;
$exept = NULL;
while(1){
if(stream_select($read, $write, $exept, 0) > 0)
echo 'read';
}
Gives
PHP Warning: stream_select(): No stream arrays were passed in
/home/user/client.php on line 18
But when I var_dump($read) it tells me, that it is an array with a stream.
array(1) {
[0]=>
resource(1) of type (stream)
}
How do I get stream_select to work?
PS: In Python I can do something like
r,w,e = select.select([sys.stdin, sock.fd], [],[])
for input in r:
if input == sys.stdin:
#having input on stdin, we can read it now
if input == sock.fd
#there is input on socket, lets read it
I need the same in PHP
I found a solution. It seems to work, when I use:
$stdin = fopen('php://stdin', 'r');
$read = array($sock, $stdin);
$write = NULL;
$exept = NULL;
Instead of just STDIN. Despite php.net says, STDIN is already open and saves using
$stdin = fopen('php://stdin', 'r');
It seems not, if you want to pass it into stream_select.
Also, the socket to the server should be created with $sock = fsockopen($host); instead of using socket_create on the client side... gotta love this language and it's reasonability and clear manual...
Here a working example of a client that connects to an echo server using select.
<?php
$ip = '127.0.0.1';
$port = 1234;
$sock = fsockopen($ip, $port, $errno) or die(
"(EE) Couldn't connect to $ip:$port ".socket_strerror($errno)."\n");
if($sock)
$connected = TRUE;
$stdin = fopen('php://stdin', 'r'); //open STDIN for reading
while($connected){ //continuous loop monitoring the input streams
$read = array($sock, $stdin);
$write = NULL;
$exept = NULL;
if (stream_select($read, $write, $exept, 0) > 0){
//something happened on our monitors. let's see what it is
foreach ($read as $input => $fd){
if ($fd == $stdin){ //was it on STDIN?
$line = fgets($stdin); //then read the line and send it to socket
fwrite($sock, $line);
} else { //else was the socket itself, we got something from server
$line = fgets($sock); //lets read it
echo $line;
}
}
}
}

Reading data from fsockopen using fgets/fread hangs

Here is the code that I am using:
if (!($fp = fsockopen('ssl://imap.gmail.com', '993', $errno, $errstr, 15)))
echo "Could not connect to host";
$server_response = fread($fp, 256);
echo $server_response;
fwrite($fp, "C01 CAPABILITY"."\r\n");
while (!feof($fp)) {
echo fgets($fp, 256);
}
I get the first response:
OK Gimap ready for requests from xx.xx.xx.xx v3if9968808ibd.15
but then the page times out. I have searched through stream_set_blocking, stream_set_timeout, stream_select, fread, etc. but could not get it to work. I need to read all the data that the server sends and then proceed with other commands (I would be retrieving emails using imap).
Thanks
Your script is hanging in the while loop at the end. This is because you have used !feof() as the condition for the loop, and the server is not closing the connection. This means the feof() will always return false and the loop will continue forever.
This will not be problem when your write a full implementation, as you will be looking for response codes and can break out of the loop accordingly, for example:
<?php
// Open a socket
if (!($fp = fsockopen('ssl://imap.gmail.com', 993, $errno, $errstr, 15))) {
die("Could not connect to host");
}
// Set timout to 1 second
if (!stream_set_timeout($fp, 1)) die("Could not set timeout");
// Fetch first line of response and echo it
echo fgets($fp);
// Send data to server
echo "Writing data...";
fwrite($fp, "C01 CAPABILITY\r\n");
echo " Done\r\n";
// Keep fetching lines until response code is correct
while ($line = fgets($fp)) {
echo $line;
$line = preg_split('/\s+/', $line, 0, PREG_SPLIT_NO_EMPTY);
$code = $line[0];
if (strtoupper($code) == 'C01') {
break;
}
}
echo "I've finished!";
Your script should be working. In fact, it is working.
See the results below on my pc when I ran your code:
* OK Gimap ready for requests from xx.xx.xx.xx l5if4585958ebb.20
* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH
C01 OK Thats all she wrote! l5if4585958ebb.20
Since gmail doesn't disconnect you. No end of file occurs. And the page loading simply times out.
In other words: Your script will just keep waiting and waiting until gmail does disconnect, which unfortunately happens after your page load has already timed out.

Video streaming from Android device to LAMP Server

starting from this point: http://www.mattakis.com/blog/kisg/20090708/broadcasting-video-with-android-without-writing-to-the-file-system
I'm trying to create an application to save a video stream from mobile camera to a remote server.
(I found several examples in google code for android part: ipcamera-for-android, spydroid-ipcamera, etc..)
I read some answers here and around the network, but can not find the solution about how to "read" and save the stream of data on the server side.
My knowledge of java is poor, so I'd rather be able to create server-side script in PHP (using server sockets, or other stuffs). Someone can help on this part?
UPDATE
using my little knowledge of tools such as mplayer / ffmpeg mencorer I'm able to save the video stream ...for example using ipcamera-for-android and its nanohttp server using on server side:
ffmpeg-i "http://{ip of android phone}:8080/live.flv" /my/server/path/stream.flv
However, can only be used in LAN,
I need that mobile connect server and not viceversa.
UPDATE 2
Some progress.. using this script on server side
#!/usr/bin/php5
<?php
$handle = fopen("stream.3gp","w");
$socket = stream_socket_server("tcp://192.168.0.102:9000", $errno, $errstr);
if ($socket)
{
echo "start listening\n";
while ( $conn = stream_socket_accept($socket, 180))
{
echo "phone connected\n";
while ($chunk = stream_socket_recvfrom($conn, 1500))
{
fwrite($handle,$chunk);
}
}
}
fclose($handle);
fclose($socket);
?>
however, 3gp file is not yet playable..
UPDATE 3
#!/usr/bin/php5
<?php
$socket = stream_socket_server("tcp://192.168.0.102:9000", $errno, $errstr);
$file = "saved.3gp";
$threegp_header = "\x00\x00\x00\x18\x66\x74\x79\x70\x33\x67\x70\x34\x00\x00\x03\x00\x33\x67\x70\x34\x33\x67\x70\x36";
$four_bytes = "\x00\x00\x00\x00";
if (!$socket) {
echo "$errstr ($errno)\n";
} else {
echo "server start listening\n";
while ( $conn = #stream_socket_accept($socket, 180))
{
echo "phone connected\n";
$handle = fopen($file,"w");
//mediaRecorder gives invalid stream header, so I replace it discarding first 32 byte, replacing with 28 good byte (standard 3gp header plus 4 empty bytes)
$discard = stream_get_contents($conn, 32);
fwrite($handle, $threegp_header);
fwrite($handle, $four_bytes);
//then confinue to write stream on file until phone stop streaming
while(!feof($conn))
{
fwrite($handle, stream_get_contents($conn, 1500));
}
echo "phone disconnected\n";
fclose($handle);
//then i had to update 3gp header (bytes 25 to 28) with the offset where moov atom starts
$handle = fopen($file,"c");
$output = shell_exec('grep -aobE "moov" '.$file);
$moov_pos = preg_replace('/moov:(\d+)/i', '\\1', $output);
$moov_pos_ex = strtoupper(str_pad(dechex($moov_pos - 24), 8, "0", STR_PAD_LEFT));
fwrite($handle, $threegp_header);
$tmp = '';
foreach(str_split($moov_pos_ex,2) as $hex)
{
$tmp .= pack('C*', hexdec($hex));
}
fwrite($handle, $tmp);
fclose($handle);
}
echo "phone disconnected\n";
}
#fclose($handle);
fclose($socket);
?>
after some experiments, this time vlc/mplayer seems that can play it.. still some problems with audio (but i think i've something wrong on android side)
You're probably going to want to use PHP's server socket functionality.
Here's a handy tutorial which goes through what you need to do in order to implement data streaming.
Depending on the incoming stream (protocol, etc.) you've ended up or want to end up using:
I'm not sure what you are willing to use/install on the LAMP, or what you'd prefer, but I know VLC can easily capture an incoming stream.
http://wiki.videolan.org/Documentation:Streaming_HowTo/Receive_and_Save_a_Stream
Of course, the Command Line only version of VLC is probably what you want. I've never done it, not sure how that works, I would hope it doesn't install a metric ton of extra packages. This is something to look at concerning possible concerns.

receiving VLC generated MP4 with PhP is a little messy

Im using VCL to broadcast to my localhost, 127.0.0.1 with UDP (legacy) method. To catch the traffic, I use this code:
$address = '127.0.0.1';
$port = 1234;
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_bind($sock, $address, $port) or die('Could not bind to address');
$f = fopen ('output', 'w');
fclose ($f);
$sock = stream_socket_server('udp://127.0.0.1:1234', $errno, $errstr, STREAM_SERVER_BIND);
while(1)
{
$a = stream_socket_recvfrom($sock, 65536);
$f = fopen('output', 'a');
fwrite ($f, $a);
fclose ($f);
#ob_flush();
}
this logs the packets and saves, I rename it to .MP4 and open - well, the result is a little messy. I can recognize the output, the top screen is visible, the lower part is not good. I tried to capture it with another VCL player, and there were no problem.
Here is your code with a lot of useless stuff removed and a few efficiency improvements. Try it out and see what happens. It may or may not fix the problem, but report back with what happens and we'll take it from there.
// Settings
$address = '127.0.0.1';
$port = 1234;
$outfile = "output.mp4";
// Open pointers
if (!$ofp = fopen($outfile, 'w'))
exit("Could not open output file for writing");
if (!$ifp = stream_socket_server("udp://$address:$port", $errno, $errstr, STREAM_SERVER_BIND))
exit("Could not create listen socket ($errno: $errstr)");
// Loop and fetch data
// This method of looping is flawed and will cause problems because you are using
// UDP. The socket will never be "closed", so the loop will never exit. But you
// were looping infinitely before, so this is no different - we can address this
// later
while (!feof($ifp)) {
if (!strlen($chunk = fread($ifp, 8192))) continue;
fwrite($ofp, $chunk);
}
// Close file pointers
fclose($ofp);
#fclose($ifp);

Creating s simple client/server UDP example in PHP

I'm trying to make a simple UDP client server example in PHP but I face an error.
This is the client :
$fp = stream_socket_client("udp://192.168.0.12:12478", $errno, $errstr);
if ($fp)
{
fwrite($fp, "TEST 1 TEST 2 TEST 3");
$buf = fgets($fp);
var_dump($buf);
fclose($fp);
}
This is the server :
$socket = stream_socket_server("udp://192.168.0.12:12478", $errno, $errstr, STREAM_SERVER_BIND);
if ($socket)
{
while ($conn = stream_socket_accept($socket)) {
fwrite($conn, date("D M j H:i:s Y\r\n"));
fclose($conn);
}
fclose($socket);
}
All executions end with :
Warning: stream_socket_accept(): accept failed: Operation not supported
Basically, this is the example given in all PHP documentations but I can't figure what is wrong in it. Any help is greatly appreciated.
Thanks.
Here is the warning on the very same page
Warning
This function should not be used with UDP server sockets. Instead,
use stream_socket_recvfrom() and
stream_socket_sendto().
according to the documentation: "you cannot make a silk piurse from a sow's ear"
stream_socket_connect is intended for STREAMS, not datagram packets. recvfrom would be more likely to work in this scenario.

Categories