windows vs2005编译libssh2支持sftp
1、编译模块
需要用到4个库:libcurl、libssh2、openssl、zlib
为啥要用libssh2
因为libcurl实现sftp功能依赖libssh2,是对libssh2的封装。
所以也可以直接用libssh2实现sftp。
为啥要用openssl
因为libssh2依赖openssl和zlib
环境:win10,vs2005,curl-7.62.0,libssh2-1.8.0,openssl-1.0.2q,zlib-1.2.11
2、下载源码
下载zlib
链接:https://zlib.net/fossils/
选择zlib-1.2.1.1
下载libcurl
链接: https://curl.haxx.se/download/
我这里选择的版本是curl-7.62.0,
下载libssh2
链接: https://www.libssh2.org/download/
我这里选择的版本是libssh2-1.8.0
下载openssl
链接: https://www.openssl.org/source/old/0.9.x/
我这里选择的版本是openssl-1.0.2q
perl工具
百度网盘链接:https://pan.baidu.com/s/107UTzX-9_vgFPTW93Ec3AA
下载完成后双击安装,安装过程中会自动配置环境变量。
检查perl是否安装成功
安装完成。
NASM工具
下载链接:https://www.nasm.us/pub/nasm/releasebuilds/2.16.01/win64/
选择*.zip格式下载,然后解压到windwos目录,并配置环境变量。
3、准备目录
在源码根目录创建deps目录,里面包含include、lib、bin
C:\Users\0049003505\Desktop\sftp-dll\
|_curl-7.62.0
| |_winbuild
|
|_deps
|_ lib
|_ include
|_ bin
4、编译zlib
(1)打开vs2005命令行窗口
(2)进入zlib-1.2.1.1\根目录 –cd C:\Users\0049003505\Desktop\sftp3\zlib-1.2.1.1
(3)执行
nmake -f win32/Makefile.msc
(4)deps\bin存放zlib1.dll
deps\include存放zconf.h,zlib.h
deps\lib存放zdll.lib(动态库导入),zlib.lib (静态库)
5、编译openssl
(1)进入openssl-1.0.2q\根目录,执行perl Configure VC-WIN32 --prefix=openssl-dll
(2)执行ms\do_nasm
(3)执行nmake -f ms\ntdll.mak
编译结果在out32dll文件夹内,如果编译静态库执行nmake -f ms\nt.mak
出现上述内容编译成功!
(4)执行nmake -f ms\ntdll.mak test
检查结果,提示passed为正常,如果编译静态库执行nmake -f ms\nt.mak test
检查通过~
(5)执行nmake -f ms\ntdll.mak install
将结果out32dll内容复制到步骤2中的目录内并安装,如果编译静态库执行nmake -f ms\nt.mak install
步骤2中openssl-dll为目录DLL目录,用于LIBCURL编译
(6) 将openssl-dll文件夹内的incllude bin lib复制到deps中
6、编译libssh2
(1)进入libssh2-1.8.0\win32,修改config.mk,修改zlib目录及openssl目录为前述编译结果目录
(2)编译
-
第一种编译方法:进入libssh2-1.8.0\根目录,执行
nmake -f NMakefile
,此编译生成DLL,无libssh2.lib -
第二种编译方法:用VS打开libssh2-1.8.0\win32\libssh2.dsp,将zlib,openssl编译结果include及lib目录加入当前项目C++环境内
当前版本选择第二种
(3)复制文件
deps\bin存放libssh2.dll
deps\include存放libssh2.h,libssh2_publickey.h,libssh2_sftp.h
deps\lib存放libssh2.lib
7、编译libcurl
(1)准备上述编译产物
(1)进入curl-7.62.0\winbuild目录
nmake /f Makefile.vc mode=dll VC=8 SSL_PATH=C:\Users\0049003505\Desktop\sftp-dll\deps ZLIB_PATH=C:\Users\0049003505\Desktop\sftp-dll\deps SSH2_PATH=C:\Users\0049003505\Desktop\sftp-dll\deps ENABLE_IDN=no DEBUG=no WITH_SSL=dll WITH_ZLIB=dll WITH_SSH2=dll
将上述路径修改为自己的路径,然后执行编译。
编译ok;
(3)复制文件
如果是以动态库的形式编译,编译后生成的include bin lib 都在 libcurl-vc8-x86-release-dll-ssl-dll-zlib-dll-ssh2-dll-ipv6-sspi
目录
将当前文件夹的内容复制到deps下的include lib bin中
8、创建工程进行测试
(1)在vs2005中创建一个win32的工程
(2)将下列代码复制到main函数中,代码来源也是从libcurl库中复制的ftpget.c示例
(3)修改工程文件所以来的头文件和库文件的路径,依赖库为libcurl.lib
(3)编译运行,就可以发现通过sftp成功下载文件
如果当前测试程序是release编译,注意要将libcurl.dll libeay32.dll libssh2.dll ssleay32.dll zlib1.dll 库文件放在release目录下,否则程序因为缺少动态库文件而无法正常启动
// sftp_test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
/* <DESC>
* Gets a file using an SFTP URL.
* </DESC>
*/
#include <stdio.h>
#include <curl/curl.h>
/* define this to switch off the use of ssh-agent in this program */
#undef DISABLE_SSH_AGENT
/*
* This is an example showing how to get a single file from an SFTP server.
* It delays the actual destination file creation until the first write
* callback so that it won't create an empty file in case the remote file
* doesn't exist or something else fails.
*/
struct FtpFile {
const char *filename;
FILE *stream;
};
static size_t my_fwrite(void *buffer, size_t size, size_t nmemb,
void *stream)
{
struct FtpFile *out = (struct FtpFile *)stream;
if(out && !out->stream) {
/* open file for writing */
out->stream = fopen(out->filename, "wb");
if(!out->stream)
return -1; /* failure, can't open file to write */
}
return fwrite(buffer, size, nmemb, out->stream);
}
int main(void)
{
CURL *curl;
CURLcode res;
struct FtpFile ftpfile = {
"C:\\Users\\0049003505\\Desktop\\sftp_test\\ai.xml", /* name to store the file as if successful */
NULL
};
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if(curl) {
/*
* You better replace the URL with one that works!
*/
curl_easy_setopt(curl, CURLOPT_URL,
"sftp://10.72.55.169:22/v2para/config/ai.xml");
//curl_easy_setopt(curl, CURLOPT_USERPWD, "lanyx:10");
/* Define our callback to get called when there's data to be written */
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
curl_easy_setopt(curl, CURLOPT_USERNAME, "root");
curl_easy_setopt(curl, CURLOPT_PASSWORD, "Zxm10*netviewu");
/* Set a pointer to our struct to pass to the callback */
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
#ifndef DISABLE_SSH_AGENT
/* We activate ssh agent. For this to work you need
to have ssh-agent running (type set | grep SSH_AGENT to check) or
pageant on Windows (there is an icon in systray if so) */
//curl_easy_setopt(curl, CURLOPT_SSH_AUTH_TYPES, CURLSSH_AUTH_AGENT);
curl_easy_setopt(curl, CURLOPT_SSH_AUTH_TYPES, CURLSSH_AUTH_PASSWORD);
//这里一定要选择CURLSSH_AUTH_PASSWORD 默认的CURLSSH_AUTH_AGENT会验证失败~
#endif
/* Switch on full protocol/debug output */
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
if(CURLE_OK != res) {
/* we failed */
fprintf(stderr, "curl told us %d\n", res);
}
}
if(ftpfile.stream)
fclose(ftpfile.stream); /* close the local file */
curl_global_cleanup();
system("pause");
return 0;
}