我们手游要接入uc九游进行测试,要用http向uc那边的sdk 服务器post  json数据。

虽然他们提供了php,java还有c#的服务端demo,但是我们服务器是C++写的,我实在不想中间再转一层。

于是查了一些资料,发现libcurl可以用在c++里用来构造http包,然后json可以用jsoncpp这个开源api来整合,于是就直接开干!

1.下载libcurl http://curl.haxx.se/download/curl-7.40.0.zip

2.下载jsoncpp https://github.com/open-source-parsers/jsoncpp

3.实现一个http线程,接收主线程推送过来的消息,并转化为json数据,并post到目标地址,在回调里获取到返回数据。

具体实现代码

HttpParse.h

  1. #ifndef HttpParse_h__
  2. #define HttpParse_h__
  3.  
  4. #include <curl/curl.h>
  5. #include <string.h>
  6. #include <string>
  7. #include "ConfigHelper.hpp"
  8.  
  9. #include "CodeQueue.hpp"
  10. #include "Thread.hpp"
  11. #include "TypesDefine.hpp"
  12. #include "NowTime.hpp"
  13. #include "StrStream.hpp"
  14.  
  15. using namespace std;
  16. using namespace KylinLib;
  17.  
  18. struct stHttpData
  19. {
  20. enum actiontype
  21. {
  22. uc_login = , // 登陆
  23. uc_recharge = , // 充值
  24. uc_extend = , // 扩展数据
  25. };
  26.  
  27. actiontype action; //动作id,登录?注册?
  28. unsigned int uiUin; //QQ号
  29. int iWorldid; //区id
  30. int iLoginWay; //登录来源
  31. int iChangeValue; //变化值
  32. stHttpData()
  33. {
  34. memset(this,,sizeof(*this) );
  35. }
  36. };
  37.  
  38. class CHTTPParse
  39. {
  40. CCodeQueue* m_pDataQueue;
  41. CURL* m_pCurlHandlder;
  42. public:
  43. //enum {appID = 90010006,};
  44. enum {appID = ,};
  45. CHTTPParse();
  46. ~CHTTPParse();
  47.  
  48. // 增加http数据
  49. void AddOneHttpData(stHttpData::actiontype actType, unsigned int uiUin, int worldID, int changeValue = , int loginWay = );
  50.  
  51. // 发送数据
  52. int ProcessMsgSend();
  53.  
  54. static size_t OnWriteData(void* buffer, size_t size, size_t nmemb, void* lpVoid);
  55.  
  56. private:
  57. // 初始化
  58. void Init();
  59.  
  60. //Curl 初始化
  61. void CurlInit();
  62.  
  63. //UC登录
  64. int UCLogin(const char* szSid, const char* szAccount);
  65.  
  66. //UC充值
  67. int UCRecharge(unsigned int Roleid, int iWorldid, const char* szAccount, int iRechargeNum);
  68.  
  69. //UC扩展数据
  70. int UCSendExtend();
  71.  
  72. //发送数据
  73. int SendHttpPost(const char* url,const char* pData);
  74. };
  75.  
  76. //处理http交互的线程
  77.  
  78. class CHTTPParseThread : public CThread
  79. {
  80. int m_iIsToBeBlocked;
  81.  
  82. public:
  83. CHTTPParseThread();
  84. public:
  85. virtual int PrepareToRun()
  86. {
  87. return ;
  88. }
  89. virtual int Run() ;
  90.  
  91. virtual int IsToBeBlocked()
  92. {
  93. return m_iIsToBeBlocked;
  94. }
  95. void SetBlockedStatus(int iStatus)
  96. {
  97. m_iIsToBeBlocked = iStatus;
  98. }
  99. };
  100.  
  101. #define CHTTPParseMgr CSingleton<CHTTPParse>::Instance()
  102.  
  103. #endif // HttpParse_h__

// HttpParse.cpp

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <sys/socket.h>
  5. #include <netinet/in.h>
  6. #include <arpa/inet.h>
  7. #include <unistd.h>
  8. #include <json/config.h>
  9. #include <json/json.h>
  10.  
  11. #include "HttpParse.hpp"
  12. #include "LogAdapter.hpp"
  13.  
  14. #define LUOPANGAPPID 100658092
  15.  
  16. #define DoSend(host, stat, data) \
  17. CStrStream1024 strHttp; \
  18. strHttp << "http://" \
  19. << host \
  20. << "/" \
  21. << stat; \
  22. return SendHttpPost(strHttp.GetStr(), data);
  23.  
  24. #define InitNet() CurlInit()
  25.  
  26. CHTTPParseThread::CHTTPParseThread()
  27. {
  28. m_iIsToBeBlocked =;
  29. }
  30.  
  31. // 注册 登录 支付
  32. int CHTTPParseThread::Run()
  33. {
  34.  
  35. while(true)
  36. {
  37. if (m_iRunStatus == rt_stopped)
  38. {
  39. break;
  40. }
  41.  
  42. int iNewMsgCount = ;
  43.  
  44. while(true)
  45. {
  46. int iRet = CHTTPParseMgr->ProcessMsgSend();
  47. if (iRet ==)
  48. {
  49. iNewMsgCount++;
  50. }
  51. else
  52. {
  53. break;
  54. }
  55. }
  56.  
  57. if (iNewMsgCount ==)
  58. {
  59. usleep(*); //1毫秒
  60. }
  61.  
  62. }
  63. return ;
  64. }
  65.  
  66. CHTTPParse::CHTTPParse()
  67. {
  68. m_pDataQueue =NULL;
  69. m_pCurlHandlder = NULL;
  70. Init();
  71. }
  72. CHTTPParse::~CHTTPParse()
  73. {
  74. if (m_pCurlHandlder)
  75. {
  76. curl_easy_cleanup(m_pCurlHandlder);
  77. }
  78. curl_global_cleanup();
  79.  
  80. }
  81.  
  82. // 增加上报数据
  83. void CHTTPParse::AddOneHttpData(stHttpData::actiontype actType, unsigned int uiUin, int worldID, int changeValue /* = 0 */, int loginWay /* = 0 */)
  84. {
  85. if (NULL == m_pDataQueue)
  86. {
  87. return;
  88. }
  89. stHttpData lplData;
  90. lplData.action = actType;
  91. lplData.uiUin = uiUin;
  92. lplData.iWorldid = worldID;
  93. lplData.iChangeValue = changeValue;
  94. lplData.iLoginWay = loginWay;
  95. m_pDataQueue->PushOneCode( (const unsigned char*)&lplData,sizeof(lplData) );
  96. }
  97.  
  98. int CHTTPParse::ProcessMsgSend()
  99. {
  100. if (m_pDataQueue)
  101. {
  102. stHttpData stData;
  103. int iCodelen;
  104. m_pDataQueue->PopOneCode((unsigned char*)&stData,sizeof(stData),iCodelen);
  105.  
  106. if ( iCodelen == sizeof(stData) )
  107. {
  108. switch (stData.action)
  109. {
  110. case stHttpData::uc_login: //登录
  111. return UCLogin("test", "account1234");
  112. break;
  113. case stHttpData::uc_recharge: //注册
  114. return UCRecharge(, , "account1234", );
  115. break;
  116. case stHttpData::uc_extend: //扩展
  117. return UCSendExtend();
  118. break;
  119. }
  120. }
  121. else
  122. {
  123. return -;
  124. }
  125. }
  126. return -;
  127. }
  128.  
  129. size_t CHTTPParse::OnWriteData( void* buffer, size_t size, size_t nmemb, void* lpVoid )
  130. {
  131. std::string* str = dynamic_cast<std::string*>((std::string *)lpVoid);
  132. if( NULL == str || NULL == buffer )
  133. {
  134. return -;
  135. }
  136.  
  137. char* pData = (char*)buffer;
  138. str->append(pData, size * nmemb);
  139. return nmemb;
  140. }
  141.  
  142. void CHTTPParse::Init()
  143. {
  144. //创建一个环形缓存队列来进行线程同步
  145. m_pDataQueue = new CCodeQueue(*); //100K足够了吧
  146. if (m_pDataQueue)
  147. {
  148. m_pDataQueue->Initialize();
  149. }
  150.  
  151. InitNet();
  152. }
  153.  
  154. void CHTTPParse::CurlInit()
  155. {
  156. curl_global_init(CURL_GLOBAL_ALL);
  157.  
  158. m_pCurlHandlder = curl_easy_init();
  159. if (m_pCurlHandlder == NULL)
  160. {
  161. TRACESVR( "Failed to create CURL connection\n");
  162. return ;
  163. }
  164. return ;
  165.  
  166. }
  167.  
  168. int CHTTPParse::SendHttpPost(const char* url,const char* pData)
  169. {
  170. CURLcode code;
  171.  
  172. TRACESVR_DEBUG("Http Data[%s]\n",pData);
  173. if (NULL == m_pCurlHandlder)
  174. {
  175. return -;
  176. }
  177. code =curl_easy_setopt(m_pCurlHandlder, CURLOPT_NOSIGNAL, 1L);
  178. if (code !=CURLE_OK)
  179. {
  180. TRACESVR("Failed to set URL [%d]\n", code);
  181. return - ;
  182. }
  183.  
  184. //设置超时
  185. curl_easy_setopt(m_pCurlHandlder, CURLOPT_TIMEOUT, );
  186. //curl_easy_setopt(m_pCurlHandlder, CURLOPT_CONNECTTIMEOUT, 3);
  187.  
  188. //设置method为post
  189. //curl_easy_setopt(m_pCurlHandlder, CURLOPT_POST, 1);
  190. curl_easy_setopt(m_pCurlHandlder, CURLOPT_VERBOSE, 1L);
  191. curl_slist *http_headers = NULL;
  192. http_headers = curl_slist_append(http_headers, "Accept: application/json");
  193. http_headers = curl_slist_append(http_headers, "Content-Type: application/json");
  194. http_headers = curl_slist_append(http_headers, "charsets: utf-8");
  195. curl_easy_setopt(m_pCurlHandlder, CURLOPT_CUSTOMREQUEST, "POST");
  196. code = curl_easy_setopt(m_pCurlHandlder, CURLOPT_HTTPHEADER, http_headers);
  197.  
  198. code = curl_easy_setopt(m_pCurlHandlder, CURLOPT_URL, "http://192.168.1.166/sdkdemo/restful/dispatch.php?do=cp/account.verifySession");
  199. if (code != CURLE_OK)
  200. {
  201. TRACESVR("Failed to set URL [%d]\n", code);
  202. return - ;
  203. }
  204. code =curl_easy_setopt(m_pCurlHandlder, CURLOPT_POSTFIELDS, pData);
  205. if (code != CURLE_OK)
  206. {
  207. TRACESVR("Failed to PostFields=%s, [code=%d]\n",pData, code);
  208. return -;
  209. }
  210. code =curl_easy_setopt(m_pCurlHandlder, CURLOPT_WRITEFUNCTION, CHTTPParse::OnWriteData);
  211. string strResp;
  212. code =curl_easy_setopt(m_pCurlHandlder, CURLOPT_WRITEDATA, (void *)&strResp);
  213. curl_easy_setopt(m_pCurlHandlder, CURLOPT_SSL_VERIFYPEER, false);
  214. curl_easy_setopt(m_pCurlHandlder, CURLOPT_SSL_VERIFYHOST, false);
  215. curl_easy_setopt(m_pCurlHandlder,CURLOPT_FOLLOWLOCATION,);
  216.  
  217. code = curl_easy_perform(m_pCurlHandlder);
  218. if(CURLE_OK == code)
  219. {
  220. char *ct =NULL;
  221.  
  222. code = curl_easy_getinfo(m_pCurlHandlder, CURLINFO_CONTENT_TYPE, &ct);
  223.  
  224. if((CURLE_OK == code) && ct)
  225. {
  226. TRACESVR("We received Content-Type: %s \n", ct);
  227. }
  228. }
  229. else
  230. {
  231. TRACESVR("curl_easy_perform Error\n");
  232. }
  233. curl_easy_cleanup(m_pCurlHandlder);
  234.  
  235. return ;
  236. }
  237.  
  238. int CHTTPParse::UCLogin(const char* szSid, const char* szAccount)
  239. {
  240. Json::Value root;
  241. // id
  242. root["id"] = GETNOWTIMEUS;
  243.  
  244. // service
  245. root["service"] = "account.verifySession";
  246.  
  247. Json::Value gameid;
  248. gameid["gameId"] = ;
  249. root["game"] = gameid;
  250.  
  251. Json::Value sid;
  252. sid["sid"] = "eeeeettttttt555444";
  253. root["data"] = sid;
  254.  
  255. // encrypt
  256. root["encrypt"] = "md5";
  257.  
  258. // sign
  259. root["sign"] = "cce4cef6ea157f411932f9651555836e";
  260.  
  261. Json::FastWriter writer;
  262. std::string strWrite = writer.write(root);
  263.  
  264. DoSend("192.168.1.166", "sdkdemo/restful/dispatch.php?do=cp/account.verifySession", strWrite.c_str());
  265. }
    // 其他函数还没调试,就不贴出来了

注意事项

1.设置http post数据格式和accept格式

  1. http_headers = curl_slist_append(http_headers, "Accept: application/json");
  2. http_headers = curl_slist_append(http_headers, "Content-Type: application/json");

2.json数据如果有问题,会直接报 500 internal server erro 的错误,其实就是json的数据格式不对。最好填充完,用工具检测一下json字符串是否合法

3.jsoncpp中要用 Json::FastWriter将json Value类型格式化,如下代码中的strWrite 就是json格式的字符串(需要post的数据),而不是调用asString()进行转化,后者会导致程序直接崩溃。

  1. Json::FastWriter writer;
  2. std::string strWrite = writer.write(root);

c++利用jsoncpp libcurl 构造http 包(原)的更多相关文章

  1. SSRF攻击-运用gopher协议构造POST包--emmmm(http://10.112.68.215:10004/index.php?action=login)

        还是天枢的一道CTF题,启程!       分析题目,自己注册账户并登陆后,提示输入一个url,网站会自己运行查找网页信息.     emmmmm,很挑衅,网站就当作服务器,我们在url框中输 ...

  2. 利用GBDT模型构造新特征具体方法

    利用GBDT模型构造新特征具体方法 数据挖掘入门与实战  公众号: datadw   实际问题中,可直接用于机器学**模型的特征往往并不多.能否从"混乱"的原始log中挖掘到有用的 ...

  3. 利用VBA+OO4O构造CTAIS开放式通用平台

    利用VBA+OO4O构造CTAIS开放式通用平台 2010-06-08 14:59:28 | 来源:税务信息化论文集 | 作者:于非 易飞 摘  要:文立足于CTAIS系统体系,探讨如何通过OO4O技 ...

  4. 利用Fiddler抓取websocket包

    一.利用fiddler抓取websockt包 打开Fiddler,点开菜单栏的Rules,选择Customize Rules... 这时会打开CustomRules.js文件,在class Handl ...

  5. scapy构造数据包

    一.进入scapy交互界面 在终端下输入:scapy ,进入交互界面: 二.查看scapy已经实现的网络协议 ls() 列出scapy中已实现的网络协议 ls(协议类型) 查看某个协议头部字段格式 l ...

  6. 利用程序随机构造N个已解答的数独棋盘

    高级软件工程第二次作业:利用程序随机构造N个已解答的数独棋盘,代码如下: package SudokuGame; /** * 解决这个问题使用的是回溯+剪枝的算法 * 基本思想:不断地将每个格子可填入 ...

  7. TCP粘包问题的解决方案02——利用readline函数解决粘包问题

      主要内容: 1.read,write 与 recv,send函数. recv函数只能用于套接口IO ssize_t recv(int sockfd,void * buff,size_t len,i ...

  8. JUC包-原子类(AtomicInteger为例)

    目录 JUC包-原子类 为什么需要JUC包中的原子类 原子类原理(AtomicInteger为例) volatile CAS CAS的缺点 ABA问题 什么是ABA问题 ABA问题的解决办法 JUC包 ...

  9. 利用Ant脚本生成war包的详细步骤

    使用ant脚本前的准备 1.下载一个ant安装包.如:apache-ant-1.8.4-bin.zip.解压到E盘. 2.配置环境变量.新增ANT_HOME:E:\apache-ant-1.8.4:P ...

随机推荐

  1. 模拟用户点击弹出新页面不会被浏览器拦截_javascript技巧

    原文:http://www.html5cn.com.cn/article/zxzx/3195.html 相信用过window.open的小伙伴们都遇到过被浏览器拦截导致页面无法弹出的情况:我们换下思路 ...

  2. 011 router backup

    Router>en Router#config t Enter configuration commands, one per line.  End with CNTL/Z. Router(co ...

  3. 获取路由事件的源Source和OriginalSource

    路由事件的消息包括在RoutedEventArgs实例中,该实例有两个属性Source和OriginalSource,都是表示路由事件传递的起点.即事件消息的源头.仅仅只是Source表示的是Logi ...

  4. vbs io file

    <% ''/*******************************二进制文件操作类************************************ ''/*作者:死在水中的鱼(死 ...

  5. java中a++和++a在较复杂的运算中分析

    关于连加和连减:http://blog.csdn.net/ieayoio/article/details/46431843 以下是一段普遍都了解的代码: public static void main ...

  6. 指针数组,数组指针,函数指针,main函数实质,二重指针,函数指针作为參数,泛型函数

     1.指针数组 数组里面的每一个元素都是指针. 指针数组的案比例如以下: 易犯错误: 2.数组指针 归根结底还是指针,仅仅是取*的时候可以取出一整个数组出来. 数组指针:(一个指针指向了数组.一般 ...

  7. 【Silverlight】Bing Maps学习系列(七):使用Bing Maps的图片系统(Tile System)

    [Silverlight]Bing Maps学习系列(七):使用Bing Maps的图片系统(Tile System) 目前包括微软必应地图在内的几乎所有在线电子地图(如:Google Maps等)都 ...

  8. 解决jQuery uploadify在非IE核心浏览器下无法上传

    之前上传了一个通过Flash实现多文件上传,但是在IE正常运行,FireFox 不能正常上传.经过反复研究学习,之所以firefox和360浏览器无法正常运行,是因为FireFox.chrome.36 ...

  9. hdoj--1254--推箱子(bfs好题)

     推箱子 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  10. python 使用.bat文件自动执行

    @echo off title demo cmd "/c activate py36 && cd demo&& python demo_test.py&quo ...