在Android

时间:2015-05-07 23:37:54

标签: android ssh sftp jsch android-networking

我正在使用JSch在Android中执行SFTP下载。这是在具有802.11n的LAN上,以及有线千兆位连接上的SFTP服务器。我使用相同的代码在笔记本电脑(也是802.11n)上获得大约8 MB /秒的速度,但我在Android上的速度只有40kbytes / sec。是否有一些标志或我需要打开的东西才能让它更快地传输?我已经在Nexus 5和Nexus 6上试用了它,都是5.1。我尝试了几个应用程序,一个以230kbytes /秒的速度下载文件,另一个以40kbytes / sec的速度下载,所以我猜其中一个有我遇到的问题。

这是我的代码:

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Thread thread = new Thread() {
            @Override
            public void run() {
                try {
                    JSch jsch = new JSch();

                    jsch.setConfig("StrictHostKeyChecking", "no");
                    Session session = jsch.getSession("ftptest", "192.168.1.205");

                    session.setPort(22);
                    session.setPassword("password");
                    session.connect();
                    ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");
                    channel.connect();
                    SftpProgressMonitor monitor = new SftpProgressMonitor() {
                        long finalCount = 0;
                        long start = -1;

                        @Override
                        public void init(int op, String src, String dest, long max) {
                            start = System.currentTimeMillis();
                        }

                        @Override
                        public boolean count(long count) {
                            finalCount += count;
                          /*  long took = (System.currentTimeMillis() - start) / 1000;
                            if (took > 0) {
                                Log.w("SFTP", "Transferred so far " + finalCount + " at speed bytes/sec " + (finalCount / took));
                            }*/
                            return true;
                        }

                        @Override
                        public void end() {
                            long took = (System.currentTimeMillis() - start) / 1000;
                            Log.w("SFTP", "Transferred " + finalCount + " in " + took + " speed bytes/sec " + (finalCount  / took ));
                        }
                    };
                    InputStream stream = channel.get("file", monitor);
                    int read = -1;
                    byte[] bs = new byte[8192];
                    while((read = stream.read(bs)) >= 0){
                        //do nothing
                    }
                } catch (JSchException e) {
                    e.printStackTrace();
                } catch (SftpException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        };
        thread.start();
    }


}

编辑:如果我告诉它将流写入文件而不给我一个InputStream,它似乎要快得多(大约160kbytes / sec)。两个get方法之间的代码看起来非常不同,但即使我走了那条路,160kbytes / sec仍然比我希望的要慢得多。

2 个答案:

答案 0 :(得分:0)

您正在测试哪个版本的Android?你可以adb shell并查看这些设置是什么(当你在wifi上时)?

cat /proc/sys/net/ipv4/tcp_rmem
cat /proc/sys/net/ipv4/tcp_wmem

然后如果它们很低(类似于“4092 8760 11680”),那么尝试将它们设置为更大的值:

sudo echo "524288,1048576,2097152" > /proc/sys/net/ipv4/tcp_rmem
sudo echo "262144,524288,1048576" > /proc/sys/net/ipv4/tcp_wmem

然后再试一次。

这可能是因为某些情况下wifi缓冲区设置得太小的错误(https://code.google.com/p/android/issues/detail?id=64706)。

答案 1 :(得分:0)

您是否尝试过在缓冲流中包装流?

 BufferedInputStream bis = new BufferedInputStream(channel.get("file", monitor));

8192字节似乎是一个小缓冲区...

还要确保关闭你的连接/流,也许你有很多传出的连接,你不知道这会占用硬件?