sftp_write_nonblock: select() on socket, use *BIG* buffer, time transfer
The select() is just to make it nicer so that it doesn't crazy-loop on EAGAIN. The buffer size thing is mostly to verify that this really work as supposed. Transfer timing is just a minor thing, but it can just as well be there and help us time and work on performance easier using out of the box examples.
Этот коммит содержится в:
родитель
22a2de7347
Коммит
31d71a94f2
@ -34,6 +34,37 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
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[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@ -53,9 +84,12 @@ int main(int argc, char *argv[])
|
|||||||
FILE *local;
|
FILE *local;
|
||||||
LIBSSH2_SFTP *sftp_session;
|
LIBSSH2_SFTP *sftp_session;
|
||||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||||
char mem[1024];
|
char mem[1024 * 100];
|
||||||
size_t nread;
|
size_t nread;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
time_t start;
|
||||||
|
long total = 0;
|
||||||
|
int duration;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
WSADATA wsadata;
|
||||||
@ -142,17 +176,19 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (auth_pw) {
|
if (auth_pw) {
|
||||||
/* We could authenticate via password */
|
/* We could authenticate via password */
|
||||||
while ((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN);
|
while ((rc = libssh2_userauth_password(session, username, password)) ==
|
||||||
if (rc) {
|
LIBSSH2_ERROR_EAGAIN);
|
||||||
|
if (rc) {
|
||||||
printf("Authentication by password failed.\n");
|
printf("Authentication by password failed.\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Or by public key */
|
/* Or by public key */
|
||||||
while ((rc = libssh2_userauth_publickey_fromfile(session, username,
|
while ((rc = libssh2_userauth_publickey_fromfile(session, username,
|
||||||
"/home/username/.ssh/id_rsa.pub",
|
"/home/username/.ssh/id_rsa.pub",
|
||||||
"/home/username/.ssh/id_rsa",
|
"/home/username/.ssh/id_rsa",
|
||||||
password)) == LIBSSH2_ERROR_EAGAIN);
|
password)) ==
|
||||||
|
LIBSSH2_ERROR_EAGAIN);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
printf("\tAuthentication by public key failed\n");
|
printf("\tAuthentication by public key failed\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
@ -163,7 +199,8 @@ int main(int argc, char *argv[])
|
|||||||
do {
|
do {
|
||||||
sftp_session = libssh2_sftp_init(session);
|
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");
|
fprintf(stderr, "Unable to init SFTP session\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
@ -178,13 +215,17 @@ int main(int argc, char *argv[])
|
|||||||
LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
|
LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
|
||||||
LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
|
LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
|
||||||
|
|
||||||
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");
|
fprintf(stderr, "Unable to open file with SFTP\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
} while (!sftp_handle);
|
} while (!sftp_handle);
|
||||||
|
|
||||||
fprintf(stderr, "libssh2_sftp_open() is done, now send data!\n");
|
fprintf(stderr, "libssh2_sftp_open() is done, now send data!\n");
|
||||||
|
|
||||||
|
start = time(NULL);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
nread = fread(mem, 1, sizeof(mem), local);
|
nread = fread(mem, 1, sizeof(mem), local);
|
||||||
if (nread <= 0) {
|
if (nread <= 0) {
|
||||||
@ -193,16 +234,28 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
ptr = mem;
|
ptr = mem;
|
||||||
|
|
||||||
|
total += nread;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
/* write data in a loop until we block */
|
/* write data in a loop until we block */
|
||||||
while ((rc = libssh2_sftp_write(sftp_handle, ptr, nread)) == LIBSSH2_ERROR_EAGAIN) {
|
while ((rc = libssh2_sftp_write(sftp_handle, ptr, nread)) ==
|
||||||
;
|
LIBSSH2_ERROR_EAGAIN) {
|
||||||
|
waitsocket(sock, session);
|
||||||
}
|
}
|
||||||
|
if(rc < 0)
|
||||||
|
break;
|
||||||
ptr += rc;
|
ptr += rc;
|
||||||
nread -= rc;
|
nread -= rc;
|
||||||
|
|
||||||
} while (nread);
|
} while (nread);
|
||||||
} while (rc > 0);
|
} while (rc > 0);
|
||||||
|
|
||||||
|
duration = (int)(time(NULL)-start);
|
||||||
|
|
||||||
|
printf("%ld bytes in %d seconds makes %.1f bytes/sec\n",
|
||||||
|
total, duration, total/(double)duration);
|
||||||
|
|
||||||
|
|
||||||
fclose(local);
|
fclose(local);
|
||||||
libssh2_sftp_close(sftp_handle);
|
libssh2_sftp_close(sftp_handle);
|
||||||
libssh2_sftp_shutdown(sftp_session);
|
libssh2_sftp_shutdown(sftp_session);
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user