I am connected to the server via the PHP ftp_
functions.
How can I measure the transfer spe开发者_StackOverflow中文版ed?
Use the non-blocking ftp functions to download the file and calculate the time and file size differences. Below is a simple demo with exponential smoothing to prevent the speed from jumping too much:
define('ALPHA', 0.2); // Weight factor of new calculations, between 0 and 1
$ftp = ftp_connect(...);
$tmp = ftp_nb_get($ftp, $filename, $filename, FTP_BINARY);
$transferred = 0;
$rate = 0;
$time = microtime(true);
while ($tmp == FTP_MOREDATA) {
$tmp = ftp_nb_continue($ftp);
$timeNow = microtime(true);
$sizeNow = filesize($filename);
$currentRate = ($sizeNow - $transferred) / ($timeNow - $time);
$rate = ALPHA * $currentRate + (1 - ALPHA) * $rate;
$time = $timeNow;
$transferred = $sizeNow;
echo "Current transfer speed: $rate B/s\n";
}
If you want same thing for ftp_nb_put()
upload, you would have to replace filesize($filename)
with ftp_size($ftp2,$filename)
, where $ftp2
would have to be a second, identical connection, used just to ask for size of remote file, because ftp_size()
will not work with your primary connection, while non-blocking transfer is in progress.
This is how I brutalized the phihag's code to check non-blocking upload speed. You can't use ftp_size()
while non-blocking transfer is ongoing, therefore you need a secondary connection just for that purpose. I'm displaying current speed, average speed, elapsed time and estimated time left.
$primary_connection = ftp_connect($server);
$secondary_connection = ftp_connect($server);
$mode = FTP_BINARY;
$login = ftp_login($primary_connection, $ftp_user_name, $ftp_user_pass);
$login2 = ftp_login($secondary_connection, $ftp_user_name, $ftp_user_pass);
if (!$primary_connection || !$login) { die('Connection attempt failed!'); }
ftp_pasv($primary_connection,TRUE);
ftp_pasv($secondary_connection,TRUE);
$upload_status=ftp_nb_put($primary_connection, $destination_file, $source_file, $mode);
define('ALPHA', 0.2); // Weight factor of new calculations, between 0 and 1
$filesize=filesize($source_file);
$transferred = 0;
$rate = 0;
$time = microtime(true);
$start_time=$time;
while($upload_status == FTP_MOREDATA){
$upload_status = ftp_nb_continue($primary_connection);
$sizeNow=ftp_size($secondary_connection,$destination_file);
$sizeNowkB=$sizeNow/1024;
$timeNow = microtime(true);
$currentRate = ($sizeNow - $transferred) / ($timeNow - $time);
$currentkBRate = $currentRate / 1024;
$rate = ALPHA * $currentRate + (1 - ALPHA) * $rate;
$time = $timeNow;
$transferred = $sizeNow;
printf("Uploading file: %s",$source_file);
echo "<br>\n";
printf( "To be transferred: %0.2f kB", $filesize/1024);
echo "<br>\n";
printf( "Transferred: %0.2f kB", $sizeNowkB);
echo "<br>\n";
printf( "Current speed: %0.2f kB/s", $currentkBRate);
echo "<br>\n";
printf( "Average speed: %0.2f kB/s", $rate/1024);
echo "<br>\n";
$elapsed_time=$timeNow - $start_time;
printf( "Elapsed time: %0.2f s", $elapsed_time);
echo "<br>\n";
if($rate!=0){
$eta=$filesize/$rate - $elapsed_time;
}else{
$eta=0.0;
}
if($eta<=0){
$eta=0.0;
};
printf( "Estimated time left: %0.2f s", $eta);
echo "<br>\n";
}
- Before transferring, put the current timestamp into a variable.
- Determine the size of your file you want to transfer.
- Transfer the file with the
ftp
functions - Get another timestamp and subtract this from the first timestamp.
- Divide the filesize with the result, then you have the kb/sec.
Example:
$start = mktime(); // 1
$size = filesize('yourfile.txt') / 1024 ; // 2 <- to get the KB
... do your transfer... // 3
//after ftp transfer
$stop = mktime(); // 4
$duration = $stop - $start;
$speed = $size / $duration; // 5
This basically gives you the speed after the transfer. If you want the speed while transferring, there are other ways of doing it.
精彩评论