Cocos2dx之Http

一、网络的基本知识

1、网络层次的划分
      (1)、物理层
          负责将比特流在结点间传输,即负责物理传输。
          该层的协议既与链路有关也与传输介质有关。
          在物理层上所传数据的单位是比特。
          物理层的任务就是透明地传送比特流
      (2)、数据链路层
          负责将IP数据报封装成合适在物理网络上传输的帧格式并传输,或将从物理、网络接收到的帧解封,去除IP数据报交给网络层。在两个相邻结点之间传送数据时,数据链路层将网络层交下来的IP数据报组装成帧(framing),在两个相邻结点间的链路上“透明”地传送帧(frame)中的数据。每一帧包括数据和必要的控制信息(如同步信息、地址信息、差错控制等)。
      (3)、网络层
          负责将数据报文独立地m从信源发送到信宿,主要解决路由选择、拥塞控制和网络互联等问题。网络层负责为分组交换网上的不同主机提供通信服务。在发送数据时,网络层把运输层产生的报文段或用户数据报封装成分组或包进行传送。在TCP/IP体系结构中,由于网络层使用IP协议,因此分组也叫作IP数据报,或简称为数据报。
      (4)、传输层
          负责为信源和信宿提供应用程序进程间的数据传输服务,这一层上主要定义了两个传输协议,传输控制协议TCP和用户数据报协议UDP。运输层的任务就是负责向两个主机中进程之间的通信提供服务。由于一个主机可同时运行多个进程,因此运输层有复用和分用的功能。复用就是多个应用层进程可同时使用下面运输层的服务,分用则是运输层把收到的信息分别交付给上面应用层中的相应的进程。
      (5)、应用层
          应用层是体系结构中的最高层。应用层直接为用户的应用进程提供服务。这里的进程就是指正在运行的程序。支持网络应用,应用协议仅仅是网络应用的一个组成部分,运行在不同主机上的进程则使用应用层协议进行通信。通信的协议主要有:httpftp等。

    2、Http协议
        Http协议(超文本传输协议),是用www服务器传输超文本到本地浏览器的传送协议,它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还能确定传输文档中的哪一部分,及哪部分内容首先显示。
        Http协议是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。Http是无状态的协议。
        Http协议的主要特点:
          (1)支持客户端/服务器模式 
          (2)简单快速。客户端请求服务器是,只需要传递请求方法和路径。 
          (3)灵活,Http准许传输任意类型的数据对象。 
          (4)无连接:每次连接只处理一个请求,服务器处理客户端的请求,并收到客户端的应答后,就会断开连接。 
          (5)无状态:Http协议是无状态的,无状态是指协议对于事物处理没有记忆功能,缺少状态意味着如果后续处理需要前面的信息,则它必须重传,会导致连接接送的数据量增大,但是会减轻服务器的压力。
        Http与Https的区别:
          总的来说Http效率更高Https安全性更高。首先谈谈什么是Https(安全超文本传输协议)它是一个安全通信通道,它基于Http开发,用于在客户计算机和服务器之间交换信息。它使用安全套接字层(SSL)进行信息交换,简单来说它是Http的安全版。它是由Netscape开发并内置于其浏览器中,用于对数据进行压缩和解压操作并返回网络上传送回的结果。Https实际上应用了Netscape的安全套接字层(SSL)作为Http应用层的子层。两者用的端口号也不同Http采用80端口,而Https采用443端口。
        Http的两种数据请求方式:getpost1get把参数数据队列追加到URL中,值和字段相对应,在URL中可以看到。post是通过将表单内的字段与其内容放置在HTML HEADER内一起传输到ACTION属性所指定的URL中,用户看不到。
          (2get传输的数据较小,不能大于2kb。post传输的数据量较大。
          (3get安全性较低,执行效率高;post安全性高,但是执行效率低。包含机密信息,建议采用post方式。做数据查询,建议用get方式。做数据添加或者修改,建议采用post形式。
        返回状态码:
           1xx 表示通知信息的,如请求收到了或正在进行处理
           2xx 表示成功,如接受或知道了。
           3xx 表示重定向,表示要完成请求还必须采取进一步的行动。
           4xx 表示客户的差错,如请求中有错误的语法或不能完成。
           5xx 表示服务器的差错,如服务器失效无法完成请求。
    3、统一资源定位符 URL
           统一资源定位符 URL 是对可以从因特网上得到的资源的位置和访问方法的一种简洁的表示。
           URL 给资源的位置提供一种抽象的识别方法,并用这种方法给资源定位。
           只要能够对资源定位,系统就可以对资源进行各种操作,如存取、更新、替换和查找其属性。
         URL 的一般形式 :
           由以冒号隔开的两大部分组成,并且在 URL 中的字符对大写或小写没有要求。

          <协议>://<主机>:<端口>/<路径>

          其中,协议:http —— 超文本传送协议 HTTP
                    ftp —— 文件传送协议 FTP
               主机:是存放资源的主机在因特网中的域名或IP地址

       使用 HTTP 的 URL 的一般形式:

           http://<主机>:<端口>/<路径> 

          其中,http:是http协议。
               :// :冒号和两个斜线是规定的格式
               <主机> 主机的域名或者ip地址
               <端口> HTTP 的默认端口号是 80,通常可省略
               <路径> 若省略文件的<路径>项,则 URL 就指到因特网上的某个主页(home page)。 
    4、CURL的简单应用(CURL用C开发的)
          curl库是一款免费开源的支持多种协议以及多个平台的通信开发包,它非常适合在cocos2dx中使用,HttpClient的底层就是使用的curl。
          curl工作的一般流程:
              (1)、curl_easy_init    //获取curl工具2)、curl_easy_setopt  //设置一些选项3)、curl_easy_perform //真正开始请求4)、curl_easy_cleanup //清理

二、curl代码示例

  头文件的导入:
  首先,在Xcode中,添加一条头文件搜索路径:  /Users/mac/Desktop/Cocos_work/AngryBirds/cocos2d/external/curl/include/ios
  其中AngryBirds:是工程名;
然后导入头文件:

  #include "curl/curl.h"
  #include "json/rapidjson.h"
  #include "json/document.h"
  #include "json/writer.h"
  #include "json/stringbuffer.h"
  using namespace rapidjson;

  1、curl get方式获取数据:
        CURL *curl;
        CURLcode  res;
        struct MemoryStruct chunk;
        chunk.memory = (char*)malloc(1);
        chunk.size = 0;
        curl = curl_easy_init();
        if (curl)
        {      curl_easy_setopt(curl,CURLOPT_URL,"http://192.168.0.101:8088/ztedu/?action=ztedu.register&name=czj&pwd=1111");                  
curl_easy_setopt(curl,CURLOPT_WRITEDATA,(void*)&chunk);          curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,WritrMemoryCallback);

            res = curl_easy_perform(curl);//启动请求,开始执行
            curl_easy_cleanup(curl);
            if (!res)
            {
                log("%s\n",chunk.memory);//将获取的内容输出,可以看出输出的内容是json格式。
            }
            else
            {
                log("error!\n");
            }
        }
        //接下来可以对json进行解析
        string path = FileUtils::getInstance()->getWritablePath();
        //拼接路径 到path(可读可写)路径之下
        string jsonPath = path + string("charpter3.json");

        if (!FileUtils::getInstance()->isFileExist(jsonPath))//此时在path(可读可写)路径之下还没有charpter.json文件
        {
            string fileContents = chunk.memory;
            FILE* file = fopen(jsonPath.c_str(), "w");
            if (file) {
                fputs(fileContents.c_str(), file);
                fclose(file);
            }
        }

        Document doc;
        string data = FileUtils::getInstance()->getStringFromFile(jsonPath);

        doc.Parse<kParseDefaultFlags>(data.c_str());
        if (doc.HasParseError())
        {
            log("error\r\n");
            return ;
        }
        rapidjson::Value &status = doc["status"];
        rapidjson::Value &message = doc["message"];
        log("文件::status:%d  message:%s \n",status.GetInt(),message.GetString());
  2、curl post方式获取数据:
        CURL *curl;
        CURLcode  res;
        struct MemoryStruct chunk;
        chunk.memory = (char*)malloc(1);
        chunk.size = 0;
        curl = curl_easy_init();
        if (curl)
        {
            curl_easy_setopt(curl,CURLOPT_URL,"http://192.168.0.101:8088/ztedu/?action=ztedu.login");
            curl_easy_setopt(curl,CURLOPT_POSTFIELDS,"&name=zzw&pwd=1993");

curl_easy_setopt(curl,CURLOPT_WRITEDATA,(void*)&chunk);

            res = curl_easy_perform(curl);
            curl_easy_cleanup(curl);
            if (!res)
            {
                log("%s\n",chunk.memory);
            }
            else
            {
                log("error!\n");
            }
        }
   3、回调函数
  struct MemoryStruct{
    char* memory;
    size_t size;
};
static size_t WritrMemoryCallback(void *contents,size_t size,size_t nmemb,void *userp)
{
    //nmemb::个数
    //realloc:重新开辟空间
    //realsize:长度

    size_t realsize = size *nmemb;
    struct MemoryStruct *mem = (struct MemoryStruct*)userp;
    mem->memory = (char*)realloc(mem->memory, mem->size + realsize + 1);
    if (mem->memory == NULL)
    {
        printf("not enough memory (realloc returned NULL)\n");
        return 0;
    }
    //memcpy::将contnts指向的位置开始realsize长度的内容拷贝      到mem->memory[mem->size]中去。

    memcpy(&(mem->memory[mem->size]), contents, realsize);
    mem->size += realsize;
    mem->memory[mem->size] = 0;
    return realsize;
}

三、HttpClient代码示例


   头文件的导入:
#include "json/rapidjson.h"
#include "json/document.h"
#include "json/writer.h"
#include "json/stringbuffer.h"
using namespace rapidjson;
#include "network/HttpRequest.h"
#include "network/HttpResponse.h"
#include "network/HttpCookie.h"
using namespace cocos2d::network;


   1、get方式获取数据:

HttpRequest* request = new(nothrow)HttpRequest();
request->setUrl("http://192.168.0.117:8088/ztedu/?action=ztedu.login&name=lxb&pwd=1994");
request->setRequestType(HttpRequest::Type::GET);
request->setResponseCallback(CC_CALLBACK_2(HttpWork::onHttpRequestCompleted, this));
request->setTag("GET test");
HttpClient::getInstance()->send(request);
request->release();
   2、post方式获取数据:

   HttpRequest* request = new(nothrow)HttpRequest();
   request->setUrl("http://192.168.0.117:8088/ztedu/?action=ztedu.register");
   request->setRequestType(HttpRequest::Type::POST);
   request->setResponseCallback(CC_CALLBACK_2(HttpWork::onHttpRequestCompleted, this));
        //write the post data
  const char* postData = "&name=zzw&pwd=1993";
  request->setRequestData(postData, strlen(postData));
  request->setTag("GET test");
  HttpClient::getInstance()->send(request);
  request->release();
   3、回调函数:

void NetWork::onHttpRequestCompleted(HttpClient *sender,HttpResponse *response)
{
    if (!response)
    {
        return;
    }
    vector<char>*buffer = response->getResponseData();
    char* str = (char*)realloc(str, buffer->size() + 1);

    for (unsigned int i = 0; i<buffer->size(); i++)
    {
        str[i] = (*buffer)[i];
    }
    str[buffer->size()] = '\0';

    //这样获取来的数据存在str中,格式也为json格式。接下来就可以按照上面的方法对json进行解析了。
    Document doc;
    doc.Parse<kParseDefaultFlags>(str);
    if (doc.HasParseError())
    {
        log("error\r\n");
        return ;
    }
    、、、、、、、
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值