由于在arm环境使用。需要交叉编译如下库:
- zlib
- openssl
- libssh2
- libcurl
编译zlib和openssl网上很多
编译libssh2
–with-zlib 填写交叉编译zlib时的安装路径,否则交叉编译可能失败【错误 recv check failed】
./configure CC=/host/gcc-linaro-6.5.0-2018.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc --host=arm-linux --with-crypto=openssl --with-libssl-prefix=/host/aarch64_install_6.3.1 CXX=/host/gcc-linaro-6.5.0-2018.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-g++ --with-crypto-prefix=/host/aarch64_install_6.3.1–with-zlib=/host/aarch64_install_6.3.1
编译libccurl:
–with-libssh2 指定 libssh2的安装路径,这里填写上一步编译libssh时设置的安装路径
./configure --prefix=/host/aarch64_install_6.3.1/ --host=aarch64-linux-gnu CC=/host/cross_compile/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc --enable-shared --with-libssh2=/host/aarch64_install_6.3.1/
使用
网上很多使用fopen上传文件。这里和我们需求不太一样。我们需要把JPG图像的内存buffer数据传到SFTP服务器。
定义结构体,用来标识当前传输数据位置:
struct BUFF{
uint8_t *data = nullptr;
size_t length;
size_t offset = 0;
};
size_t readfunc_ptr(void *ptr, size_t size, size_t nmemb, void *stream)
{
BUFF* buf = (BUFF*)stream;
printf("offset:%ld size:%ld,nmemb:%ld
",buf->offset,size,nmemb);
auto max_value = size *nmemb;
size_t cp_size = min(max_value,buf->length-buf->offset);
//分段发送时,记录以及发送的数据长度,从上次的位置继续发送
memcpy(ptr,buf->data + buf->offset,cp_size);
buf->offset+=cp_size;
return cp_size;
}
bool UpLoad(uint8_t *data, size_t length) {
CURL *curl;
CURLcode res;
string user = "root";
string passwd;
BUFF *buf = new BUFF;
buf->data = data;
buf->length = length;
curl = curl_easy_init();
printf("curl_easy_init success
");
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, "sftp://192.168.0.11/userdata/x.png");
curl_easy_setopt(curl, CURLOPT_USERPWD, (user + ":" + passwd).c_str());
curl_easy_setopt(curl, CURLOPT_READDATA, buf);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, readfunc_ptr);
curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, 0);
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
curl_easy_setopt(curl, CURLOPT_INFILESIZE, length);
printf("curl_easy_setopt success
");
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
if (CURLE_OK != res) {
fprintf(stdout, "curl told us %d %s
",res, curl_easy_strerror(res));
}
}
delete buf;
curl_global_cleanup();
return true;
}