C++ C++;libcurl如何使用Sign STOR和REST发送FTP文件
我有一个XML,我想增量上传到ftp服务器 问题是,它不适用于我的附加,因为我必须消除最终标签。比如说 服务器上的文件C++ C++;libcurl如何使用Sign STOR和REST发送FTP文件,c++,rest,ftp,libcurl,C++,Rest,Ftp,Libcurl,我有一个XML,我想增量上传到ftp服务器 问题是,它不适用于我的附加,因为我必须消除最终标签。比如说 服务器上的文件 < xml>< root>< a>ssss< /a>< b>kkkkk< /b>< /root> 我没能用旋度解决这个问题。为了解决这个问题,我用C++创建了一个类来进行上传。我注意到RFC rfc3659第13页的文档 5.5. REST Example Assume that t
< xml>< root>< a>ssss< /a>< b>kkkkk< /b>< /root>
我没能用旋度解决这个问题。为了解决这个问题,我用C++创建了一个类来进行上传。我注意到RFC rfc3659第13页的文档
5.5. REST Example
Assume that the transfer of a largish file has previously been
interrupted after 802816 octets had been received, that the previous
transfer was with TYPE=I, and that it has been verified that the file
on the server has not since changed.
C> TYPE I
S> 200 Type set to I.
C> PORT 127,0,0,1,15,107
S> 200 PORT command successful.
C> REST 802816
S> 350 Restarting at 802816. Send STORE or RETRIEVE
C> RETR cap60.pl198.tar
S> 150 Opening BINARY mode data connection
[...]
S> 226 Transfer complete.
我没有放置RETR,而是放置了一个STOR,它可以正常工作。您所要求的并不是FTP的工作原理。是什么阻止您在上载文件之前简单地截断
标记?否则,您的读取回调必须跟踪它从文件中读取的实际XML数据,并在到达
标记时返回0。当前,我跟踪标签以这种方式进行上载。我认为版本2的linux FTP服务器允许此功能
< xml>< root>< a>ssss< /a>< b>kkkkk< /b>< /root>
----------------------------------------^
size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream) {
curl_off_t nread;
size_t retcode = fread(ptr, size, nmemb, (FILE*) stream);
nread = (curl_off_t) retcode;
fprintf(stderr, "*** We read %" CURL_FORMAT_CURL_OFF_T " bytes from file\n", nread);
return retcode;
}
bool uploadFile(std::string urlFtp, std::string rutaFtp, std::string archivoOrigen, std::string userPassword, long posicion) {
bool resultado = false;
try {
CURL *curl;
CURLcode res;
FILE *hd_src;
struct stat file_info;
curl_off_t fsize;
/* get the file size of the local file */
if (stat(archivoOrigen.c_str(), &file_info)) {
LOGF_ERROR("Couldn't open '%s': %s\n", archivoOrigen.c_str(), strerror(errno));
return false;
}
fsize = (curl_off_t) file_info.st_size;
LOGF_INFO("Local file size: %" CURL_FORMAT_CURL_OFF_T " bytes.\n", fsize);
hd_src = fopen(archivoOrigen.c_str(), "rb"); // get a FILE * of the same file
curl_global_init(CURL_GLOBAL_ALL); // In windows, this will init the winsock stuff
curl = curl_easy_init(); // get a curl handle
if (curl) {
// build a list of commands to pass to libcurl
struct curl_slist *headerlist = NULL;
std::string cadena(rutaFtp);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); // we want to use our own read function
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); // enable uploading
cadena = urlFtp;
cadena.append(rutaFtp);
curl_easy_setopt(curl, CURLOPT_URL, cadena.c_str()); // specify target
curl_easy_setopt(curl, CURLOPT_USERPWD, userPassword.c_str());
if (posicion > 0) {
curl_easy_setopt(curl, CURLOPT_RESUME_FROM, posicion);
}
curl_easy_setopt(curl, CURLOPT_READDATA, hd_src); // now specify which file to upload
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t) fsize);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 15L);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
res = curl_easy_perform(curl); // Now run off and do what you've been told!
if (res != CURLE_OK)
LOGF_ERROR("curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
else
resultado = true;
curl_slist_free_all(headerlist); // clean up the FTP commands list
curl_easy_cleanup(curl);
}
fclose(hd_src); // close the local file
curl_global_cleanup();
} catch (std::exception &e) {
LOGF_ERROR(e.what());
}
return resultado;
}
5.5. REST Example
Assume that the transfer of a largish file has previously been
interrupted after 802816 octets had been received, that the previous
transfer was with TYPE=I, and that it has been verified that the file
on the server has not since changed.
C> TYPE I
S> 200 Type set to I.
C> PORT 127,0,0,1,15,107
S> 200 PORT command successful.
C> REST 802816
S> 350 Restarting at 802816. Send STORE or RETRIEVE
C> RETR cap60.pl198.tar
S> 150 Opening BINARY mode data connection
[...]
S> 226 Transfer complete.