小可爱网络科技 2022-05-11 20:27 采纳率: 0%
浏览 199
已结题

使用libssh2库文件上传sftp协议速度很慢

为了自己更好的管理自己写的项目 打算自己写一个sftp工具 方便自己使用 百度搜了一下资料 基本都是用的开源的libssh2库 所以写了一个demo发现上传速度很慢 我的是阿里云的服务器 用openSSH工具上传速度可以达到8M/s 但是使用libssh2库发现只有1M/s 我以为是我代码的问题 我尝试调大缓冲区 堵塞模式和非堵塞模式 发现不管如何调节 速度都会保持在1M/s

后来我想到一个方法 并发多线程上传 上传文件的时候 把文件拆开成10份 并开启10条线程并发上传 上传完毕以后在服务器里面进行合并 果不其然 上传速度的确上去了 也可以达到每秒8M/s了

我想问的是 关于libssh2库上传文件限速的事 必须开多线程才可以吗 这个问题是库本身的问题还是协议的问题啊

上代码吧



//========================================================================================================================
//= 功能:上传文件 =======================================================================================================
//========================================================================================================================

LRESULT SFTP_PostFile(LPWSTR hostname,LPWSTR port,LPWSTR username,LPWSTR password,LPWSTR filename,LPWSTR savefile){


    WSADATA wsadata = { 0 };
    SOCKET sock = { 0 };
    sockaddr_in addr = { 0 };
    hostent * host = { 0 };
    LIBSSH2_SESSION * session = { 0 };
    LIBSSH2_SFTP * sftp = { 0 };
    LIBSSH2_SFTP_HANDLE * sftpfile = { 0 };
    CHAR szHostname[128] = { 0 };
    CHAR szUsername[128] = { 0 };
    CHAR szPassword[128] = { 0 };
    CHAR szFilename[128] = { 0 };
    FILE * file = { 0 };
    CHAR buffer[30000 * 2] = { 0 };//libssh2_sftp_write函数每次最大只能写入30000字节 设置太大是没用的

    /* 初始化库 */
    WSAStartup(MAKEWORD(2, 0), &wsadata);

    /* 转码 */
    WideCharToMultiByte(CP_UTF8,0,hostname,-1,szHostname,sizeof(szHostname),0,0);
    WideCharToMultiByte(CP_UTF8,0,username,-1,szUsername,sizeof(szUsername),0,0);
    WideCharToMultiByte(CP_UTF8,0,password,-1,szPassword,sizeof(szPassword),0,0);
    WideCharToMultiByte(CP_UTF8,0,filename,-1,szFilename,sizeof(szFilename),0,0);
    
    /* 初始化 */
    if(libssh2_init(0) != 0) {

        return FALSE;
    }
    
    /* 设置信息 */
    sock = socket(AF_INET,SOCK_STREAM,0);
    addr.sin_family = AF_INET;
    addr.sin_port = htons((short)wcstol(port,0,NULL));
    host = gethostbyname(szHostname);
    memcpy(&addr.sin_addr.S_un.S_addr,host->h_addr_list[0],host->h_length);
    
    /* 连接服务器 */
    if(connect(sock,(struct sockaddr*)(&addr),sizeof(struct sockaddr_in)) != 0) {

        return FALSE;
    }
 
    /* 初始化SSH */
    if(!(session = libssh2_session_init())){

        closesocket(sock);

        return FALSE;
    
    }
    
    /* 堵塞模式 */
    libssh2_session_set_blocking(session,1);

    /* 套接字与ssh绑定 */
    if(libssh2_session_handshake(session,sock)){

        libssh2_session_disconnect(session,"Normal Shutdown");
        libssh2_session_free(session);
        libssh2_exit();
        closesocket(sock);

        return FALSE;

    }

    /* 验证密码 */    
    if(libssh2_userauth_password(session,szUsername,szPassword)){
           
        libssh2_session_disconnect(session,"Normal Shutdown");
        libssh2_session_free(session);
        libssh2_exit();
        closesocket(sock);

        return FALSE;

    }

    /* sftp初始化 */
    if(!(sftp = libssh2_sftp_init(session))){

        libssh2_session_disconnect(session,"Normal Shutdown");
        libssh2_session_free(session);
        libssh2_exit();
        closesocket(sock);
        return FALSE;
    }

    /* 打开文件 */
    if(!(sftpfile = libssh2_sftp_open(sftp,szFilename,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))) {

        libssh2_sftp_shutdown(sftp);
        libssh2_session_disconnect(session,"Normal Shutdown");
        libssh2_session_free(session);
        libssh2_exit();
        closesocket(sock);
        return FALSE;

    }

    /* 打开文件 */
    file = _wfopen(savefile, L"rb");


    /* 上传数据 */
    while (TRUE){
        
        int nread = fread(buffer,1,sizeof(buffer),file);

        if(nread <= 0) {

            break;
        }

        for(char * ptr = buffer;nread;){

             //发现个问题 这个函数最高只能写入30000字节数据 所以调太大是没用的 后来还发现如果缓冲区设成30000 上传速度也会变慢
// 必须高于30000的2倍数 所以 我设置成了2倍
            int len = libssh2_sftp_write(sftpfile,ptr,nread);

            if(len < 0)
                break;

            ptr += len;
            nread -= len;
        }
 
    }
 

 
    /* 关闭句柄 */
    fclose(file);
    libssh2_sftp_close(sftpfile);
    libssh2_sftp_shutdown(sftp);
    libssh2_session_disconnect(session,"Normal Shutdown");
    libssh2_session_free(session);
    libssh2_exit();
    closesocket(sock);

    return TRUE;

}

  • 写回答

0条回答 默认 最新

    报告相同问题?

    问题事件

    • 系统已结题 5月19日
    • 创建了问题 5月11日

    悬赏问题

    • ¥15 gg加速器加速游戏时,提示不是x86架构
    • ¥15 python按要求编写程序
    • ¥15 Python输入字符串转化为列表排序具体见图,严格按照输入
    • ¥20 XP系统在重新启动后进不去桌面,一直黑屏。
    • ¥15 opencv图像处理,需要四个处理结果图
    • ¥15 无线移动边缘计算系统中的系统模型
    • ¥15 深度学习中的画图问题
    • ¥15 java报错:使用mybatis plus查询一个只返回一条数据的sql,却报错返回了1000多条
    • ¥15 Python报错怎么解决
    • ¥15 simulink如何调用DLL文件