SFTP client code example
Environment:Libssh2 1.4.3, zlib-1.2.8, openssl-1.0.1g
Author:Kagula
Last update date:
From Idea 2013, there are two projects in it. You only need to compile the libssh2 project. Before compilation, add the header files of zlib and OpenSSL and the link location of the library file. If you are prompted to not find msvcrt. Lib after compiling libssh2, add the following path for the link library.
C: \ Program Files (x86) \ microsoft visualstudio 12.0 \ Vc \ Lib
The following link path cannot be found: ws2_32.lib or odbc32.lib.
C: \ Program Files (x86) \ microsoftsdks \ windows \ v7.1a \ Lib
After compilation, the file is output to \ libssh2-1.4.3 \ Win32 \ release_lib path
The following is the sample code of the SFTP client.
# Include "sftp_libssh2.h" # include <iostream> int main (INT argc, char * argv []) {// the following code executes kagula: Network during process initialization:: sftp_init (); // test SFTP link kagula: Network: sftp_libssh2 * client = kagula: Network: sftp_libssh2: insT (); STD :: string IP = "192.168.19.130"; uint16_t Port = 22; STD: String USR = "kagula"; STD: String Pwd = "123456 "; if (false = client-> isabilityconn (IP, port, USR, PWD) {STD: cout <client-> Str Lasterror <STD: Endl; Return-1 ;}// Test File Upload, D: \ temp \ a.html if (0! = Client-> upload (IP, 22, USR, PWD, "d :\\ Temp \ a.html", "/home/kagula/a.html") {STD :: cout <"error:" <client-> strlasterror <STD: Endl;} else {STD: cout <client-> strlasterror <STD :: endl;} // download the test file if (0! = Client-> download (IP, 22, USR, PWD, "/home/kagula/a.html", "d: \ temp \ B .html") {STD :: cout <"error:" <client-> strlasterror <STD: Endl;} else {STD: cout <client-> strlasterror <STD :: endl;} // when the process preparation is complete and resources are released, run the following code kagula: Network: sftp_exit (); Return 0 ;}
Sftp_libssh2.h
# Pragma once # include <string> # include <atomic>/* function: SFTP file transfer function last updated: Introduction: SFTP is easily implemented using the libssh2 library, SSH2 client, here shows how to implement SFTP client code test environment: Windows 8.1 64bit, Visual Studio 2013 Professional SP1 OpenSSL 1.0.1g, zlib-1.2.8, libssh2 1.4.3 Win32 console project note: the "libssh2.dll" file needs to be copied to the current project path for dynamic links. Note: the original code supports multithreading and is simplified when the application is extracted, you can modify the code so that it supports uploading or downloading multiple files at the same time. Suggestion: [1] a third-party library directly downloads the source code and compiles it by itself to avoid a lot of trouble in the library due to different compiler versions or different links set. [2] Reading the code and making corresponding modifications as required by the project. Additional reading materials: using the libssh2 library to implement SSH2 clients supporting Password parameters unzip kagula {namespace network {int sftp_init (); void sftp_exit (); Class sftp_bkcall {public:/* progress return value range [0.0, 1.0] */virtual void onprogress (float progress) = 0 ;}; class sftp_libssh2 {public: static sftp_libssh2 * insT () {static sftp_libssh2 inst; Return & inst;}/* entry parameter instructions IP Address: Just fill in an IP address, for example, "1 27.0.0.1 ". Port: port. The default port of the SFTP server is 22. Username: Password: sftppath: Start with remote path "/", for example, "/a.jpg" localpath: local path, for example, "d: \ temp \ test.jpg" strlasterror: if the exit parameter of the error message is returned, it is not equal to zero, indicating that the error failed! */INT upload (STD: String IP, unsigned short port, STD: String username, STD: String password, STD: String localpath, STD: String remotepath ); int download (STD: String IP, unsigned short port, STD: String username, STD: String password, STD: String sftppath, STD: String localpath ); // test whether the SFTP server can connect to bool isabilityconn (STD: String IP, unsigned short port, STD: String username, STD: String password ); // set the return function void setbkcall (sftp_bkcall * bkcall) {m_bkcall = bkcall;} // stores the latest error message STD: String strlasterror; // used to stop the current upload or download thread void stop () {m_isbreak.store (true);} PRIVATE: sftp_libssh2 (): m_bkcall (null) {m_isbreak.store (false );}; // prevent direct initialization of sftp_libssh2 (const sftp_libssh2 &); // prevent copy and replication of sftp_libssh2 & operator = (const sftp_libssh2 &); // prevent allocation (call of operator functions) sftp_bkcall * m_bkcall; STD: atomic_bool m_isbreak; // bool value with read/write protection };}}
Sftp_libssh2.cpp
// Sftp_libssh2.cpp file list # include "outputs" # include <libssh2.h> # include <strong> # ifdef have_winsock2_h # include <winsock2.h> # endif # ifdef have_sys_socket_h # include <sys/socket. h> # endif # ifdef have_netinet_in_h # include <netinet/in. h> # endif # ifdef have_unistd_h # include <unistd. h> # endif # ifdef have_arpa_inet_h # include <ARPA/inet. h> # endif # ifdef have_sys_time_h # include <sys/time. h> # endif # include <Sys/types. h> # include <fcntl. h> # include <errno. h> # include <stdio. h> # include <ctype. h> # include <sstream> # include <iomanip> # pragma comment (Lib, "ws2_32.lib") # pragma comment (Lib, "libeay32.lib") # pragma comment (Lib, "libssh2.lib") namespace kagula {namespace network {// called during process initialization // if it is not 0, initialization fails! Int sftp_init () {wsadata; int rc = wsastartup (makeword (2, 0), & wsadata); If (RC! = 0) {return RC;} rc = libssh2_init (0); Return RC;} // call void sftp_exit () {libssh2_exit (); wsacleanup () when the process ends ();} bool sftp_libssh2: isabilityconn (STD: String IP, unsigned short port, STD: String username, STD: String password) {unsigned long hostaddr; struct sockaddr_in sin; const char * fingerprint; libssh2_session * session; int RC; bool BR = false; file * local; libssh2_sftp * sftp_session; libssh2_sftp_handle * SFTP _ HANDLE; hostaddr = inet_addr (IP. c_str (); // hostaddr = htonl (0x7f000001); // create a connection int sock = socket (af_inet, sock_stream, 0); sin. sin_family = af_inet; sin. sin_port = htons (port); sin. sin_addr.s_addr = hostaddr; If (connect (sock, (struct sockaddr *) (& sin), sizeof (struct sockaddr_in ))! = 0) {STD: ostringstream ostr; ostr <"[" <_ file _ <"] [" <_ line _ <"] failed to connect" <IP <"! "<STD: Endl; strlasterror = ostr. STR (); Return BR;} // create a dialog instance session = libssh2_session_init (); If (! Session) {closesocket (sock); Return BR;} // set call blocking libssh2_session_set_blocking (Session, 1); // perform handshake rc = libssh2_session_handshake (Session, sock ); if (RC) {STD: ostringstream ostr; ostr <"[" <_ file _ <"] [" <_ line _ <"] failure establishing SSH session: "<RC <STD: Endl; strlasterror = ostr. STR (); libssh2_session_free (session); closesocket (sock); Return BR;} // check the host fingerprint STD: ostringstream ostr; fingerp RINT = libssh2_hostkey_hash (Session, libssh2_hostkey_hash_sha1); ostr <"fingerprint:"; for (INT I = 0; I <20; I ++) {unsigned char c = fingerprint [I]; int Nt = C; ostr <STD: Hex <STD: SETW (2) <STD :: setfill ('0') <NT;} strlasterror = ostr. STR (); // verify the login user identity using the password if (libssh2_userauth_password (Session, username. c_str (), password. c_str () {STD: ostringstream ostr; ostr <"[" <_ file _ <"] [" <_ _ Line _ <"] authentication by password failed. "<STD: Endl; strlasterror = ostr. STR (); goto shutdown;} sftp_session = libssh2_sftp_init (session); If (! Sftp_session) {STD: ostringstream ostr; ostr <"[" <_ file _ <"] [" <_ line _ <"] unable to init SFTP session" <STD:: Endl; strlasterror = ostr. STR (); goto shutdown;} BR = true; disconnect (sftp_session); shutdown: libssh2_session_disconnect (Session, "normal shutdown, thank you for playing"); libssh2_session_free (session ); closesocket (sock); Return BR;}/* source reference address http://www.libssh2.org/example S/sftp_write.html */INT sftp_libssh2: Upload (STD: String IP, unsigned short port, STD: String username, STD: String password, STD: String localpath, STD: String remotepath) {If (IP. length () <1 | username. length () <1 | password. length () <1 | localpath. length () <1 | remotepath. length () <1) {return-1;} int Nr = 0; unsigned long hostaddr; struct sockaddr_in sin; const char * fingerprint; libssh2_session * sessio N; int rc =-1; file * local = NULL; libssh2_sftp * sftp_session; libssh2_sftp_handle * sftp_handle; hostaddr = inet_addr (IP. c_str (); // hostaddr = htonl (0x7f000001); If (fopen_s (& Local, localpath. c_str (), "rb ")! = 0) {STD: ostringstream ostr; ostr <"[" <_ file _ <"] [" <_ line _ <"] Can't open local file" <localpath <STD:: Endl; strlasterror = ostr. STR (); Return-2;} // obtain the entire size of the file to be uploaded. fseek (local, 0, seek_end); size_t filesize = ftell (local); // local file size, which is referenced by fseek (local, 0, seek_set) in readfromdisk ); // reset the file pointer to the file header // new connection int sock = socket (af_inet, sock_stream, 0); sin. sin_family = af_inet; sin. sin_port = Hton S (port); sin. sin_addr.s_addr = hostaddr; If (connect (sock, (struct sockaddr *) (& sin), sizeof (struct sockaddr_in ))! = 0) {STD: ostringstream ostr; ostr <"[" <_ file _ <"] [" <_ line _ <"] failed to connect" <IP <std:: Endl; strlasterror = ostr. STR (); fclose (local); Return-3;} // create a session instance session = libssh2_session_init (); If (! Session) {fclose (local); closesocket (sock); Return-4;} // call libssh2libssh2_session_set_blocking (Session, 1) in blocking mode; // perform handshake rc = libssh2_session_handshake (Session, Session, sock); If (RC) {STD: ostringstream ostr; ostr <"[" <_ file _ <"] [" <_ line _ <"] failure establishing SSH session: "<RC <STD: Endl; strlasterror = ostr. STR (); fclose (local); libssh2_session_free (session); closesocket (sock); Return-5 ;}// Obtain the host fingerprint STD: ostringstream ostr; fingerprint = libssh2_hostkey_hash (Session, libssh2_hostkey_hash_sha1); ostr <"fingerprint:"; for (INT I = 0; I <20; I ++) {unsigned char c = fingerprint [I]; int Nt = C; // This conversion is to prevent the symbol bit extension ostr <STD: Hex <STD :: SETW (2) <STD: setfill ('0') <NT;} strlasterror = ostr. STR (); // verify if (libssh2_userauth_password (Session, username. c_str (), password. c_str () {STD: ostringst Ream ostr; ostr <"[" <_ file _ <"] [" <_ line _ <"] authentication by password failed [" <username <<"] [" <password <"]" <RC <STD:: Endl; strlasterror = ostr. STR (); goto shutdown;} sftp_session = libssh2_sftp_init (session); If (! Sftp_session) {STD: ostringstream ostr; ostr <"[" <_ file _ <"] [" <_ line _ <"] unable to init SFTP session" <STD:: Endl; strlasterror = ostr. STR (); goto shutdown;} // send a new file request to the SFTP server sftp_handle = libssh2_sftp_open (sftp_session, remotepath. c_str (), libssh2_fxf_write | libssh2_fxf_creat | libssh2_fxf_trunc, required | libssh2_sftp_s_iwusr | libssh2_sftp_s_irgrp | required); If (! Sftp_handle) {STD: ostringstream ostr; ostr <"[" <_ file _ <"] [" <_ line _ <"] unable to open file with SFTP. IP = "<IP <"] remotepath = ["<remotepath <"] "<STD: Endl; strlasterror = ostr. STR (); Nr =-1; goto shutdown;} Char mem [1024*16]; size_t nread; char * PTR; size_t COUNT = 0; do {nread = fread (MEm, 1, sizeof (MEM), local); If (nread <= 0) {// reach the break at the end of the file;} PTR = MEM; do {// write data to the server until the data is written Bi rc = libssh2_sftp_write (sftp_handle, PTR, nread); If (RC <0) break; PTR + = RC; count + = nread; nread-= RC; // If a callback is set, perform the callback if (m_bkcall) {float P = count/(float) filesize; m_bkcall-> onprogress (p);} // callback. end} while (nread); If (m_isbreak.load () = true) {STD: ostringstream ostr; ostr <"[" <_ file _ <"] [" <_ line _ <"] the file upload task is break by the user! "<STD: Endl; strlasterror = ostr. STR (); Nr =-6; break;} while (rc> 0); libssh2_sftp_close (sftp_handle); merge (sftp_session); shutdown: libssh2_session_disconnect (Session, "normal shutdown, thank you for playing "); libssh2_session_free (session); closesocket (sock); fclose (local); Return NR; // return "0" to indicate success}/* Source code reference address: http://www.oschina.net/code/snippet_12_201717824/int sftp_libssh2: Download (STD: Stri Ng IP, unsigned short port, STD: String username, STD: String password, STD: String sftppath, STD: String localpath) {unsigned long hostaddr; int sock, i, auth_pw = 0; struct sockaddr_in sin; const char * fingerprint; char * userauthlist; Comment * session; int RC; Comment * sftp_session; Comment * sftp_handle; hostaddr = inet_addr (IP. c_str (); // hostaddr = htonl (0x7f000001);/** the appli Cation code is responsible for creating the socket * and establishing the connection */sock = socket (af_inet, sock_stream, 0); sin. sin_family = af_inet; sin. sin_port = htons (port); sin. sin_addr.s_addr = hostaddr; If (connect (sock, (struct sockaddr *) (& sin), sizeof (struct sockaddr_in ))! = 0) {STD: ostringstream ostr; ostr <"[" <_ file _ <"] [" <_ line _ <"] connection failed! "<STD: Endl; strlasterror = ostr. STR (); Return-1;}/* Create a session instance */session = libssh2_session_init (); If (! Session) Return-1;/* since we have set non-blocking, tell libssh2 we are blocking */libssh2_session_set_blocking (Session, 1 );/*... start it up. this will trade welcome banners, exchange keys, * and setup crypto, compression, and MAC layers */rc = libssh2_session_handshake (Session, sock); If (RC) {STD :: ostringstream ostr; ostr <"[" <_ file _ <"] [" <_ line _ <"] failed to establish an SSH session" <RC <STD:: Endl; s Trlasterror = ostr. STR (); Return-1;}/* at this point we havn't yet authenticated. the first thing to do * is check the hostkey's fingerprint against our known hosts your app * may have it hard coded, may go to a file, may present it to the * user, that's your call */fingerprint = libssh2_hostkey_hash (Session, libssh2_hostkey_hash_sha1); STD: ostringstream ostr; fingerprint = libssh2_hostkey_hash (Session, Libssh2_hostkey_hash_sha1); ostr <"fingerprint:"; for (INT I = 0; I <20; I ++) {unsigned char c = fingerprint [I]; int Nt = C; ostr <STD: Hex <STD: SETW (2) <STD: setfill ('0') <NT ;} strlasterror = ostr. STR ();/* Check what authentication methods are available */userauthlist = libssh2_userauth_list (Session, username. c_str (), username. length (); If (strstr (userauthlist, "password") = NULL) {STD:: Ostringstream ostr; ostr <"[" <_ file _ <"] [" <_ line _ <"] the server does not support password verification! "<STD: Endl; strlasterror = ostr. STR (); goto shutdown;}/* We cocould authenticate via password */If (libssh2_userauth_password (Session, username. c_str (), password. c_str () {STD: ostringstream ostr; ostr <"[" <_ file _ <"] [" <_ line _ <"] incorrect password! "<STD: Endl; strlasterror = ostr. STR (); goto shutdown;} sftp_session = libssh2_sftp_init (session); If (! Sftp_session) {STD: ostringstream ostr; ostr <"[" <_ file _ <"] [" <_ line _ <"] failed to initialize the FTL conversation! "<STD: Endl; strlasterror = ostr. STR (); goto shutdown;}/* request a file via SFTP */sftp_handle = libssh2_sftp_open (sftp_session, sftppath. c_str (), libssh2_fxf_read, 0); If (! Sftp_handle) {STD: ostringstream ostr; ostr <"[" <_ file _ <"] [" <_ line _ <"] failed to open the file! "<Libssh2_sftp_last_error (sftp_session) <STD: Endl; strlasterror = ostr. STR (); goto shutdown;} file * stream; If (fopen_s (& stream, localpath. c_str (), "WB") = 0) {do {char mem [1024];/* loop until we fail */rc = libssh2_sftp_read (sftp_handle, mem, sizeof (MEM); If (rc> 0) {// from memory to disk fwrite (MEm, 1, RC, stream);} else {break ;}} while (1); fclose (Stream);} else {STD: ostringstream ostr; ostr <"[" <_ file _ <"] [" <_ line _ <"] failed to create local file" <localpath <STD:: Endl; strlasterror = ostr. STR ();} libssh2_sftp_close (sftp_handle); terminate (sftp_session); shutdown: suspend (Session, "normal shutdown, thank you for playing"); libssh2_session_free (session ); closesocket (sock); // invalid_socketreturn 0 ;}}}
SFTP client code example