一、建立基本的http通信并得到返回信息

1、创建cocos2dx工程

2、项目引用外部库

如果要使用cocos2dx的CCHttpClient来进行网络访问,则需要引入cocos2dx的相关库,详细步骤如下:

右键单击项目->属性->c/c++->常规,在右边的附件包含目录中添加cocos2dx的extensions目录对应的路径。

然后,右键单击项目->属性->链接器->输入,在右边的附件依赖项中添加libcurl_imp.lib和libExtensions.lib两个库,用分号隔开。

如果不引入extensions文件夹,会出现找不到CCHttpClient的错误;如果不引入libcurl_imp.lib和libExtensions.lib两个库,编译项目时也会出现报错。另外注意引入头文件:

#include "cocos-ext.h"  

3.添加下载按钮和回调函数

CCMenuItemImage *pDownloadItem = CCMenuItemImage::create(
"bt_blue_light.png",
"bt_blue_light.png",
this,
menu_selector(HelloWorld::menuDownloadCallback)
);
CC_BREAK_IF(!pDownloadItem);
CCSize pWinSize = CCDirector::sharedDirector()->getWinSize(); CCMenu* pDownloadMenu = CCMenu::create(pDownloadItem, NULL);
pDownloadMenu->setPosition(ccp( ,));
CC_BREAK_IF(! pDownloadMenu);
this->addChild(pDownloadMenu, );

添加按钮的回调函数:

void HelloWorld::menuDownloadCallback(CCObject* pSender)
{
cocos2d::extension::CCHttpRequest* request = new cocos2d::extension::CCHttpRequest();
request->setUrl("http://www.oschina.net/action/api/news_list");
request->setRequestType(cocos2d::extension::CCHttpRequest::kHttpPost);
std::vector<std::string> headers;
headers.push_back("Content-Type: application/json; charset=utf-8");
request->setHeaders(headers);
const char* postData = "catalog=2&pageIndex=1&pageSize=5";
request->setRequestData(postData ,strlen(postData));
request->setResponseCallback(this, callfuncND_selector(HelloWorld::onHttpRequestCompleted));
request->setTag("Post_My_Data");
cocos2d::extension::CCHttpClient::getInstance()->send(request);
request->release();
}

按钮的回调函数里向服务器发起http请求了,request->setResponseCallback(this, callfuncND_selector(HelloWorld::onHttpRequestCompleted))一行代码,向请求结束时添加了onHttpRequestCompleted回调函数:

4.为http request 结束增加回调函数并读取网络数据

void HelloWorld::onHttpRequestCompleted(cocos2d::CCNode *sender ,void *data)
{
AllocConsole();
freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
cocos2d::extension::CCHttpResponse *response = (cocos2d::extension::CCHttpResponse*)data;
if (!response)
{
return;
}
if ( != strlen(response->getHttpRequest()->getTag()))
{
CCLog("%s completed", response->getHttpRequest()->getTag());
}
int statusCode = response->getResponseCode();
char statusString[] = {};
sprintf(statusString ,"Http status code:%d ,tag = %s" ,statusCode ,response->getHttpRequest()->getTag());
CCLog("response code:%d" ,statusCode);
if (!response->isSucceed())
{
CCLog("response failed");
CCLog("error buffer:%s" ,response->getErrorBuffer());
}
std::vector<char> *buffer = response->getResponseData();
printf("Http response,dump data:");
std::string result = "";
for (unsigned int i = ; i < buffer->size(); i ++)
{
printf("%c" ,(*buffer)[i]);
}
}

debug时就能看到reponse中服务器返回的数据了

注:上面操作遇到的问题

(1) 1>libExtensions.lib(HttpClient.obj) : error LNK2019: 无法解析的外部符号 __imp__pthread_create,该符号在函数 "private: bool __thiscall cocos2d::extension::CCHttpClient::lazyInitThreadSemphore(void)" (?lazyInitThreadSemphore@CCHttpClient@extension@cocos2d@@AAE_NXZ) 中被引用。

解决方法:刚开始这里我是不理解的,因为我以为lib库只需要添加一个libExtensions.lib就行...其实还需要其他俩个lib库文件,pthreadVCE2.lib,libcurl_imp.lib,添加方法(Vs2012):项目属性->链接器->输入->附加依赖项。

(2)error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“0”不匹配值“2”

error:
vtkCommon.lib(vtkSmartPointerBase.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项:值“0”不匹配值“2”(cloudviewer.obj 中)
1>vtkCommon.lib(vtkGarbageCollector.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“0”不匹配值“2”(cloudviewer.obj 中)
1>vtkCommon.lib(vtkDebugLeaksManager.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“0”不匹配值“2”(cloudviewer.obj 中)
 
错误原因是:Debug使用了Release的库文件。
即使你连接库里面两个都添加着呢,但是release库文件放在了debug前面,也是出错的。默认按顺序使用库文件。
类似错误:如release下使用了Debug的库文件,报错类似:
error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”.
解决方法:把Debug模式改为Release模式,编译生成之后,在项目文件夹中运行.exe文件(这里还报了找不到图片资源的错误,把图片资源拷贝到.exe文件同等目录下则可)

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" #include "SimpleAudioEngine.h"
#include "cocos-ext.h" class HelloWorld : public cocos2d::CCLayer
{
public:
// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
virtual bool init(); // there's no 'id' in cpp, so we recommand to return the exactly class pointer
static cocos2d::CCScene* scene(); // a selector callback
void menuCloseCallback(CCObject* pSender); void onHttpRequestCompleted(cocos2d::CCNode *sender ,void *data); // implement the "static node()" method manually
CREATE_FUNC(HelloWorld);
}; #endif // __HELLOWORLD_SCENE_H__
#include "HelloWorldScene.h"

using namespace cocos2d;

CCScene* HelloWorld::scene()
{
CCScene * scene = NULL;
do
{
// 'scene' is an autorelease object
scene = CCScene::create();
CC_BREAK_IF(! scene); // 'layer' is an autorelease object
HelloWorld *layer = HelloWorld::create();
CC_BREAK_IF(! layer); // add layer as a child to scene
scene->addChild(layer);
} while (); // return the scene
return scene;
} // on "init" you need to initialize your instance
bool HelloWorld::init()
{
bool bRet = false;
do
{
//////////////////////////////////////////////////////////////////////////
// super init first
////////////////////////////////////////////////////////////////////////// CC_BREAK_IF(! CCLayer::init()); //////////////////////////////////////////////////////////////////////////
// add your codes below...
////////////////////////////////////////////////////////////////////////// // 1. Add a menu item with "X" image, which is clicked to quit the program. // Create a "close" menu item with close icon, it's an auto release object.
CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
this,
menu_selector(HelloWorld::menuCloseCallback));
CC_BREAK_IF(! pCloseItem); // Place the menu item bottom-right conner.
pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - , )); // Create a menu with the "close" menu item, it's an auto release object.
CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
pMenu->setPosition(CCPointZero);
CC_BREAK_IF(! pMenu); // Add the menu to HelloWorld layer as a child layer.
this->addChild(pMenu, ); // 2. Add a label shows "Hello World". // Create a label and initialize with string "Hello World".
CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Arial", );
CC_BREAK_IF(! pLabel); // Get window size and place the label upper.
CCSize size = CCDirector::sharedDirector()->getWinSize();
pLabel->setPosition(ccp(size.width / , size.height - )); // Add the label to HelloWorld layer as a child layer.
this->addChild(pLabel, ); // 3. Add add a splash screen, show the cocos2d splash image.
CCSprite* pSprite = CCSprite::create("HelloWorld.png");
CC_BREAK_IF(! pSprite); // Place the sprite on the center of the screen
pSprite->setPosition(ccp(size.width/, size.height/)); // Add the sprite to HelloWorld layer as a child layer.
this->addChild(pSprite, ); bRet = true;
} while (); return bRet;
} void HelloWorld::menuCloseCallback(CCObject* pSender)
{
// "close" menu item clicked
//CCDirector::sharedDirector()->end();
cocos2d::extension::CCHttpRequest* request = new cocos2d::extension::CCHttpRequest();
request->setUrl("http://www.oschina.net/action/api/news_list");
request->setRequestType(cocos2d::extension::CCHttpRequest::kHttpPost);
std::vector<std::string> headers;
headers.push_back("Content-Type: application/json; charset=utf-8");
request->setHeaders(headers);
const char* postData = "catalog=2&pageIndex=1&pageSize=5";
request->setRequestData(postData ,strlen(postData));
request->setResponseCallback(this, callfuncND_selector(HelloWorld::onHttpRequestCompleted));
request->setTag("Post_My_Data");
cocos2d::extension::CCHttpClient::getInstance()->send(request);
request->release(); } void HelloWorld::onHttpRequestCompleted(cocos2d::CCNode *sender ,void *data)
{
AllocConsole();
freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
cocos2d::extension::CCHttpResponse *response = (cocos2d::extension::CCHttpResponse*)data;
if (!response)
{
return;
}
if ( != strlen(response->getHttpRequest()->getTag()))
{
CCLog("%s completed", response->getHttpRequest()->getTag());
}
int statusCode = response->getResponseCode();
char statusString[] = {};
sprintf(statusString ,"Http status code:%d ,tag = %s" ,statusCode ,response->getHttpRequest()->getTag());
CCLog("response code:%d" ,statusCode);
if (!response->isSucceed())
{
CCLog("response failed");
CCLog("error buffer:%s" ,response->getErrorBuffer());
}
std::vector<char> *buffer = response->getResponseData();
printf("Http response,dump data:");
std::string result = "";
for (unsigned int i = ; i < buffer->size(); i ++)
{
printf("%c" ,(*buffer)[i]);
}
}

二、使用libjson来解析网络json数据

cocos2d-x游戏引擎核心之十——网络通信的更多相关文章

  1. cocos2d-x游戏引擎核心之十二——3.x新特性

    v3.0 亮点 使用 C++(C++11) 的特性取代了 Objective-C 的特性 优化了 Labels 优化了渲染器(比 v2.2 更快) 新的事件分发机制 物理引擎集成 新的 UI 对象 J ...

  2. cocos2d-x游戏引擎核心(3.x)----事件分发机制之事件从(android,ios,desktop)系统传到cocos2dx的过程浅析

    (一) Android平台下: cocos2dx 版本3.2,先导入一个android工程,然后看下AndroidManifest.xml <application android:label= ...

  3. cocos2d-x游戏引擎核心之十一——并发编程(消息通知中心)

    [续] cocos2d-x游戏引擎核心之八——多线程 这里介绍cocos2d-x的一种消息/数据传递方式,内置的观察者模式,也称消息通知中心,CCNotificationCenter. 虽然引擎没有为 ...

  4. cocos2d-x游戏引擎核心之六——绘图原理和绘图技巧

    一.OpenGL基础 游戏引擎是对底层绘图接口的包装,Cocos2d-x 也一样,它是对不同平台下 OpenGL 的包装.OpenGL 全称为 Open Graphics Library,是一个开放的 ...

  5. cocos2d-x游戏引擎核心之八——多线程

    一.多线程原理 (1)单线程的尴尬 重新回顾下 Cocos2d-x 的并行机制.引擎内部实现了一个庞大的主循环,在每帧之间更新各个精灵的状态.执行动作.调用定时函数等,这些操作之间可以保证严格独立,互 ...

  6. cocos2d-x游戏引擎核心(3.x)----启动渲染流程

    (1) 首先,这里以win32平台下为例子.win32下游戏的启动都是从win32目录下main文件开始的,即是游戏的入口函数,如下: #include "main.h" #inc ...

  7. cocos2d-x游戏引擎核心之九——跨平台

    一.cocos2d-x跨平台 cocos2d-x到底是怎样实现跨平台的呢?这里以Win32和Android为例. 1. 跨平台项目目录结构 先看一下一个项目创建后的目录结构吧!这还是以HelloCpp ...

  8. cocos2d-x游戏引擎核心之七——数据持久化

    一.XML与JSON XML 和 JSON 都是当下流行的数据存储格式,它们的共同特点就是数据明文,十分易于阅读.XML 源自于 SGML,是一种标记性数据描述语言,而 JSON 则是一种轻量级数据交 ...

  9. cocos2d-x游戏引擎核心之四——动作调度机制

    一.动作机制的用法 在深入学习动作机制在 Cocos2d-x 里是如何实现的之前,我们先来学习整套动作机制的用法,先知道怎么用,再深入学习它如何实现,是一个很好很重要的学习方法. (1)基本概念 CC ...

随机推荐

  1. dp之分组背包hdu1712

    题意:有n门课程,和m天时间,完成a[i][j]得到的价值为第i行j列的数字,求最大价值...... 思路:分组背包,就是第n门课程,可以做一天,可以做两天,但它们相斥,你做了一天,就不能再做一天.. ...

  2. javascript publish/subscribe or observer pattern

     定义 定义一对多的对象封装,目标对象状态发生变化,它所有的接受者都会收到通知并做相应的更新. 使用频率:5/5 最高 概要 观察者模式,也就是发布者/订阅者模式,当发布者发布一个通知的时候,订阅者就 ...

  3. ssh 移植记录

    利用buildroot 先编译一个 sshd cd buildroot-2016.05/ make menuconfig Target packages ---> Networking appl ...

  4. 细数JDK里的设计模式<转>

    这也是篇老文了,相信很多人也看过.前面那些废话就不翻译了,直接切入正题吧~ 结构型模式: 适配器模式: 用来把一个接口转化成另一个接口. java.util.Arrays#asList() javax ...

  5. BUS Matrix

    ARM的BUS Matrix就是多主(Core,DMA等).多从(内部RAM,APB,外部总线等)的交联和仲裁.目的是为了提高不同主机访问不同外设情况下的带宽,另外一个就是简化Bus Master的协 ...

  6. 百兆千兆网口100Base-TX/1000Base-T

    100Base-TX快速以太网目前制定的三种有关传输介质的标准之一. 另外两种是100Base-T4,100Base-FX. 100标识传输速率为100Mbit/s. base标识采用基带传输. T代 ...

  7. BusyBox inittab

    # /etc/inittab init(8) configuration for BusyBox## Copyright (C) 1999-2004 by Erik Andersen <ande ...

  8. Hive Tuning(一) 连接策略

    群里共享了一本hive调优的书记,名叫<Hive Tunning>,就忍不住开始看了,也顺便记录一下自己学到的东西,备忘! 首先,这是hive的数据摘要,别问我什么意思,我也没看懂. 好, ...

  9. iOS边练边学--UIScrollView和xib文件实现简单分页+定时器初使用

    一.xib文件构成 二.自定义控件类(xib文件与自定义控件类的文件名字相同,并且将xib文件中父类控件的类名改成自定义控件类的名称) ***********自定义控件类需要的属性********** ...

  10. ★ Maven的坑,tomcat插件6 不能与jdk8一起使用

    Maven 集成Tomcat7插件 maven WEB项目启动没问题访问页面就报错:org.apache.jasper.JasperException: Unable to compile class ...