From 2ba8db91683f84834c4f0ac98b1501ad77ad2780 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 13 Mar 2009 12:35:13 +0000 Subject: [PATCH] wait for socket action accordingly, and do some measurements on the transfer to make this better to use for speed tests --- example/simple/sftp_nonblock.c | 94 ++++++++++++++++++++++++++++------ 1 file changed, 78 insertions(+), 16 deletions(-) diff --git a/example/simple/sftp_nonblock.c b/example/simple/sftp_nonblock.c index c56d15d..3637eab 100644 --- a/example/simple/sftp_nonblock.c +++ b/example/simple/sftp_nonblock.c @@ -1,12 +1,12 @@ /* - * $Id: sftp_nonblock.c,v 1.15 2008/11/10 16:48:41 bagder Exp $ + * $Id: sftp_nonblock.c,v 1.16 2009/03/13 12:35:13 bagder Exp $ * * Sample showing how to do SFTP non-blocking transfers. * * The sample code has default values for host name, user name, password * and path to copy, but you can specify them on the command line like: * - * "sftp 192.168.0.1 user password /tmp/secrets" + * "sftp_nonblock 192.168.0.1 user password /tmp/secrets" */ #include "libssh2_config.h" @@ -38,6 +38,43 @@ #include #include +/* diff in ms */ +static long tvdiff(struct timeval newer, struct timeval older) +{ + return (newer.tv_sec-older.tv_sec)*1000+ + (newer.tv_usec-older.tv_usec)/1000; +} + +static int waitsocket(int socket_fd, LIBSSH2_SESSION *session) +{ + struct timeval timeout; + int rc; + fd_set fd; + fd_set *writefd = NULL; + fd_set *readfd = NULL; + int dir; + + timeout.tv_sec = 10; + timeout.tv_usec = 0; + + FD_ZERO(&fd); + + FD_SET(socket_fd, &fd); + + /* now make sure we wait in the correct direction */ + dir = libssh2_session_block_directions(session); + + if(dir & LIBSSH2_SESSION_BLOCK_INBOUND) + readfd = &fd; + + if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND) + writefd = &fd; + + rc = select(socket_fd + 1, readfd, writefd, NULL, &timeout); + + return rc; +} + int main(int argc, char *argv[]) { unsigned long hostaddr; @@ -48,7 +85,12 @@ int main(int argc, char *argv[]) const char *username="username"; const char *password="password"; const char *sftppath="/tmp/TEST"; + struct timeval start; + struct timeval end; int rc; + int total = 0; + long time_ms; + int spin = 0; #if defined(HAVE_IOCTLSOCKET) long flag = 1; #endif @@ -116,10 +158,13 @@ int main(int argc, char *argv[]) /* Since we have set non-blocking, tell libssh2 we are non-blocking */ libssh2_session_set_blocking(session, 0); + gettimeofday(&start, NULL); + /* ... start it up. This will trade welcome banners, exchange keys, * and setup crypto, compression, and MAC layers */ - while ((rc = libssh2_session_startup(session, sock)) == LIBSSH2_ERROR_EAGAIN); + while ((rc = libssh2_session_startup(session, sock)) == + LIBSSH2_ERROR_EAGAIN); if (rc) { fprintf(stderr, "Failure establishing SSH session: %d\n", rc); return -1; @@ -139,17 +184,22 @@ int main(int argc, char *argv[]) if (auth_pw) { /* We could authenticate via password */ - while ((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN); + while ((rc = libssh2_userauth_password(session, username, password)) + == LIBSSH2_ERROR_EAGAIN); if (rc) { fprintf(stderr, "Authentication by password failed.\n"); goto shutdown; } } else { /* Or by public key */ - while ((rc = libssh2_userauth_publickey_fromfile(session, username, - "/home/username/.ssh/id_rsa.pub", - "/home/username/.ssh/id_rsa", - password)) == LIBSSH2_ERROR_EAGAIN); + while ((rc = + libssh2_userauth_publickey_fromfile(session, username, + "/home/username/" + ".ssh/id_rsa.pub", + "/home/username/" + ".ssh/id_rsa", + password)) == + LIBSSH2_ERROR_EAGAIN); if (rc) { fprintf(stderr, "\tAuthentication by public key failed\n"); goto shutdown; @@ -160,7 +210,8 @@ int main(int argc, char *argv[]) do { sftp_session = libssh2_sftp_init(session); - if ((!sftp_session) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) { + if ((!sftp_session) && (libssh2_session_last_errno(session) != + LIBSSH2_ERROR_EAGAIN)) { fprintf(stderr, "Unable to init SFTP session\n"); goto shutdown; } @@ -169,9 +220,11 @@ int main(int argc, char *argv[]) fprintf(stderr, "libssh2_sftp_open()!\n"); /* Request a file via SFTP */ do { - sftp_handle = libssh2_sftp_open(sftp_session, sftppath, LIBSSH2_FXF_READ, 0); + sftp_handle = libssh2_sftp_open(sftp_session, sftppath, + LIBSSH2_FXF_READ, 0); - if ((!sftp_handle) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) { + if (!sftp_handle && + (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) { fprintf(stderr, "Unable to open file with SFTP\n"); goto shutdown; } @@ -179,26 +232,35 @@ int main(int argc, char *argv[]) fprintf(stderr, "libssh2_sftp_open() is done, now receive data!\n"); do { - char mem[1024]; + char mem[1024*24]; /* loop until we fail */ - fprintf(stderr, "libssh2_sftp_readnb()!\n"); - while ((rc = libssh2_sftp_read(sftp_handle, mem, sizeof(mem))) == LIBSSH2_ERROR_EAGAIN) { - ; + while ((rc = libssh2_sftp_read(sftp_handle, mem, + sizeof(mem))) == LIBSSH2_ERROR_EAGAIN) { + spin++; + waitsocket(sock, session); /* now we wait */ } if (rc > 0) { + total += rc; write(1, mem, rc); } else { break; } } while (1); + gettimeofday(&end, NULL); + time_ms = tvdiff(end, start); + printf("Got %d bytes in %ld ms = %.1f bytes/sec spin: %d\n", total, + time_ms, total/(time_ms/1000.0), spin ); + libssh2_sftp_close(sftp_handle); libssh2_sftp_shutdown(sftp_session); shutdown: - while ((rc = libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing")) == LIBSSH2_ERROR_EAGAIN); + while ((rc = libssh2_session_disconnect(session, + "Normal Shutdown, Thank you")) == + LIBSSH2_ERROR_EAGAIN); libssh2_session_free(session); #ifdef WIN32