1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-07-05 21:42:47 -05:00

First cut at speeding up SFTP. Generic download-management code in

sftp.c, and psftp.c now uses that instead of going it alone. Should
in principle be easily installed in PSCP as well, but I haven't done
it yet; also it only handles downloads, not uploads, and finally it
doesn't yet properly calculate the correct number of parallel
requests to queue. Still, it's a start, and in my own tests it
seemed to perform as expected (download speed suddenly became
roughly what you'd expect from the available bandwidth, and
decreased by roughly the expected number of round-trip times).

[originally from svn r3468]
This commit is contained in:
Simon Tatham
2003-09-27 17:52:34 +00:00
parent e3018a08e8
commit bc83c59aa7
3 changed files with 290 additions and 26 deletions

55
psftp.c
View File

@ -370,6 +370,7 @@ int sftp_general_get(struct sftp_command *cmd, int restart)
struct fxp_handle *fh;
struct sftp_packet *pktin;
struct sftp_request *req, *rreq;
struct fxp_xfer *xfer;
char *fname, *outfname;
uint64 offset;
FILE *fp;
@ -439,41 +440,43 @@ int sftp_general_get(struct sftp_command *cmd, int restart)
* thus put up a progress bar.
*/
ret = 1;
while (1) {
char buffer[4096];
int len;
xfer = xfer_download_init(fh, offset);
while (!xfer_download_done(xfer)) {
void *vbuf;
int ret, len;
int wpos, wlen;
sftp_register(req = fxp_read_send(fh, offset, sizeof(buffer)));
rreq = sftp_find_request(pktin = sftp_recv());
assert(rreq == req);
len = fxp_read_recv(pktin, rreq, buffer, sizeof(buffer));
xfer_download_queue(xfer);
pktin = sftp_recv();
ret = xfer_download_gotpkt(xfer, pktin);
if ((len == -1 && fxp_error_type() == SSH_FX_EOF) || len == 0)
break;
if (len == -1) {
printf("error while reading: %s\n", fxp_error());
ret = 0;
break;
if (ret < 0) {
printf("error while reading: %s\n", fxp_error());
ret = 0;
}
wpos = 0;
while (wpos < len) {
wlen = fwrite(buffer, 1, len - wpos, fp);
if (wlen <= 0) {
printf("error while writing local file\n");
ret = 0;
break;
while (xfer_download_data(xfer, &vbuf, &len)) {
unsigned char *buf = (unsigned char *)vbuf;
wpos = 0;
while (wpos < len) {
wlen = fwrite(buf + wpos, 1, len - wpos, fp);
if (wlen <= 0) {
printf("error while writing local file\n");
ret = 0;
xfer_set_error(xfer);
}
wpos += wlen;
}
if (wpos < len) { /* we had an error */
ret = 0;
xfer_set_error(xfer);
}
wpos += wlen;
}
if (wpos < len) { /* we had an error */
ret = 0;
break;
}
offset = uint64_add32(offset, len);
}
xfer_cleanup(xfer);
fclose(fp);
sftp_register(req = fxp_close_send(fh));