Re: [JSch-users] SFTP slow file transfer speed with Titan FTP
Status: Alpha
Brought to you by:
ymnk
|
From: Thomas K. <tho...@ou...> - 2016-03-29 12:17:12
|
I've managed to overcome this issue myself. First, I tried to find out where the blocking actually occurs. After a number of sent bulk requests the ChannelSftp.header(Buffer, Header) method gets blocked for exactly 60 seconds, that's the stack trace:
Daemon Thread [Camel (camel-1) thread #0 - sftp://secret/archive] (Suspended)
waiting for: Channel$MyPipedInputStream (id=26)
Object.wait(long) line: not available [native method]
Channel$MyPipedInputStream(PipedInputStream).read() line: 326
Channel$MyPipedInputStream(PipedInputStream).read(byte[], int, int) line: 377
ChannelSftp.fill(byte[], int, int) line: 2605
ChannelSftp.header(Buffer, ChannelSftp$Header) line: 2631
ChannelSftp.access$11(ChannelSftp, Buffer, ChannelSftp$Header) line: 2629
ChannelSftp$2.read(byte[], int, int) line: 1282
ChannelSftp$2.read(byte[]) line: 1232
FileOperations.writeFileByStream(InputStream, File) line: 382
I don't know what is causing this. After the "timeout" occurred processing continued until the next outage. I tried to reproduce the "bug" with Openssh's sftp command and the -R (num_requests) argument which I think is meant by "sending multiple requests at any one time". As Openssh's sftp works well I compared the ChannelSftp implementation with what is in sftp-client.c. The only obvious difference I found is the "rq.count()==0" condition in "ChannelSftp.get(String, SftpProgressMonitor, long).new InputStream() {...}.read(byte[], int, int)". Removing the condition fixes the issue for me.
Can this be considered as a bug? Is this something eligible for a next version of JSCH?
The following patch is based upon jsch-0.1.53:
--- src/com/jcraft/jsch/ChannelSftp.java
+++ src/com/jcraft/jsch/ChannelSftp.java
@@ -1374,17 +1374,16 @@
len=1024;
}
- if(rq.count()==0) {
- int request_len = buf.buffer.length-13;
- if(server_version==0){ request_len=1024; }
- while(rq.count() < request_max){
- try{
- sendREAD(handle, request_offset, request_len, rq);
- }
- catch(Exception e){ throw new IOException("error"); }
- request_offset += request_len;
+ int request_len = buf.buffer.length-13;
+ if(server_version==0){ request_len=1024; }
+
+ while(rq.count() < request_max){
+ try{
+ sendREAD(handle, request_offset, request_len, rq);
}
+ catch(Exception e){ throw new IOException("error"); }
+ request_offset += request_len;
}
header=header(buf, header);
Thanks for considering this.
Regards,
Thomas
|