cocos2dx_CurlTest分析
来源:互联网 发布:caffe接口matlab 编辑:程序博客网 时间:2024/06/01 09:21
1.概述
Curl,是一套可以访问各种网络协议服务的API,
官方网站:http://curl.haxx.se
在cocos2d-x-3.10中,你可以在如下目录找到curl.h:
cocos2d-x-3.10/external/curl/include/android/curl
cocos2d-x-3.10/external/curl/include/ios/curl
注意:cocos2dx3.10中的Http连接的底层就是curl实现的,具体请看cocos2dx3.10 lua中的测试用例XMLHttpRequestTest。
2.实例
cocos2d-x提供了curl测试用例,在如下地址:
cocos2d-x-3.10/tests/cpp-tests/Classes/CurlTest
CurlTest.h---------------
#include "cocos2d.h"
#include "../BaseTest.h"
DEFINE_TEST_SUITE(CurlTests);
class CurlTest : public TestCase
{
public:
CREATE_FUNC(CurlTest);
CurlTest();
~CurlTest();
void onTouchesEnded(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event *event);
private:
cocos2d::Label* _label;
};
CurlTest.cpp---------------
#include "platform/CCPlatformConfig.h"
#if (CC_TARGET_PLATFORM != CC_PLATFORM_IOS) && (CC_TARGET_PLATFORM != CC_PLATFORM_ANDROID)
#include "CurlTest.h"
#include "stdio.h"
#include "stdlib.h"
#include "curl/curl.h"
USING_NS_CC;
CurlTests::CurlTests(){
ADD_TEST_CASE(CurlTest);
}
CurlTest::CurlTest(){
auto label = Label::createWithTTF("Curl Test", "fonts/arial.ttf", 28);
addChild(label, 0);
label->setPosition(VisibleRect::center().x, VisibleRect::top().y-50);
auto listener = EventListenerTouchAllAtOnce::create();
listener->onTouchesEnded = CC_CALLBACK_2(CurlTest::onTouchesEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
// create a label to display the tip string
_label = Label::createWithTTF("Touch the screen to connect", "fonts/arial.ttf", 22);
_label->setPosition(VisibleRect::center());
addChild(_label, 0);
_label->retain();
}
//用来保存要发送的数据的结构体
struct MemoryStruct {
char *memory;
size_t size;
};
//写数据
static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp){
size_t realsize = size * nmemb;
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
if(mem != null){ //这里为了防止抛出异常,加了一个判断
mem->memory = (char*)realloc(mem->memory, mem->size + realsize + 1);
if(mem->memory == NULL) {
/* out of memory! */
printf("not enough memory (realloc returned NULL)\n");
return 0;
}
memcpy(&(mem->memory[mem->size]), contents, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
}
return realsize;
}
// the test code is
// http://curl.haxx.se/mail/lib-2009-12/0071.html
void CurlTest::onTouchesEnded(const std::vector<Touch*>& touches, Event *event){
CURL *curl; //首先,使用CURL必须要创建一个CULR指针,它是CURL的全局句柄。
CURLcode res; //这里定义一个CURL库中API的返回值,用于取得API调用的结果。
char buffer[10]; //错误码的缓冲区
struct MemoryStruct chunk;
chunk.memory = (char*)malloc(1); /* will be grown as needed by the realloc above */
chunk.size = 0; /* no data at this point */
//第一步:初始化CURL,取得初始化成功后的CURL指针。
curl = curl_easy_init();
if (curl) {
//第二步,设定我们用此CURL指针来完成的动作。参数一为CURL指针,参数二为相应
//的动作类型枚举,这个枚举值在curl.h中定义,比如本例中的CURLOPT_URL,定义
//为CINIT(URL, OBJECTPOINT, 2),即联接一个网站的HTTP服务。参数三为动作对应
//的数据参数,这里是网站的URL地址。
curl_easy_setopt(curl, CURLOPT_URL, "http://webtest.cocos2d-x.org/curltest");
//code from http://curl.haxx.se/libcurl/c/getinmemory.html
/* we pass our 'chunk' struct to the callback function */
//保存回调函数得到的数据
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
//If we don't provide a write function for curl, it will recieve error code 23 on windows.
//将得到的数据传递到回调函数里
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
//第三步,执行上面设定的动作处理。返回结果放在res中。
res = curl_easy_perform(curl);
/* always cleanup */
//最后一步,清除CURL指针,结束对CURL库的使用。
curl_easy_cleanup(curl);
if (res == 0){ //如果动作处理成功,则显示联结成功,但没有开始接收任何数据。
_label->setString(StringUtils::format("Connect successfully!\n%s", chunk.memory));
}else{ //如果动作处理失败,打印错误码。
sprintf(buffer,"code: %i",res);
_label->setString(buffer);
}
}else {
_label->setString("no curl");
}
}
CurlTest::~CurlTest(){
_label->release(); //对占用的标题文本标签计数器减一。不再继续占用以使它能够正常被释放。
}
#endif
3.函数分析
3.1.curl_easy_perform()
当你调用的时候,libcurl会执行所有的必要动作,当开始上传的时候,它会调用我的回调函数。
程序会尽可能多,尽可能快的的上传数据。回调函数返回写入缓冲区的数据的大小。
返回0的时候就表示上传结束了。
3.2.回调函数
如果你想自己处理得到的数据而不是直接显示在标准输出里,就需要自己写回调函数,如下:
size_t write_data(char *bufptr, size_t size, size_t nitems, void *userp);
bufptr 参数指向一段准备上传数据的缓冲区,nitem是这段缓冲区的大小,userp是一个用户自
定义指针,libcurl不对该指针作任何操作,它只是简单的传递该指针。
可以使用该指针在应用程序与libcurl之间传递信息。
以下函数的chunk就是该指针。
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
3.3.
当你用字符串设置 curl_easy_setopt(),libcurl会复制这个字符串的一个副本,所以你在设
置后不用再保存那个字符串的内存。
使用 CURLOPT_WRITEDATA,libcurl不会处理你所传递的数据。
3.4.显示进度
通过将CURLOPT_NOPROGRESS设置为0开启进度支持。该选项默认值为1。对大多数应用程序,我们
需要提供一个进度显示回调。libcurl会不定期的将当前传输的进度通过回调函数告诉你的程序。
通过CURLOPT_PROGRESSFUNCTION注册该回调函数。
参数clientp是一个用户自定义指针,应用程序通过CURLOPT_PROCESSDATA
属性将该自定义指定传递给libcurl。libcurl对该参数不作任何处理,
只是简单将其传递给回调函数。
curl_easy_setopt(_curl, CURLOPT_PROGRESSFUNCTION, progress_callback);
curl_easy_setopt(_curl, CURLOPT_NOPROGRESS, 0L);
//回调函数原型
int progress_callback(void *clientp,double dltotal,double dlnow,double ultotal,double ulnow);
3.5.
每次执行完curl_easy_perform,licurl会继续保持与服务器的连接。接下来的请求可以使用这
个连接而不必创建新的连接(如果目标主机是同一个的话)。这样可以减少网络开销。
即使连接被释放了,libcurl也会缓存这些连接的会话信息,这样下次再连接到目标主机上时,
就可以使用这些信息,从而减少重新连接所需的时间。
4.curl_easy_perform()返回值说明
CURLE_OK = 0, /* 0 */ 0: no error
CURLE_UNSUPPORTED_PROTOCOL, /* 1 */ 1: unsupported protocol
CURLE_FAILED_INIT, /* 2 */ 2: failed init
CURLE_URL_MALFORMAT, /* 3 */ 3: URL using bad/illegal format or missing URL
CURLE_URL_MALFORMAT_USER, /* 4 - NOT USED */ 4: unknown error
CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ 5: couldn't resolve proxy name
CURLE_COULDNT_RESOLVE_HOST, /* 6 */ 6: couldn't resolve host name
CURLE_COULDNT_CONNECT, /* 7 */ 7: couldn't connect to server
CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */ 8: FTP: weird server reply
CURLE_FTP_ACCESS_DENIED, /* 9 a service was denied by the FTP server 9: FTP: access denied
due to lack of access - when login fails
this is not returned. */
CURLE_FTP_USER_PASSWORD_INCORRECT, /* 10 - NOT USED */ 10: unknown error
CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ 11: FTP: unknown PASS reply
CURLE_FTP_WEIRD_USER_REPLY, /* 12 */ 12: FTP: unknown USER reply
CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ 13: FTP: unknown PASV reply
CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ 14: FTP: unknown 227 response format
CURLE_FTP_CANT_GET_HOST, /* 15 */ 15: FTP: can't figure out the host in the PASV response
CURLE_FTP_CANT_RECONNECT, /* 16 */ 16: FTP: can't connect to server the response code is unknown
CURLE_FTP_COULDNT_SET_BINARY, /* 17 */ 17: FTP: couldn't set binary mode
CURLE_PARTIAL_FILE, /* 18 */ 18: Transferred a partial file
CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ 19: FTP: couldn't retrieve (RETR failed) the specified file
CURLE_FTP_WRITE_ERROR, /* 20 */ 20: FTP: the post-transfer acknowledge response was not OK
CURLE_FTP_QUOTE_ERROR, /* 21 */ 21: FTP: a quote command returned error
CURLE_HTTP_RETURNED_ERROR, /* 22 */ 22: HTTP response code said error
CURLE_WRITE_ERROR, /* 23 */ 23: failed writing received data to disk/application
CURLE_MALFORMAT_USER, /* 24 - NOT USED */ 24: unknown error
CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */ 25: upload failed (at start/before it took off)
CURLE_READ_ERROR, /* 26 - could open/read from file */ 26: failed to open/read local data from file/application
CURLE_OUT_OF_MEMORY, /* 27 */ 27: out of memory
/* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error
instead of a memory allocation error if CURL_DOES_CONVERSIONS
is defined
*/
CURLE_OPERATION_TIMEOUTED, /* 28 - the timeout time was reached */ 28: a timeout was reached
CURLE_FTP_COULDNT_SET_ASCII, /* 29 - TYPE A failed */ 29: FTP could not set ASCII mode (TYPE A)
CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ 30: FTP command PORT failed
CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ 31: FTP command REST failed
CURLE_FTP_COULDNT_GET_SIZE, /* 32 - the SIZE command failed */ 32: FTP command SIZE failed
CURLE_HTTP_RANGE_ERROR, /* 33 - RANGE "command" didn't work */ 33: a range was requested but the server did not deliver it
CURLE_HTTP_POST_ERROR, /* 34 */ 34: internal problem setting up the POST
CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ 35: SSL connect error
CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */ 36: couldn't resume download
CURLE_FILE_COULDNT_READ_FILE, /* 37 */ 37: couldn't read a file:// file
CURLE_LDAP_CANNOT_BIND, /* 38 */ 38: LDAP: cannot bind
CURLE_LDAP_SEARCH_FAILED, /* 39 */ 39: LDAP: search failed
CURLE_LIBRARY_NOT_FOUND, /* 40 */ 40: a required shared library was not found
CURLE_FUNCTION_NOT_FOUND, /* 41 */ 41: a required function in the shared library was not found
CURLE_ABORTED_BY_CALLBACK, /* 42 */ 42: the operation was aborted by an application callback
CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ 43: a libcurl function was given a bad argument
CURLE_BAD_CALLING_ORDER, /* 44 - NOT USED */ 44: unknown error
CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ 45: failed binding local connection end
CURLE_BAD_PASSWORD_ENTERED, /* 46 - NOT USED */ 46: unknown error
CURLE_TOO_MANY_REDIRECTS , /* 47 - catch endless re-direct loops */ 47: number of redirects hit maximum amount
CURLE_UNKNOWN_TELNET_OPTION, /* 48 - User specified an unknown option */ 48: User specified an unknown option
CURLE_TELNET_OPTION_SYNTAX , /* 49 - Malformed telnet option */ 49: Malformed telnet option
CURLE_OBSOLETE, /* 50 - NOT USED */ 50: unknown error
CURLE_SSL_PEER_CERTIFICATE, /* 51 - peer's certificate wasn't ok */ 51: SSL peer certificate was not ok
CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ 52: server returned nothing (no headers, no data)
CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ 53: SSL crypto engine not found
CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as 54: can not set SSL crypto engine as default
default */
CURLE_SEND_ERROR, /* 55 - failed sending network data */ 55: failed sending data to the peer
CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ 56: failure when receiving data from the peer
CURLE_SHARE_IN_USE, /* 57 - share is in use */ 57: share is already in use
CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ 58: problem with the local SSL certificate
CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */ 59: couldn't use specified SSL cipher
CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */ 60: peer certificate cannot be authenticated with known CA certificates
CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized transfer encoding */ 61: Unrecognized HTTP Content-Encoding
CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ 62: Invalid LDAP URL
CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ 63: Maximum file size exceeded
CURLE_FTP_SSL_FAILED, /* 64 - Requested FTP SSL level failed */ 64: Requested FTP SSL level failed
CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind 65: Send failed since rewinding of the data stream failed
that failed */
CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */ 66: failed to initialise SSL crypto engine
CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not 67: FTP: login denied
accepted and we failed to login */
CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */ 68: TFTP: File Not Found
CURLE_TFTP_PERM, /* 69 - permission problem on server */ 69: TFTP: Access Violation
CURLE_TFTP_DISKFULL, /* 70 - out of disk space on server */ 70: TFTP: Disk full or allocation exceeded
CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */ 71: TFTP: Illegal operation
CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ 72: TFTP: Unknown transfer ID
CURLE_TFTP_EXISTS, /* 73 - File already exists */ 73: TFTP: File already exists
CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ 74: TFTP: No such user
CURLE_CONV_FAILED, /* 75 - conversion failed */ 75: conversion failed
CURLE_CONV_REQD, /* 76 - caller must register conversion 76: caller must register CURLOPT_CONV_ callback options
callbacks using curl_easy_setopt options
CURLOPT_CONV_FROM_NETWORK_FUNCTION,
CURLOPT_CONV_TO_NETWORK_FUNCTION, and
CURLOPT_CONV_FROM_UTF8_FUNCTION */
CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing 77: problem with the SSL CA cert (path? access rights?)
or wrong format */
CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */ 78: Remote file not found
CURLE_SSH, /* 79 - error from the SSH layer, somewhat 79: Error in the SSH layer
generic so the error message will be of
interest when this has happened */
CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL 80: Failed to shut down the SSL connection
connection */
0 0
- cocos2dx_CurlTest分析
- 分析
- 分析
- 分析
- 分析
- 分析
- 分析
- 分析
- 分析
- 分析
- 大家帮忙分析分析!
- FFMpeg分析详细分析
- FFMpeg分析详细分析
- core 分析的分析
- 写给自己,分析分析
- FFMpeg分析详细分析
- 图像分析------直方图分析
- 静态分析 - 数据流分析
- JPA学习笔记(14)——查询缓存
- [iOS item-services分发] 企业级账户分发-个人练手记录
- POJ 1386 有向图的欧拉路径
- Swift - 侧滑菜单的实现(样例2:仿QQ,菜单带缩放效果)
- mysql数据库中文乱码解决
- cocos2dx_CurlTest分析
- Maven核心pom.xml详解
- 在Android中如何使用注解取代Enum
- iOS_富文本的图文混排
- uwa内存占用
- C++构造与析构类与类中的指针对象
- JPA学习笔记(15)——关联查询
- 华为手机打开log日志的方法[Android]
- 编译链接问题