2011-10-21 39 views
9

Tôi có ứng dụng nhận dữ liệu qua các yêu cầu HTTP POST. Tôi đang cố gắng sử dụng libcurl để mở yêu cầu cho ứng dụng này, gửi dữ liệu và nhận trả lời từ ứng dụng. Đây là mã tôi có cho đến nay:libcurl HTTPS POST gửi dữ liệu?

int main(void) 
{ 
    CURL *curl; 
    CURLcode res; 

    curl = curl_easy_init(); 
    if(curl) 
    { 
     const int timeout = 30000; 
     char outputmessage[]="VGhpcyBpcyBqdXN0IGEgbWVzc2FnZSwgaXQncyBub3QgdGhlIHJlYWwgdGhpbmc="; 

     curl_easy_setopt(curl, CURLOPT_URL, "https://somehost.com/someapp"); 
     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); 
     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); 
     curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.5"); 
     curl_easy_setopt(curl, CURLOPT_POSTFIELDS, outputmessage); 
     curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(outputmessage)); 
     curl_easy_setopt(curl, CURLOPT_POST, 1L); 
     curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout/1000); 

     res = curl_easy_perform(curl); 
     if(CURLE_OK != res) 
     { 
      printf("Error: %s\n", strerror(res)); 
      return 1; 
     } 

     // now what? 

     // cleanup when done 
     curl_easy_cleanup(curl); 
    } 
    return 0; 
} 

này về cơ bản kết nối đến máy chủ, tôi nhận được một OK trên curl_easy_perform(). Tôi có thể thấy kết nối trên Wireshark.

Hai câu hỏi:

1) này đúng cách gửi dữ liệu thông qua một POST là, và
2) Làm thế nào để nhận được trả lời từ ứng dụng.

Tôi nghĩ tôi cần sử dụng curl_easy_recv() nhưng tôi không thể thấy cách thực hiện. Bất kỳ mã mẫu nào đều được chào đón. Cảm ơn.

Trả lời

4

Tôi nghĩ bạn cũng nên cân nhắc việc thêm một handler cho các tiêu đề phản ứng:

cres = curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, HandleHeader); 

Nó có thể là nếu điều này là một dịch vụ web được thiết kế để ứng dụng sử dụng, câu trả lời của nó là trả lời chỉ tiêu đề, không có dữ liệu phản hồi. Tiêu đề sẽ chứa dữ liệu như:

HTTP/1.1 200 OK ... 

Trong đó điều chính bạn đang tìm kiếm là mã 200 cho biết yêu cầu là OK.

Các chức năng xử lý dữ liệu từ tiêu đề hoặc phản hồi sẽ mất khoảng trống * và bạn sẽ cần phải hủy kết thúc nếu bạn đang sử dụng nó dưới dạng chuỗi. Để biết đây là cách tôi xử lý các dữ liệu đến (trong trường hợp này tôi chỉ sử dụng mã trở lại trong ứng dụng của tôi - cơ quan phản ứng chỉ đi vào một tập tin log):

static size_t CurlHandleResponse(
    void *Ptr, 
    size_t Size, 
    size_t NoElements, 
    void* Data) 
{ 
    memcpy(&(gData[gDataLen]), Ptr, (Size * NoElements)); 
    gDataLen += (Size * NoElements); 
    gData[ gDataLen ] = '\0'; 
    return (Size * NoElements); 
} 

... 
ConvertUnprintable(gData, PrintStr); 
... 

Lỗi xử lý loại bỏ cho ngắn gọn!

+0

Dữ liệu được ứng dụng trả lại nằm ngay sau 200 OK. Tôi cần phải đọc tiêu đề để xem liệu yêu cầu có được chấp nhận hay không, nhưng sau đó là dữ liệu sau nó. Bất kỳ ý tưởng? Và không phải để tập tin nhưng để một char * –

+0

Để biết thông tin, nó phải là một void * ptr, không phải là một char * ptr, nhưng tôi sẽ chỉnh sửa câu trả lời của tôi với mã tôi đang sử dụng để xử lý các phản ứng. – asc99c

+0

OK, cảm ơn. Bây giờ tôi cần phải bắt đầu phân tích tất cả các thông tin. cảm ơn sự giúp đỡ –

1

Bạn không cần gọi bất kỳ chức năng nhận nào. Phản hồi nhận được sẽ trả lại cho bạn khi điều khiển chuyển đến cuộc gọi lại đã hoàn thành. Thiết lập cuộc gọi lại đó như sau:

curl_res = curl_easy_setopt (xử lý, CURLOPT_WRITEFUNCTION, RecvResponseCallback);

trước khi thực hiện cuộc gọi.

Xác định gọi lại như thế này:

size_t 
RecvResponseCallback (char *ptr, size_t size, size_t nmemb, char *data) { 
    // handle received data 
    return size * nmemb; 
} 

Các dữ liệu đáp ứng được trỏ bởi các dữ liệu arg (không các arg ptr, đó là cái gì khác mà bạn sẽ muốn xem xét khi bạn làm việc này).

Khi bạn thoát khỏi RecvResponseCallback, hãy chắc chắn để trở (size_t) size * nmemb

+0

bất kỳ đối số nào cần được khai báo trên RecvResponseCallback() –

+0

Khi đặt và gọi tôi thực hiện, tôi nhận được 'Lỗi: Quá nhiều tệp đang mở trong hệ thống ' –

+0

Hệ thống bạn đang chạy là gì? Tôi nghĩ rằng libcurl phải mở một tập tin khác cho ổ cắm nhận. Vậy bạn có bao nhiêu tệp trong chương trình của mình? –

Các vấn đề liên quan