Code below to send/receive files over TRBO. Server script runs on base unit, waits for connection from client. Spawns child process to receive and verify data. Received files are placed in the 'infile' folder, located in same directory as scripts. Handles multiple clients at the same time.
disclaimer:
Of course, it's in php. There might be errors. Seems to send text files alright. Might send binary too. Both sides spew some random debugging info to stdout.
server: $ php file-server.php
client: $ php file-send.php <filename> <server_radio_id>
Server scripts:
file-server.php
Code: Select all
<?php
set_time_limit(0);
$sock = stream_socket_server('udp://0.0.0.0:4041', $errno, $errstr, STREAM_SERVER_BIND);
if (!$sock) {
die("$errstr ($errno)");
}
$PIDS = array();
do {
$pkt = stream_socket_recvfrom($sock, 1000, 0, $peer);
$pid = pcntl_fork();
if ($pid == -1) {
die ('could not fork');
} elseif ($pid) {
// parent
$PIDS[] = $pid;
} else {
// child
include "file-xfer.inc.php";
exit;
}
/** cleanup dead children **/
foreach ($PIDS as $pid) pcntl_waitpid($pid,$status,WNOHANG);
} while ($pkt !== false);
/** cleanup dead parents **/
foreach ($PIDS as $pid) {
$returnPid = pcntl_waitpid($pid,$status);
unset($PIDS[$pid]);
}
fclose($sock);
?>
file-xfer.php
Code: Select all
<?php
$stime = time();
print " start: $stime\n";
$xsock = stream_socket_server('udp://0.0.0.0:0', $xerrno, $xerrstr, STREAM_SERVER_BIND);
if (!$xsock) {
die("$xerrstr ($xerrno)");
}
list($xhost, $xport) = explode(":", stream_socket_get_name($xsock, FALSE));
list($fname, $fsize, $fhash) = explode("/////", trim($pkt));
stream_socket_sendto($sock, "$xport\n", 0, $peer);
print "xfer: $xport; fname: $fname; fsize: $fsize;\n";
$ftmp = "";
stream_set_timeout($xsock, 120);
while (strlen($ftmp) < $fsize) {
$pkt = stream_socket_recvfrom($xsock, 900, 0, $peer);
$ftmp .= $pkt;
print " size: " . strlen($ftmp) . "\n";
stream_socket_sendto($xsock, "K", 0, $peer);
}
if (strlen($ftmp) == $fsize) {
$hash = hash('md5', $ftmp);
if ($hash == $fhash) {
$fh = fopen("infile/$fname", 'w');
fputs($fh, $ftmp);
fclose($fh);
// success-xfer
$result = 0;
} else {
// bad hash
$result = 2;
}
} else {
// fail-xfer
$result = 1;
}
stream_socket_sendto($xsock, "$result", 0, $peer);
fclose($xsock);
$etime = time();
$dur = $etime - $stime;
$abps = $fsize / $dur;
print " end: $etime\n duration: $dur\n abps: $abps\n\n";
exit;
?>
Client script:
file-send.php
Code: Select all
<?php
set_time_limit(0);
$port_init = "4041";
if ($argc !== 3) { die ("usage: file-send.php <filename> <target_id>\n"); }
$file = $argv[1];
$id = $argv[2];
if (!is_numeric($id)) {
die("id not numeric\n");
}
if (($id < 1) | ($id > 16776415)) {
die("id out of range -- 1-16776415\n");
}
if (!is_file($file)) {
die("file not valid\n");
}
$host = '13.' . (($id >> 16) & 0xFF) . '.' . (($id >> 8) & 0xFF) . '.' . ($id & 0xFF);
$handle = fopen($file, "rb");
$fname = basename($file);
$fsize = filesize($file);
$fhash = hash_file('md5', $file);
if ($handle) {
/* ititiate connection */
$sock = stream_socket_client("udp://{$host}:{$port_init}", $errno, $errstr);
if (!$sock) {
die ("error: $errno - $errstr\n");
}
fwrite($sock, "$fname/////$fsize/////$fhash\n");
$xport = trim(stream_socket_recvfrom($sock, 6));
fclose($sock);
$xsock = stream_socket_client("udp://{$host}:{$xport}", $errno, $errstr);
if (!$xsock) {
die ("x error: $errno = $errstr\n");
}
/* send file */
$j = 1;
stream_set_timeout($xsock, 90);
while (!feof($handle)) {
$buf = fread($handle, 900);
#send buffer
fwrite($xsock, $buf);
print "sent: $j\n";
$j++;
$ret = stream_socket_recvfrom($xsock, 1);
if ($ret !== "K") { die("error sending"); }
sleep(1);
}
print "done sending\n";
$ret = stream_socket_recvfrom($xsock, 1);
if ($ret == "0") {
echo "success!\n";
} else {
echo "fail -- $ret\n";
}
fclose($xsock);
fclose($handle);
}
?>