Cocos2d-X游戏开发之libcurl(六)

时间:2023-02-07 21:27:44


#include <stdio.h>
#include <string.h>

//引入CURL类库
#include <curl/curl.h>
#include <sys/time.h>
#include <unistd.h>

//引入多线程类库
#include <pthread.h>

#include "JsonBox.h"

char *buffer = NULL;

size_t write_data(char *ptr,size_t size,size_t nmemb,void *userData)
{
    static int flag = 1;
    FILE *fp = fopen("/Users/kevin/Desktop/test.text", "a");
    char *data = NULL;
    buffer = ptr;
    data = ptr;

    //strcpy((char *)ptr,(char *)data);
    int writeen = fwrite(ptr, size, nmemb, fp);
    //CCLog("close");
    printf("write_data 第%d次\n",flag++);
    printf("写入字节数量是 %d\n",writeen);
    printf("data**********:%s",data);
    putchar(10);
    printf("*********************************************\n");
    fclose(fp);
    return written;
}

int main(int argc, const char * argv[])
{
    char *serverIP = "http://192.168.1.112/jforum?module=shoot&action=start";
    char *serverIP2 = "http://weather.china.xappengine.com/api?city=beijing";
    char *serverIP3 = "http://192.168.1.105/jforum?module=shoot&action=start";
    
    //1.同步请求http,并且使用CURLOPT_FOLLOWLOCATION获取返回数据
    /*
    CURL *curl = curl_easy_init();
    CURLcode res;
    
    if (curl) {
        curl_easy_setopt(curl,CURLOPT_URL, "http://esample.com");
        curl_easy_setopt(curl,CURLOPT_FOLLOWLOCATION, 1L);
        res = curl_easy_perform(curl);
     
        if (res != CURLE_OK) {
            fprintf(stderr, "curl_easy_perform() failed:%s\n",curl_easy_strerror(res));
        }
        curl_easy_cleanup(curl);
    
    }*/
    
    //2.使用同步方式向服务器发送数据
    /*CURL *curl;
    CURLcode res;
    const char *postThis = "name=Kevin&passWord=1234";
    curl = curl_easy_init();
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, serverIP2);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postThis);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE,(long)strlen(postThis));
        res = curl_easy_perform(curl);
        printf("%d\n",res);
        if (res==CURLE_COULDNT_CONNECT) {
            printf("连接服务器失败!\n");
        }
        printf("");
        if (res!=CURLE_OK) {
            //如果返回错误,通过此方法输出错误信息
            fprintf(stderr, "curl_easy_perform() failed :%s",curl_easy_strerror(res));
        }
        curl_easy_cleanup(curl);
    }
    putchar(10);*/
    
    //3.https协议的简单请求
    /*CURL *curl;
    //CURLcode  0表示正常
    CURLcode res;
    //全局初始化变量,但不是线程安全,注意使用
    curl_global_init(CURL_GLOBAL_DEFAULT);
    curl =curl_easy_init();
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
        
#ifdef SKIP_PEER_VERIFICATION
        curl_easy_setopt(CURL, CURLOPT_SSL_VERIFYPEER, 0L);
#endif
        
#ifdef SKIP_HOSTNAME_VERIFICATION
        curl_easy_setopt(CURL, CURLOPT_SSL_VERIFYHOST, 0L);
#endif
        res = curl_easy_perform(curl);
        if (res!=CURLE_OK) {
            fprintf(stderr, "failed :%s",curl_easy_strerror(res));
        }
        curl_easy_cleanup(curl);
        
    }
    curl_global_cleanup();*/
    
    //4.异步请求2个http
    /*
    
    CURL *http1,*http2;
    CURLcode res1,res2;
    CURLM *multi;
    int still_running;
    http1 = curl_easy_init();
    http2 = curl_easy_init();
    curl_easy_setopt(http1, CURLOPT_URL, "http://www.example.com");
    curl_easy_setopt(http2, CURLOPT_URL, "http://loaclhost");
    multi = curl_multi_init();
    curl_multi_add_handle(multi, http1);
    curl_multi_add_handle(multi, http2);
    curl_multi_perform(multi, &still_running);
    do {
        struct timeval timeout;
        int rc;
        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);
        timeout.tv_sec = 1;
        timeout.tv_usec = 0;
        curl_multi_timeout(multi, &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;
            }
        }
        curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep,&maxfd);
        rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
        switch (rc) {
            case -1:
                
                break;
                
            default:
                curl_multi_perform(multi, &still_running);
                break;
        }
    } while (still_running);
    curl_multi_cleanup(multi);
    curl_easy_cleanup(http1);
    curl_easy_cleanup(http2);
    
    
    putchar(10);
    printf("Hello, World!\n");
    CURL *curl1;
    curl1 = curl_easy_init();
    curl_easy_setopt(curl1, CURLOPT_URL, "http://www.google.com");
    curl_easy_setopt(curl1, CURLOPT_FOLLOWLOCATION,1L);
    curl_easy_perform(curl1);*/
    
    //5.CURLOPT_POSTFIELDS
    //char *buffer = NULL;
    //char *userName = "my name is Kevin";
    
    CURL *curl5;
    char *data = "name=Kevin&passWord=5678";
    curl5 = curl_easy_init();
    curl_easy_setopt(curl5, CURLOPT_URL, serverIP2);
    //curl_easy_setopt(curl5, CURLOPT_POSTFIELDS, data);
    curl_easy_setopt(curl5, CURLOPT_WRITEFUNCTION, write_data);
    //curl_easy_setopt(curl5, CURLOPT_FOLLOWLOCATION, 1L);
    //curl_easy_setopt(curl5, CURLOPT_PASSWORD,"1234");
    //curl_easy_setopt(curl5, CURLOPT_USERNAME, "kevin");
    //curl_easy_setopt(curl5, CURLOPT_WRITEDATA, &buffer);
    
    curl_easy_perform(curl5);
    curl_easy_cleanup(curl5);
    putchar(10);
    printf("buffer*******:%s\n",buffer);
    
    //printf("userName  %s\n",userName);
    

    //6.json包获取http  get 方法
    /*
     CURLOPT_WRITEFUNCTION
     
     Pass a pointer to a function that matches the following prototype: size_t function( char *ptr, size_t size, size_t nmemb, void *userdata); This function gets called by libcurl as soon as there is data received that needs to be saved. The size of the data pointed to by ptr is size multiplied with nmemb, it will not be zero terminated. Return the number of bytes actually taken care of. If that amount differs from the amount passed to your function, it'll signal an error to the library. This will abort the transfer and return CURLE_WRITE_ERROR.
     
     From 7.18.0, the function can return CURL_WRITEFUNC_PAUSE which then will cause writing to this connection to become paused. See curl_easy_pause(3) for further details.
     
     This function may be called with zero bytes data if the transferred file is empty.
     
     Set this option to NULL to get the internal default function. The internal default function will write the data to the FILE * given with CURLOPT_WRITEDATA.
     
     Set the userdata argument with the CURLOPT_WRITEDATA option.
     
     The callback function will be passed as much data as possible in all invokes, but you cannot possibly make any assumptions. It may be one byte, it may be thousands. The maximum amount of body data that can be passed to the write callback is defined in the curl.h header file: CURL_MAX_WRITE_SIZE (the usual default is 16K). If you however have CURLOPT_HEADER set, which sends header data to the write callback, you can get up to CURL_MAX_HTTP_HEADER bytes of header data passed into it. This usually means 100K.
     
     CURLOPT_WRITEDATA
     
     Data pointer to pass to the file write function. If you use the CURLOPT_WRITEFUNCTION option, this is the pointer you'll get as input. If you don't use a callback, you must pass a 'FILE *' (cast to 'void *') as libcurl will pass this to fwrite() when writing data. By default, the value of this parameter is unspecified.
     
     The internal CURLOPT_WRITEFUNCTION will write the data to the FILE * given with this option, or to stdout if this option hasn't been set.
     
     If you're using libcurl as a win32 DLL, you MUST use the CURLOPT_WRITEFUNCTION if you set this option or you will experience crashes.
     
     This option is also known with the older name CURLOPT_FILE, the name CURLOPT_WRITEDATA was introduced in 7.9.7.
     

     */
    //FILE *fp = fopen("/Users/kevin/Desktop/test.text", "a");
    
    /*CURL *curlJson;
    curlJson = curl_easy_init();
    curl_easy_setopt(curlJson, CURLOPT_URL, serverIP2);
    //设置curl缓存数据为2000字节
    curl_easy_setopt(curlJson, CURLOPT_BUFFERSIZE, 5000);
    curl_easy_setopt(curlJson, CURLOPT_WRITEFUNCTION, write_data);
    int a = curl_easy_perform(curlJson);
    printf("a******  %d\n",a);
    curl_easy_cleanup(curlJson);
    printf("%s\n",buffer);
    putchar(10);*/
    
    
    /*CURL *curl;
    CURLcode res;
    curl = curl_easy_init();
    if (curl)
    {
        curl_easy_setopt(curl, CURLOPT_URL,serverIP2);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
        res = curl_easy_perform(curl);
        
    }
    
    curl_easy_cleanup(curl);*/
    //7.easyHandle向服务器发送表单
    /*CURL *curl = curl_easy_init();
    struct curl_httppost *post = NULL;
    struct curl_httppost *last = NULL;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.1.112/jforum?module=shoot&action=start");
        
        curl_formadd(&post, &last,CURLFORM_COPYNAME,"name",CURLFORM_COPYCONTENTS,"kevin",CURLFORM_END);
        curl_formadd(&post, &last,CURLFORM_COPYNAME,"passsWord",CURLFORM_COPYCONTENTS,"1234",CURLFORM_END);
        curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
        curl_easy_perform(curl);

    }
    curl_easy_cleanup(curl);
    curl_formfree(post);*/
    
    //8.多线程解决请求
    /*CURL *curlJson;
    curlJson = curl_easy_init();
    CURLM *multi;
    int running_handles;
    
    
    
    curl_easy_setopt(curlJson, CURLOPT_URL, serverIP2);
    //curl_easy_setopt(curlJson, CURLOPT_WRITEFUNCTION,write_data);
    //curl_easy_perform(curlJson);
    
    multi = curl_multi_init();
    curl_multi_add_handle(multi, curlJson);
    if (multi) {
        curl_multi_setopt(multi, CURLOPT_WRITEFUNCTION, write_data);
        curl_multi_perform(multi, &running_handles);
    }
    curl_easy_cleanup(curlJson);
    curl_multi_cleanup(multi);
    printf("%s\n",buffer);
    putchar(10);*/
    
    return 0;
    
    
    
}

上面的文章,有时间我会更新,实在是有点杂乱,非常不利于学习。

下面看下Curl访问网络时候,控制台打印输出的详细网络参数。

将下面代码添加就OK

curl_easy_setopt(easyHandle1, CURLOPT_VERBOSE, 1L);

现在看下连接的打印信息:


//ip地址和端口号
* About to connect() to 192.168.1.5 port 80 (#0)
//开始连接
*   Trying 192.168.1.5...
* connected
* Connected to 192.168.1.5 (192.168.1.5) port 80 (#0)
//ip地址后的方法参数
> GET /jforum?module=shoot&action=load HTTP/1.1
//host address
Host: 192.168.1.5
//读取本地的cookie文件
Accept: *
Cookie: jforumUserHash=7b96d4832d66aca47a9e9d11fff1de69; jforumAutoLogin=1; jforumUserId=305; JSESSIONID=09D0FE46A767973E1A1EF89B1D771693.jvm1

//返回状态码200 和ok
< HTTP/1.1 200 OK
* Replaced cookie JSESSIONID="7E0D21DF09402CE07494F8BE33895459.jvm1" for domain 192.168.1.5, path /, expire 0
< Set-Cookie: JSESSIONID=7E0D21DF09402CE07494F8BE33895459.jvm1; Path=/
//utf8编码,文本或者静态网页
< Content-Type: text/html;charset=UTF-8
< Transfer-Encoding: chunked
//时间戳
< Date: Sat, 10 Aug 2013 02:44:43 GMT
//服务器架构
< Server: Apache-Coyote/1.1
<
//打印返回信息
Cocos2d: Network:jsonDataLoad: {"er":0,"zs":0,"fb":2090,"un":"Player_65315","dh":13700,"infoTime":600,"id":305}
0


* Connection #0 to host 192.168.1.5 left intact
//关闭连接
* Closing connection #0