为了自己更好的管理自己写的项目 打算自己写一个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;
}