c++利用jsoncpp libcurl 构造http 包(原)
我们手游要接入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
- #ifndef HttpParse_h__
- #define HttpParse_h__
- #include <curl/curl.h>
- #include <string.h>
- #include <string>
- #include "ConfigHelper.hpp"
- #include "CodeQueue.hpp"
- #include "Thread.hpp"
- #include "TypesDefine.hpp"
- #include "NowTime.hpp"
- #include "StrStream.hpp"
- using namespace std;
- using namespace KylinLib;
- struct stHttpData
- {
- enum actiontype
- {
- uc_login = , // 登陆
- uc_recharge = , // 充值
- uc_extend = , // 扩展数据
- };
- actiontype action; //动作id,登录?注册?
- unsigned int uiUin; //QQ号
- int iWorldid; //区id
- int iLoginWay; //登录来源
- int iChangeValue; //变化值
- stHttpData()
- {
- memset(this,,sizeof(*this) );
- }
- };
- class CHTTPParse
- {
- CCodeQueue* m_pDataQueue;
- CURL* m_pCurlHandlder;
- public:
- //enum {appID = 90010006,};
- enum {appID = ,};
- CHTTPParse();
- ~CHTTPParse();
- // 增加http数据
- void AddOneHttpData(stHttpData::actiontype actType, unsigned int uiUin, int worldID, int changeValue = , int loginWay = );
- // 发送数据
- int ProcessMsgSend();
- static size_t OnWriteData(void* buffer, size_t size, size_t nmemb, void* lpVoid);
- private:
- // 初始化
- void Init();
- //Curl 初始化
- void CurlInit();
- //UC登录
- int UCLogin(const char* szSid, const char* szAccount);
- //UC充值
- int UCRecharge(unsigned int Roleid, int iWorldid, const char* szAccount, int iRechargeNum);
- //UC扩展数据
- int UCSendExtend();
- //发送数据
- int SendHttpPost(const char* url,const char* pData);
- };
- //处理http交互的线程
- class CHTTPParseThread : public CThread
- {
- int m_iIsToBeBlocked;
- public:
- CHTTPParseThread();
- public:
- virtual int PrepareToRun()
- {
- return ;
- }
- virtual int Run() ;
- virtual int IsToBeBlocked()
- {
- return m_iIsToBeBlocked;
- }
- void SetBlockedStatus(int iStatus)
- {
- m_iIsToBeBlocked = iStatus;
- }
- };
- #define CHTTPParseMgr CSingleton<CHTTPParse>::Instance()
- #endif // HttpParse_h__
// HttpParse.cpp
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <unistd.h>
- #include <json/config.h>
- #include <json/json.h>
- #include "HttpParse.hpp"
- #include "LogAdapter.hpp"
- #define LUOPANGAPPID 100658092
- #define DoSend(host, stat, data) \
- CStrStream1024 strHttp; \
- strHttp << "http://" \
- << host \
- << "/" \
- << stat; \
- return SendHttpPost(strHttp.GetStr(), data);
- #define InitNet() CurlInit()
- CHTTPParseThread::CHTTPParseThread()
- {
- m_iIsToBeBlocked =;
- }
- // 注册 登录 支付
- int CHTTPParseThread::Run()
- {
- while(true)
- {
- if (m_iRunStatus == rt_stopped)
- {
- break;
- }
- int iNewMsgCount = ;
- while(true)
- {
- int iRet = CHTTPParseMgr->ProcessMsgSend();
- if (iRet ==)
- {
- iNewMsgCount++;
- }
- else
- {
- break;
- }
- }
- if (iNewMsgCount ==)
- {
- usleep(*); //1毫秒
- }
- }
- return ;
- }
- CHTTPParse::CHTTPParse()
- {
- m_pDataQueue =NULL;
- m_pCurlHandlder = NULL;
- Init();
- }
- CHTTPParse::~CHTTPParse()
- {
- if (m_pCurlHandlder)
- {
- curl_easy_cleanup(m_pCurlHandlder);
- }
- curl_global_cleanup();
- }
- // 增加上报数据
- void CHTTPParse::AddOneHttpData(stHttpData::actiontype actType, unsigned int uiUin, int worldID, int changeValue /* = 0 */, int loginWay /* = 0 */)
- {
- if (NULL == m_pDataQueue)
- {
- return;
- }
- stHttpData lplData;
- lplData.action = actType;
- lplData.uiUin = uiUin;
- lplData.iWorldid = worldID;
- lplData.iChangeValue = changeValue;
- lplData.iLoginWay = loginWay;
- m_pDataQueue->PushOneCode( (const unsigned char*)&lplData,sizeof(lplData) );
- }
- int CHTTPParse::ProcessMsgSend()
- {
- if (m_pDataQueue)
- {
- stHttpData stData;
- int iCodelen;
- m_pDataQueue->PopOneCode((unsigned char*)&stData,sizeof(stData),iCodelen);
- if ( iCodelen == sizeof(stData) )
- {
- switch (stData.action)
- {
- case stHttpData::uc_login: //登录
- return UCLogin("test", "account1234");
- break;
- case stHttpData::uc_recharge: //注册
- return UCRecharge(, , "account1234", );
- break;
- case stHttpData::uc_extend: //扩展
- return UCSendExtend();
- break;
- }
- }
- else
- {
- return -;
- }
- }
- return -;
- }
- size_t CHTTPParse::OnWriteData( void* buffer, size_t size, size_t nmemb, void* lpVoid )
- {
- std::string* str = dynamic_cast<std::string*>((std::string *)lpVoid);
- if( NULL == str || NULL == buffer )
- {
- return -;
- }
- char* pData = (char*)buffer;
- str->append(pData, size * nmemb);
- return nmemb;
- }
- void CHTTPParse::Init()
- {
- //创建一个环形缓存队列来进行线程同步
- m_pDataQueue = new CCodeQueue(*); //100K足够了吧
- if (m_pDataQueue)
- {
- m_pDataQueue->Initialize();
- }
- InitNet();
- }
- void CHTTPParse::CurlInit()
- {
- curl_global_init(CURL_GLOBAL_ALL);
- m_pCurlHandlder = curl_easy_init();
- if (m_pCurlHandlder == NULL)
- {
- TRACESVR( "Failed to create CURL connection\n");
- return ;
- }
- return ;
- }
- int CHTTPParse::SendHttpPost(const char* url,const char* pData)
- {
- CURLcode code;
- TRACESVR_DEBUG("Http Data[%s]\n",pData);
- if (NULL == m_pCurlHandlder)
- {
- return -;
- }
- code =curl_easy_setopt(m_pCurlHandlder, CURLOPT_NOSIGNAL, 1L);
- if (code !=CURLE_OK)
- {
- TRACESVR("Failed to set URL [%d]\n", code);
- return - ;
- }
- //设置超时
- curl_easy_setopt(m_pCurlHandlder, CURLOPT_TIMEOUT, );
- //curl_easy_setopt(m_pCurlHandlder, CURLOPT_CONNECTTIMEOUT, 3);
- //设置method为post
- //curl_easy_setopt(m_pCurlHandlder, CURLOPT_POST, 1);
- curl_easy_setopt(m_pCurlHandlder, CURLOPT_VERBOSE, 1L);
- curl_slist *http_headers = NULL;
- http_headers = curl_slist_append(http_headers, "Accept: application/json");
- http_headers = curl_slist_append(http_headers, "Content-Type: application/json");
- http_headers = curl_slist_append(http_headers, "charsets: utf-8");
- curl_easy_setopt(m_pCurlHandlder, CURLOPT_CUSTOMREQUEST, "POST");
- code = curl_easy_setopt(m_pCurlHandlder, CURLOPT_HTTPHEADER, http_headers);
- code = curl_easy_setopt(m_pCurlHandlder, CURLOPT_URL, "http://192.168.1.166/sdkdemo/restful/dispatch.php?do=cp/account.verifySession");
- if (code != CURLE_OK)
- {
- TRACESVR("Failed to set URL [%d]\n", code);
- return - ;
- }
- code =curl_easy_setopt(m_pCurlHandlder, CURLOPT_POSTFIELDS, pData);
- if (code != CURLE_OK)
- {
- TRACESVR("Failed to PostFields=%s, [code=%d]\n",pData, code);
- return -;
- }
- code =curl_easy_setopt(m_pCurlHandlder, CURLOPT_WRITEFUNCTION, CHTTPParse::OnWriteData);
- string strResp;
- code =curl_easy_setopt(m_pCurlHandlder, CURLOPT_WRITEDATA, (void *)&strResp);
- curl_easy_setopt(m_pCurlHandlder, CURLOPT_SSL_VERIFYPEER, false);
- curl_easy_setopt(m_pCurlHandlder, CURLOPT_SSL_VERIFYHOST, false);
- curl_easy_setopt(m_pCurlHandlder,CURLOPT_FOLLOWLOCATION,);
- code = curl_easy_perform(m_pCurlHandlder);
- if(CURLE_OK == code)
- {
- char *ct =NULL;
- code = curl_easy_getinfo(m_pCurlHandlder, CURLINFO_CONTENT_TYPE, &ct);
- if((CURLE_OK == code) && ct)
- {
- TRACESVR("We received Content-Type: %s \n", ct);
- }
- }
- else
- {
- TRACESVR("curl_easy_perform Error\n");
- }
- curl_easy_cleanup(m_pCurlHandlder);
- return ;
- }
- int CHTTPParse::UCLogin(const char* szSid, const char* szAccount)
- {
- Json::Value root;
- // id
- root["id"] = GETNOWTIMEUS;
- // service
- root["service"] = "account.verifySession";
- Json::Value gameid;
- gameid["gameId"] = ;
- root["game"] = gameid;
- Json::Value sid;
- sid["sid"] = "eeeeettttttt555444";
- root["data"] = sid;
- // encrypt
- root["encrypt"] = "md5";
- // sign
- root["sign"] = "cce4cef6ea157f411932f9651555836e";
- Json::FastWriter writer;
- std::string strWrite = writer.write(root);
- DoSend("192.168.1.166", "sdkdemo/restful/dispatch.php?do=cp/account.verifySession", strWrite.c_str());
- }
// 其他函数还没调试,就不贴出来了
注意事项
1.设置http post数据格式和accept格式
- http_headers = curl_slist_append(http_headers, "Accept: application/json");
- 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()进行转化,后者会导致程序直接崩溃。
- Json::FastWriter writer;
- std::string strWrite = writer.write(root);
c++利用jsoncpp libcurl 构造http 包(原)的更多相关文章
- SSRF攻击-运用gopher协议构造POST包--emmmm(http://10.112.68.215:10004/index.php?action=login)
还是天枢的一道CTF题,启程! 分析题目,自己注册账户并登陆后,提示输入一个url,网站会自己运行查找网页信息. emmmmm,很挑衅,网站就当作服务器,我们在url框中输 ...
- 利用GBDT模型构造新特征具体方法
利用GBDT模型构造新特征具体方法 数据挖掘入门与实战 公众号: datadw 实际问题中,可直接用于机器学**模型的特征往往并不多.能否从"混乱"的原始log中挖掘到有用的 ...
- 利用VBA+OO4O构造CTAIS开放式通用平台
利用VBA+OO4O构造CTAIS开放式通用平台 2010-06-08 14:59:28 | 来源:税务信息化论文集 | 作者:于非 易飞 摘 要:文立足于CTAIS系统体系,探讨如何通过OO4O技 ...
- 利用Fiddler抓取websocket包
一.利用fiddler抓取websockt包 打开Fiddler,点开菜单栏的Rules,选择Customize Rules... 这时会打开CustomRules.js文件,在class Handl ...
- scapy构造数据包
一.进入scapy交互界面 在终端下输入:scapy ,进入交互界面: 二.查看scapy已经实现的网络协议 ls() 列出scapy中已实现的网络协议 ls(协议类型) 查看某个协议头部字段格式 l ...
- 利用程序随机构造N个已解答的数独棋盘
高级软件工程第二次作业:利用程序随机构造N个已解答的数独棋盘,代码如下: package SudokuGame; /** * 解决这个问题使用的是回溯+剪枝的算法 * 基本思想:不断地将每个格子可填入 ...
- TCP粘包问题的解决方案02——利用readline函数解决粘包问题
主要内容: 1.read,write 与 recv,send函数. recv函数只能用于套接口IO ssize_t recv(int sockfd,void * buff,size_t len,i ...
- JUC包-原子类(AtomicInteger为例)
目录 JUC包-原子类 为什么需要JUC包中的原子类 原子类原理(AtomicInteger为例) volatile CAS CAS的缺点 ABA问题 什么是ABA问题 ABA问题的解决办法 JUC包 ...
- 利用Ant脚本生成war包的详细步骤
使用ant脚本前的准备 1.下载一个ant安装包.如:apache-ant-1.8.4-bin.zip.解压到E盘. 2.配置环境变量.新增ANT_HOME:E:\apache-ant-1.8.4:P ...
随机推荐
- 模拟用户点击弹出新页面不会被浏览器拦截_javascript技巧
原文:http://www.html5cn.com.cn/article/zxzx/3195.html 相信用过window.open的小伙伴们都遇到过被浏览器拦截导致页面无法弹出的情况:我们换下思路 ...
- 011 router backup
Router>en Router#config t Enter configuration commands, one per line. End with CNTL/Z. Router(co ...
- 获取路由事件的源Source和OriginalSource
路由事件的消息包括在RoutedEventArgs实例中,该实例有两个属性Source和OriginalSource,都是表示路由事件传递的起点.即事件消息的源头.仅仅只是Source表示的是Logi ...
- vbs io file
<% ''/*******************************二进制文件操作类************************************ ''/*作者:死在水中的鱼(死 ...
- java中a++和++a在较复杂的运算中分析
关于连加和连减:http://blog.csdn.net/ieayoio/article/details/46431843 以下是一段普遍都了解的代码: public static void main ...
- 指针数组,数组指针,函数指针,main函数实质,二重指针,函数指针作为參数,泛型函数
1.指针数组 数组里面的每一个元素都是指针. 指针数组的案比例如以下: 易犯错误: 2.数组指针 归根结底还是指针,仅仅是取*的时候可以取出一整个数组出来. 数组指针:(一个指针指向了数组.一般 ...
- 【Silverlight】Bing Maps学习系列(七):使用Bing Maps的图片系统(Tile System)
[Silverlight]Bing Maps学习系列(七):使用Bing Maps的图片系统(Tile System) 目前包括微软必应地图在内的几乎所有在线电子地图(如:Google Maps等)都 ...
- 解决jQuery uploadify在非IE核心浏览器下无法上传
之前上传了一个通过Flash实现多文件上传,但是在IE正常运行,FireFox 不能正常上传.经过反复研究学习,之所以firefox和360浏览器无法正常运行,是因为FireFox.chrome.36 ...
- hdoj--1254--推箱子(bfs好题)
推箱子 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
- python 使用.bat文件自动执行
@echo off title demo cmd "/c activate py36 && cd demo&& python demo_test.py&quo ...