“写身体失败”CURLOPT_WRITEDATA

时间:2013-05-14 13:04:05

标签: c++ c curl wsdl libcurl

下面的代码是使用wsdl从服务器获取响应,这里问题是curl返回响应但是无法打印它。

错误:

写身体失败 写入数据失败

#include<stdio.h>
#include<string.h>
#include"../include/curl.h"

size_t write_data(void *ptr, size_t size, size_t count, void *stream)
{
      /* ptr - your string variable.
      stream - data chuck you received */

     printf("%.*s", size, (char*)stream);
}


int main()
{
    int res=0,i=0;
    char buffer[4098]="",buff[128]="",buf[256]="",buf7[30]="",buf6[30]="",buf5[30]="";
    char machineid[]="SUBANI";
    char filename1[50]="";
    int refno=0,paymode=0,taxtype=0;
    FILE *fbc;

    memset(filename1,0,sizeof(filename1));
    sprintf(filename1,"/mnt/jffs2/Response_Details1.xml");
    lk_dispclr();
    lk_disptext(1,0,(unsigned char *)"Sending Request",0);
    lk_disptext(2,0,(unsigned char *)"Please Wait",0);
    memset(buffer,0,sizeof(buffer));

    sprintf(buffer,"<?xml version=\"1.0\" encoding=\"utf-8\"?>\
                        <soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:log=\"http://wsdlclassess.application.sims.test.com\">\
                        <soap:Header>\
                        </soap:Header>\
                        <soap:Body>\
                        <log:loginMethod>\
                        <log:loginid>%s</log:loginid>\
                        <log:password>%s</log:password>\
                        </log:loginMethod>\
                        </soap:Body>\
                        </soap:Envelope>","raja","test");


    res=GET_FILE1(buffer,filename1);


    return 0;
}


int GET_FILE1(char *buffer,char *filename)
{
    CURL *curl;
    CURLcode res;
    struct curl_slist *headers = NULL;
    FILE *out_fd = (FILE *) 0;
    char errorbuf[300] = "",tmpbuff[128]="";
    char errmsg[256];
    int Timeout=120;   //Default timeout is = 2 mins
    int buffer_size = 0;
    char urlbuff[256]="";
    char mstr[10240];

    memset(urlbuff,0,sizeof(urlbuff));
        memset(tmpbuff,0,sizeof(tmpbuff));
    buffer_size = strlen(buffer);
         strcpy(tmpbuff,"http://10.10.1.111:8081/test_server/services/application?wsdl");
             tmpbuff[strlen(tmpbuff)]='\0';
    curl = curl_easy_init();
    if(curl)
    {
        out_fd = fopen (filename, "w");
        curl_easy_setopt(curl, CURLOPT_FILE, out_fd);
        printf("%s:Sign-In Request\n", __func__);
        headers = curl_slist_append(headers, "Content-type:application/soap+xml; charset=utf-8; action=\"http://wsdlclassess.application.sims.test.com/loginMethod\"");

        curl_easy_setopt(curl, CURLOPT_URL, tmpbuff);
        curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);

        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);

    curl_easy_setopt(curl, CURLOPT_WRITEDATA, mstr);


        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, buffer_size);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, buffer);

        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, Timeout);
        curl_easy_setopt(curl, CURLOPT_ERRORBUFFER,errmsg);

        printf("The Server%s:Performing Transaction.....\n",__func__);
        res = curl_easy_perform(curl);
        printf("res=after culreasey perform%d\n",res);
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
        printf("\nerrorbuf:%s\n",errmsg);
        fclose(out_fd);
        if(CURLE_OK != res)
        {
            puts("error occured is\n" );
            //ppp_close();
            return -1;
        }
    }

    return 0;
}

1 个答案:

答案 0 :(得分:4)

错误是您没有从函数返回正确的值,实际上您没有返回任何内容。

此外,提供给函数的数据实际上是第一个ptr参数。


我同意documentation不是很清楚,但它说:

  

ptr 指向的数据的大小是大小乘以 nmemb ,它不会是零终止。

上面一行(强调我的)告诉你数据在ptr中,这是文档中提供的函数声明中的第一个参数。

文档表明:

  

返回实际处理的字节数。如果该金额与传递给您的函数的金额不同,它将向库发出错误信号。这将中止转移并返回CURLE_WRITE_ERROR

您没有从函数返回值,因此您有未定义的行为,并返回看似随机的值,导致整个操作失败。要解决此问题,您应该返回size * count

您还使用size打印字符串,该字符串是使用的基础类型的大小(可能是1),您的count变量是CURL读取的字符数。要完全正常工作,不要调用更多未定义的行为(因为数据没有终止),你应该像printf那样调用:

printf("%*.*s", size * count, size * count, ptr);