libcurl上传文件到服务器的几种方式

来源:互联网 发布:手机接收卫星电视软件 编辑:程序博客网 时间:2024/05/16 08:17

提交表单方式

/*************************************************************************** *                                  _   _ ____  _ *  Project                     ___| | | |  _ \| | *                             / __| | | | |_) | | *                            | (__| |_| |  _ <| |___ *                             \___|\___/|_| \_\_____| * * Copyright (C) 1998 - 2015, 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 http://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> * using the multi interface to do a multipart formpost without blocking * </DESC> */#include <stdio.h>#include <string.h>#include <sys/time.h>#include <curl/curl.h>int main(void){  CURL *curl;  CURLM *multi_handle;  int still_running;  struct curl_httppost *formpost=NULL;  struct curl_httppost *lastptr=NULL;  struct curl_slist *headerlist=NULL;  static const char buf[] = "Expect:";  /* Fill in the file upload field. This makes libcurl load data from     the given file name when curl_easy_perform() is called. */  curl_formadd(&formpost,               &lastptr,               CURLFORM_COPYNAME, "sendfile",               CURLFORM_FILE, "postit2.c",               CURLFORM_END);  /* Fill in the filename field */  curl_formadd(&formpost,               &lastptr,               CURLFORM_COPYNAME, "filename",               CURLFORM_COPYCONTENTS, "postit2.c",               CURLFORM_END);  /* Fill in the submit field too, even if this is rarely needed */  curl_formadd(&formpost,               &lastptr,               CURLFORM_COPYNAME, "submit",               CURLFORM_COPYCONTENTS, "send",               CURLFORM_END);  curl = curl_easy_init();  multi_handle = curl_multi_init();  /* initialize custom header list (stating that Expect: 100-continue is not     wanted */  headerlist = curl_slist_append(headerlist, buf);  if(curl && multi_handle) {    /* what URL that receives this POST */    curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.com/upload.cgi");    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);    curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);    curl_multi_add_handle(multi_handle, curl);    curl_multi_perform(multi_handle, &still_running);    do {      struct timeval timeout;      int rc; /* select() return code */      CURLMcode mc; /* curl_multi_fdset() return code */      fd_set fdread;      fd_set fdwrite;      fd_set fdexcep;      int maxfd = -1;      long curl_timeo = -1;      FD_ZERO(&fdread);      FD_ZERO(&fdwrite);      FD_ZERO(&fdexcep);      /* set a suitable timeout to play around with */      timeout.tv_sec = 1;      timeout.tv_usec = 0;      curl_multi_timeout(multi_handle, &curl_timeo);      if(curl_timeo >= 0) {        timeout.tv_sec = curl_timeo / 1000;        if(timeout.tv_sec > 1)          timeout.tv_sec = 1;        else          timeout.tv_usec = (curl_timeo % 1000) * 1000;      }      /* get file descriptors from the transfers */      mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);      if(mc != CURLM_OK)      {        fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);        break;      }      /* On success the value of maxfd is guaranteed to be >= -1. We call         select(maxfd + 1, ...); specially in case of (maxfd == -1) there are         no fds ready yet so we call select(0, ...) --or Sleep() on Windows--         to sleep 100ms, which is the minimum suggested value in the         curl_multi_fdset() doc. */      if(maxfd == -1) {#ifdef _WIN32        Sleep(100);        rc = 0;#else        /* Portable sleep for platforms other than Windows. */        struct timeval wait = { 0, 100 * 1000 }; /* 100ms */        rc = select(0, NULL, NULL, NULL, &wait);#endif      }      else {        /* Note that on some platforms 'timeout' may be modified by select().           If you need access to the original value save a copy beforehand. */        rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);      }      switch(rc) {      case -1:        /* select error */        break;      case 0:      default:        /* timeout or readable/writable sockets */        printf("perform!\n");        curl_multi_perform(multi_handle, &still_running);        printf("running: %d!\n", still_running);        break;      }    } while(still_running);    curl_multi_cleanup(multi_handle);    /* always cleanup */    curl_easy_cleanup(curl);    /* then cleanup the formpost chain */    curl_formfree(formpost);    /* free slist */    curl_slist_free_all (headerlist);  }  return 0;}

put方式

#include <fcntl.h>#include <sys/stat.h>#include <curl/curl.h>/* * This example shows a HTTP PUT operation. PUTs a file given as a command * line argument to the URL also given on the command line. * * This example also uses its own read callback. * * Here's an article on how to setup a PUT handler for Apache: * http://www.apacheweek.com/features/put */static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream){  size_t retcode;  curl_off_t nread;  /* in real-world cases, this would probably get this data differently     as this fread() stuff is exactly what the library already would do     by default internally */  retcode = fread(ptr, size, nmemb, stream);  nread = (curl_off_t)retcode;  fprintf(stderr, "*** We read %" CURL_FORMAT_CURL_OFF_T          " bytes from file\n", nread);  return retcode;}int main(int argc, char **argv){  CURL *curl;  CURLcode res;  FILE * hd_src ;  struct stat file_info;  char *file;  char *url;  if(argc < 3)    return 1;  file= argv[1];  url = argv[2];  /* get the file size of the local file */  stat(file, &file_info);  /* get a FILE * of the same file, could also be made with     fdopen() from the previous descriptor, but hey this is just     an example! */  hd_src = fopen(file, "rb");  /* In windows, this will init the winsock stuff */  curl_global_init(CURL_GLOBAL_ALL);  /* get a curl handle */  curl = curl_easy_init();  if(curl) {    /* we want to use our own read function */    curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);    /* enable uploading */    curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);    /* HTTP PUT please */    curl_easy_setopt(curl, CURLOPT_PUT, 1L);    /* specify target URL, and note that this URL should include a file       name, not only a directory */    curl_easy_setopt(curl, CURLOPT_URL, url);    /* now specify which file to upload */    curl_easy_setopt(curl, CURLOPT_READDATA, hd_src);    /* provide the size of the upload, we specicially typecast the value       to curl_off_t since we must be sure to use the correct data size */    curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,                     (curl_off_t)file_info.st_size);    /* Now run off and do what you've been told! */    res = curl_easy_perform(curl);    /* Check for errors */    if(res != CURLE_OK)      fprintf(stderr, "curl_easy_perform() failed: %s\n",              curl_easy_strerror(res));    /* always cleanup */    curl_easy_cleanup(curl);  }  fclose(hd_src); /* close the local file */  curl_global_cleanup();  return 0;}

直接post二进制流

int dsdAAASetIcon(struct dsdAAA *dsdAAAObject, char *imagePath,                  dsdAAACallBack callback, char *userBuf){    char url[512] = { 0 };    char userp[1024];    int res = AAA_SUCCESS;    char *postContent = NULL;    CURL *curl;    struct curl_slist *slist = NULL;    FILE * file;    struct stat fileInfo;    if (imagePath == NULL || (dsdAAAObject == NULL)        || (callback == NULL) || (userBuf == NULL)) {        dsdl_err("argument can't be empty\n");        return -AAA_ERROR;    }    file = fopen(imagePath, "rb");    if (file == NULL) {        dsdl_err("open file failed\n");        return -AAA_ERROR;    }    stat(imagePath, &fileInfo);// get file size    long fileSize = fileInfo.st_size;    dsdl_debug("文件大小是 = %ld\n", fileSize);    postContent = (char*)malloc(fileSize);    if (postContent == NULL) {        dsdl_err("malloc failed\n");        return -AAA_ERROR;    }    int readCount = fread(postContent, 1, fileSize, file);    if (readCount != fileSize) {        dsdl_err("read file failed\n");        fclose(file);        free(postContent);        return -AAA_ERROR;    }    snprintf(url, sizeof(url), "%s/update_portrait?token=%s",             dsdAAAObject->serverUrl, dsdAAAObject->token);    dsdl_debug("url = %s\n", url);    curl_global_init(CURL_GLOBAL_ALL);    curl = curl_easy_init();    if (curl) {        curl_easy_setopt(curl, CURLOPT_URL, url);        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);        curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl/7.38.0");        slist = curl_slist_append(slist, "Content-Type: image/png");        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);        curl_easy_setopt(curl, CURLOPT_WRITEDATA, userp);        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlCallback);        dsdl_debug("dsdAAAObject->cookie = %s\n", dsdAAAObject->cookie);        curl_easy_setopt(curl, CURLOPT_COOKIELIST, dsdAAAObject->cookie);// 设置cookie        curl_easy_setopt(curl, CURLOPT_POST, 1L);        curl_easy_setopt(curl, CURLOPT_READDATA, file);        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, fileSize);//指定图片大小,否则遇到'\0'就停止了        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postContent);        dsdl_debug("start send file to server\n");        res = curl_easy_perform(curl);        if (res != CURLE_OK) {            dsdl_err("curl_easy_perform() failed: %s\n", curl_easy_strerror(res));            res = -AAA_ERROR;            goto END;        }        curl_easy_cleanup(curl);        callback(userp, userBuf);    }END:    fclose(file);    free(postContent);    curl_global_cleanup();    return res;}
2 0
原创粉丝点击