1. 程式人生 > >利用第三方庫實現sftp上傳檔案

利用第三方庫實現sftp上傳檔案

封裝一個類CSftp

upload_sftp.h

#define UPLOAD_SFTP_H
#include <QString>
#include <string>

#include "libssh2_sftp.h"

class CSftp
{
public:
    CSftp();
    ~CSftp();
    bool Init(QString remotePath ,QString ip = "10.11.22.34", int port = 22, QString user = "test", QString pwd = "test");
    bool Fini();
    bool CreateFile(const std::string fullPathFileName);
    bool CreateDir(const std::string fullPathName);
    bool UploadSftp(const char * data, const int size,const std::string fullPathName,const std::string fileName);
private:
    bool ConnectToHost();
    bool DisConnHost();
 private:
    int     m_nPort;
    int     m_sock;
    QString m_strIP;
    QString m_strUser;
    QString m_strPwd;
    QString m_remotePath;
    LIBSSH2_SESSION   *m_session;
    LIBSSH2_SFTP         *m_sftpSession;
    LIBSSH2_SFTP_HANDLE *m_sftpHandle;
};

#endif // UPLOAD_SFTP_H

upload_sftp.cpp

#include "upload_huainan.h"
#include <string>
#include "log.h"

#ifdef WIN32
#include <windows.h>
#include <winsock2.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#endif


CSftp::CSftp()
{
    m_session = NULL;
    m_sock = -1;
    m_sftpSession = NULL;
    m_sftpHandle = NULL;
}


CSftp::~CSftp()
{
    if (m_session != NULL)
    {
        libssh2_session_free(m_session);
        m_session = NULL;
    }
    DisConnHost();
    Fini();
}

bool CSftp::Init(QString remotePath ,QString ip /*= "10.11.22.34"*/, int port /*= 22*/, QString user /*= "test"*/, QString pwd /*= "test"*/)
{
    if (ip.length()<1 || user.length()<1 || pwd.length()<1 || port <1 || remotePath.length()<1 )
    {
        return false;
    }
    m_strIP = ip;
    m_nPort = port;
    m_strUser = user;
    m_strPwd = pwd;
    m_remotePath = remotePath;
    //初始化程序的時候呼叫
    //如果非0表示初始化失敗!
    if (libssh2_init(0) != 0)
    {
        return false;
    }
    return true;
}


bool CSftp::Fini()
{
    libssh2_exit();
}


bool CSftp::ConnectToHost()
{
    //新建連線
    m_sock = socket(AF_INET, SOCK_STREAM, 0);
    sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(m_nPort);
    sin.sin_addr.s_addr = inet_addr(m_strIP.toStdString().c_str());
    if ( connect( m_sock, (sockaddr*)(&sin), sizeof(sockaddr_in) ) != 0 )
    {
        Log::trace(Log::Info,QObject::tr("socket failed to connect."));
        DisConnHost();
        return false;
    }

    //新建對話例項
    m_session = libssh2_session_init();
    if (!m_session)
    {
        Log::trace(Log::Info,QObject::tr("new session failed."));
        DisConnHost();
        return false;
    }

    //設定呼叫阻塞
    libssh2_session_set_blocking(m_session, 1);

    //進行握手
    if ( libssh2_session_handshake(m_session, m_sock) )
    {
        Log::trace(Log::Info,QObject::tr("Failure establishing SSH session."));
        DisConnHost();
        return false;
    }

    //獲取主機指紋
    std::string fingerprint = libssh2_hostkey_hash(m_session, LIBSSH2_HOSTKEY_HASH_SHA1);
    std::string userauthlist = libssh2_userauth_list( m_session, m_strUser.toStdString().c_str(), (int)m_strUser.size() );

    int auth_pw = 0;
    if ( strstr( userauthlist.c_str(), "password") != NULL )
    {
        auth_pw |= 1;
    }
    if ( strstr( userauthlist.c_str(), "keyboard-interactive") != NULL )
    {
        auth_pw |= 2;
    }
    if ( strstr(userauthlist.c_str(), "publickey") != NULL)
    {
        auth_pw |= 4;
    }

    if (auth_pw & 1)
    {
        /* We could authenticate via password */
        //通過密碼驗證登陸使用者身份
        if ( libssh2_userauth_password(m_session, m_strUser.toStdString().c_str(), m_strPwd.toStdString().c_str() ) )
        {
            Log::trace(Log::Info,QObject::tr("Authentication by password failed."));
            DisConnHost();
            return false;
        }
    }
    else if (auth_pw & 2)
    {
        /* Or via keyboard-interactive */
        //s_password = userPwd;
        //if (libssh2_userauth_keyboard_interactive(m_session, m_strUser.toStdString().c_str(), &S_KbdCallback) )
        //{
            Log::trace(Log::Info,QObject::tr("keyboard-interactive failed."));
            DisConnHost();
            return false;
        //}
    }
    else
    {
        Log::trace(Log::Info,QObject::tr("auth_pw else failed."));
        DisConnHost();
        return false;
    }
    m_sftpSession = libssh2_sftp_init(m_session);

    if (!m_sftpSession)
    {
        Log::trace(Log::Info,QObject::tr("Unable to init SFTP session."));
        DisConnHost();
        return false;
    }
    return true;
}

bool CSftp::CreateFile(const std::string fullPathFileName)
{
    if (!m_sftpSession || fullPathFileName.length()<1)
    {
        Log::trace(Log::Info,QObject::tr("CreateFile failure."));
        return false;
    }
    //向SFTP伺服器發出新建檔案請求
    m_sftpHandle = libssh2_sftp_open(m_sftpSession, fullPathFileName.c_str(),
        LIBSSH2_FXF_WRITE | LIBSSH2_FXF_CREAT | LIBSSH2_FXF_TRUNC,
        LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR |
        LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IROTH);

    if (!m_sftpHandle)
    {
        Log::trace(Log::Info,QObject::tr("Unable to open file with SFTP."));
        DisConnHost();
        return false;
    }
    return true;
}


bool CSftp::UploadSftp(const char * data, const int size,const std::string fullPathName,const std::string fileName)
{
    if (data == NULL || size <= 0)
    {
        return false;
    }
    if(!ConnectToHost())
    {
        return false;
    }
    if(!CreateDir(fullPathName))
    {
        return false;
    }
    if(!CreateFile(fullPathName + fileName))
    {
        return false;

    }

    ssize_t rc = 0;
    const char* ptr = data;
    size_t nsize = size;
    do {
        // 向伺服器寫資料,直到資料寫完畢
        rc = libssh2_sftp_write(m_sftpHandle, ptr, nsize);
        if (rc < 0)
        {
            break;
        }
        ptr += rc;
        nsize -= rc;
    } while (nsize);

    libssh2_sftp_close(m_sftpHandle);
    libssh2_sftp_shutdown(m_sftpSession);
    DisConnHost();

    return true;
}


bool CSftp::DisConnHost()
{
    if( m_session )
    {
        libssh2_session_disconnect(m_session, "Bye bye, Thank you");
        libssh2_session_free(m_session);
        m_session = NULL;
    }
    if( m_sock != -1 )
    {
#ifdef WIN32
        closesocket(m_sock);
#else
        close(m_sock);
#endif
        m_sock = -1;
    }

    return true;
}

bool CSftp::CreateDir(const std::string fullPathName)
{
    if (!m_sftpSession || fullPathName.length()<1)
    {
        Log::trace(Log::Info,QObject::tr("CreateDir failed___1."));
        return false;
    }
    //向SFTP伺服器發出新建檔案請求

    m_sftpHandle = libssh2_sftp_opendir(m_sftpSession, fullPathName.c_str());

    if (!m_sftpHandle)
    {
        if(libssh2_sftp_mkdir(m_sftpSession, fullPathName.c_str(), S_IRWXU))
        {
            Log::trace(Log::Info,QObject::tr("CreateDir failed___2."));
            return false;
        }
        else
        {
            Log::trace(Log::Info,QObject::tr("CreateDir success."));
            return true;
        }
    }
    return true;
}

轉載請備註出處!!否則,後果自負!!謝謝~  原創微博如下:http://blog.csdn.net/qnavy123

相關推薦

利用第三方實現sftp檔案

封裝一個類CSftpupload_sftp.h#define UPLOAD_SFTP_H#include <QString>#include <string>#include "libssh2_sftp.h"class CSftp{public:   

C#利用HttpListener實現接受檔案

最近一個winform專案想直接用http協議與java端進行雙向通訊,發現HttpListener可以實現http通訊,如果提交form的enctype=application/x-www-form-urlencoded則可以通過HttpUtility.Par

JSch包實現SFTP、下載

-- sch ftp上傳 sftp 實現 gpo AC raft epo JSch包maven倉庫地址: <!-- https://mvnrepository.com/artifact/com.jcraft/jsch --> <dependency>

ajax實現非同步檔案

 html+js程式碼 <form action="" enctype="multipart/form-data" id="upForm"> {{csrf_field()}} <input type="text" name="name" value="

用java實現ftp檔案

實際專案需求:從資料庫查詢資訊,在本地生成檔案,再上傳到ftp 所用Jar包:NetComponents.jar 核心程式碼: import java.io.File; import java.io.FileInputStream; import java.io.IOExcepti

如何呼叫第三方API實現圖片

這裡是修真院後端小課堂,每篇分享文從 【背景介紹】【知識剖析】【常見問題】【解決方案】【編碼實戰】【擴充套件思考】【更多討論】【參考文獻】 八個方面深度解析後端知識/技能,本篇分享的是: 【如何呼叫第三方API實現圖片上傳?  】 1.背景介紹   在

java實現FTP(檔案)、下載(檔案、資料夾、資料夾遞迴)、刪除(檔案、資料夾遞迴)

提示:必須先保證有在FTP上上傳、下載、刪除的許可權! 本文結構 ---- 先給出測試樣例(圖片版),再給出工具類程式碼(文字版)! 上傳測試 注意:.uploadFile(String remoteDir, String remoteFileName, F

Java實現FTP檔案到Linux伺服器的那些坑

一、Linux安裝FTP服務         首先Linux伺服器需要安裝FTP服務,步驟如下: 1、執行如下ftp服務安裝命令: yum install vsftpd 可能會出現如下錯誤: "Couldn't open file /m

利用js/jq 利用FormData 物件和ajax檔案

new FormData(); 可以獲取某個表單,但是有時候感覺不太靈活。可以利用jq獲取指定input type=file 中的檔案,將其賦值給FormData 例項的某個屬性,做上傳。 HTML: <div class="test" style="

【問題解決】利用Eclipse,在hadoop檔案到hdfs沒有內容

本文適用於一些在網上找了半天答案都沒解決問題的人群,因為我也是在按網上說道弄了一天,最後才解決的。如果你是剛遇到問題,還沒有深入,建議你檢視這篇文章 http://f.dataguru.cn/hadoop-208802-1-1.html 將問題一步一步排除後仍沒有解決的話,可以試試我

SpringMVC使用MultipartFile 實現非同步檔案

目的是實現非同步上傳 1.新增pom依賴 新增pom依賴,因為用的ajax,資料需要轉成json的格式進行傳輸,所以還有加入一個JSON jar包: <dependenc

SpringMVC_20_使用HttpMessageConverter T 實現檔案(不推薦)和下載檔案操作

使用HttpMessageConverter< T>將請求資訊轉化並繫結到處理方法的入參中或將響應結果轉化為對應型別的響應資訊,Spring提供了兩種途徑: 使用@RequestBody/@ResponseBody對處理方法進行標註 使用Ht

React Native 使用react-native-image-picker實現圖片功能

react-native-image-picker作為一個整合相機和相簿的功能的第三方庫,因為其使用相對簡單受到前端開發人員的喜愛。 react-native-image-picker使用 1, 首先,安裝下該外掛。 npm install rea

multipart/form-data圖片實現方法(檔案到Nimg)

        在實現multipart/form-data的圖片上傳時,需要用\r\n來分隔每一行,在JAVA中實現multipart/form-data的圖片上傳時則可以使用System.getProperty("line.separator")來進行每一行的分割。但是如果要將程式碼用於Android中

不帶外掛 ,自己寫js,實現批量檔案及進度顯示

今天接受專案中要完成檔案批量上傳檔案而且還要顯示上傳進度,一開始覺得這個應該不是很麻煩,當我在做的時候遇到了很多問題,很頭疼啊。 不過看了別人寫的程式碼,自己也測試過,發現網上好多都存在一些問題,並不是自己想要的。然後自己查閱各種資料,經過自己總結,最終完成了這個功能。

python 實現自動檔案到百度網盤(附程式原始碼及實現過程)

5、編寫AutoIt指令碼,實現檔案上傳 1.開啟scite script editor 程式碼如下: # coding=utf-8 import time from selenium import webdriver driver = webdriver.Firefox() #開啟火狐瀏覽器 dr

阿里雲物件儲存OSS--實現隨時隨地檔案到阿里雲

需求背景:消費者多批次回饋我司生產的車載智慧後視鏡出現宕機、連不上伺服器等問題,因產品已經出到全國各地不方便去取異常log,也不可能要求消費者把log傳給我們分析。 需求目標:公司內部實現遠端後臺上傳問題機型的log。 必備條件:後視鏡有SIM卡且能夠聯網(

基於html5 websocket API簡單實現斷點檔案

本例項基於html5的 websocket API和netty框架,如果您對兩個技術不太熟悉,可以點選下面連線瞭解 準備: fiefox瀏覽器或chrome瀏覽器 在classpath中匯入netty類庫,json類庫 好拉

jquery.form實現ajax檔案同時設定headers

function ajaxSubmitForm() {     var option = {    url : cache.batchImport,    type : 'POST',    dataType : '

SFTP 檔案報錯:SFTP ERROR?Algorithm negotiation fail

專案過程中曾經遇到這樣一個錯誤:SFTP ERROR?Algorithm negotiation fail。java程式碼利用SFTP上傳客戶伺服器報錯,但是可以在Linux上上傳成功,嘗試過很多解決