curl的封装

首先要搭建一个httpserver,这里採用tomcat6为例:

过程:新建一个Servlet,并使用tomcat的默认port号8080监听,最后写一个jsp来測试能否够訪问该server

1)新建一个Serlvet

新建完后增加写下測试代码:

public class TestServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

    /**
     * Default constructor.
     */
    public TestServlet() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setAttribute("test", "test");
		request.getRequestDispatcher("index.jsp").forward(request, response);

	}

}

该Servlet的名字是TestServlet。所以把web.xml中的内容改成下面内容

<?

xml version="1.0" encoding="UTF-8"?

>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>TestServlet</display-name>

  <servlet>
    <servlet-name>TestServlet</servlet-name>
    <servlet-class>com.test.servlet.TestServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>TestServlet</servlet-name>
    <url-pattern>/TestServlet</url-pattern>
  </servlet-mapping>
</web-app>

然后编写一个訪问该Servlet后会跳转的jsp(index.jsp)

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
${test }
</body>
</html>

最后启动server。在浏览器中如输入下面地址:http://localhost:8080/TestServlet/TestServlet,能够看到訪问成功

其次在cocos2d-x项目中封装curl(參考Cocos2d-x高级开发教程,并添加了能够传输多个键值对),代码比較简单,直接在凝视中说明:

头文件:

//单线程发送,会堵塞
class NetworkAdaptor {
public:
	NetworkAdaptor(const string &baseUrl);//构造
	NetworkAdaptor(const char* baseUrl);//构造
	bool sendValueForKey(const char* key, const char* value, string &wirteBackBuffer);//发送一个HTTP请求
	bool sendValueForKey(const map<string, string> &content, string &wirteBackBuffer);//发送一个HTTP请求
private:
	string m_sBaseUrl;//请求的url地址
};
//多线程线程发送
class AsynNetworkAdaptor {
public:
	void sendValueForKeyToUrl(const char* key, const char* value, const string &url, string &wirteBackBuffer);//添加一个HTTP请求
	void sendValueForKeyToUrl(const map<string, string> content, const string &url, string &wirteBackBuffer);//添加一个HTTP请求
	void flushSendRequests();//批量发送HTTP请求

	CC_SYNTHESIZE_READONLY(int, m_iUnfinishedRequest, UnfinishedRequest);//发送的数量
protected:
	struct RequestInfo {//请求信息
		RequestInfo(const map<string, string> &content, const string &url, string &buffer) : content(content), url(url), buffer(buffer){}
		map<string, string> content;//发送内容
		string url;//请求的url地址
		string &buffer;//server回传的内容
	};
	vector<RequestInfo> requests;//请求容器
};

cpp文件:

//将键值对的内容转换成表单格式的内容进行传送
void translate(const map<string, string> &content, string &sendout) {
	sendout = "";
	for(map<string, string>::const_iterator it = content.begin(); it != content.end(); ++it) {
		sendout = sendout + (it->first + "=" + it->second) + "&";
	}
	sendout = sendout.substr(0, sendout.length() - 1);//去掉最后一个&字符
}
//回调函数。一定要返回服务器对应过来的字节大小
size_t writer(char* data, size_t size, size_t number, string* writeData) {
	if(writeData == NULL) {
		return 0;
	}
	writeData->append(data, size * number);
	return size * number;
}

NetworkAdaptor::NetworkAdaptor(const string& baseUrl) {
	this->m_sBaseUrl =  baseUrl;
}
NetworkAdaptor::NetworkAdaptor(const char* baseUrl) {
	this->m_sBaseUrl =  string(baseUrl);
}
bool NetworkAdaptor::sendValueForKey(const char* key, const char* value, string &wirteBackBuffer) {
	map<string, string> content;
	content.insert(make_pair(key, value));
	sendValueForKey(content, wirteBackBuffer);
	return true;
}
bool NetworkAdaptor::sendValueForKey(const map<string, string> &content, string &wirteBackBuffer) {
	CURL* curl = curl_easy_init();//初始化curl
	if(curl) {
		string sendout;
		translate(content, sendout);
		//配置curl的请求參数
		curl_easy_setopt(curl, CURLOPT_URL, m_sBaseUrl.c_str());
		curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
		curl_easy_setopt(curl, CURLOPT_POST, 1);//post方式
		curl_easy_setopt(curl, CURLOPT_POSTFIELDS, sendout.c_str());
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, &wirteBackBuffer);

		int res = curl_easy_perform(curl);
		curl_easy_cleanup(curl);

		if(res == CURLE_OK) {
			CCLog("get data from server : %s", wirteBackBuffer.c_str());
			return true;
		}else {
			CCLog("curl post error");
		}
	}else {
		CCLog("curl init fail");
	}
	return false;
}

void AsynNetworkAdaptor::sendValueForKeyToUrl(const char* key, const char* value, const string &url, string &wirteBackBuffer) {
	map<string, string> content;
	content.insert(make_pair(key, value));
	sendValueForKeyToUrl(content, url, wirteBackBuffer);
}
void AsynNetworkAdaptor::sendValueForKeyToUrl(const map<string, string> content, const string &url, string &wirteBackBuffer) {
	RequestInfo info(content, url, wirteBackBuffer);
	requests.push_back(info);//将请求放到请求容器中
}
void AsynNetworkAdaptor::flushSendRequests() {
	CURLM* curlm = curl_multi_init();
	if(curlm) {
		for(unsigned int i = 0; i < requests.size(); ++i) {//将请求容器中的请求批量发送到服务端
			CURL* curl = curl_easy_init();
			if(curl) {
				string sendout;
				translate(requests[i].content, sendout);
				curl_easy_setopt(curl, CURLOPT_URL, requests[i].url.c_str());
				curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
				curl_easy_setopt(curl, CURLOPT_POST, 1);
				curl_easy_setopt(curl, CURLOPT_POSTFIELDS, sendout.c_str());
				curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
				curl_easy_setopt(curl, CURLOPT_WRITEDATA, &requests[i].buffer);
				int res = curl_easy_perform(curl);

				curl_multi_add_handle(curlm, curl);
				curl_easy_cleanup(curl);

			}else {
				CCLog("curl init fail");
				break;
			}
		}

		CURLMcode curlm_code = CURLM_CALL_MULTI_PERFORM;
		while(CURLM_CALL_MULTI_PERFORM == curlm_code) {
			curlm_code = curl_multi_perform(curlm, &m_iUnfinishedRequest);
		}
		if (curlm_code != CURLM_OK) {
			CCLog("curlm post error");

		}
		curl_multi_cleanup(curlm);
	}else {
		CCLog("curlm init fail");
	}
}

最后写一个測试用例:

	NetworkAdaptor n("http://localhost:8080/TestServlet/TestServlet");
	string v;
	map<string, string> m;
	m.insert(make_pair("name", "myName"));
	m.insert(make_pair("password", "myPassword"));
	n.sendValueForKey(m, v);
	CCLog("%s", v.c_str());

改动server端的代码。使其不跳转。并给client响应一句话

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//request.setAttribute("testt", "test");
		//request.getRequestDispatcher("index.jsp").forward(request, response);
		String name = request.getParameter("name");
		String password = request.getParameter("password");
		System.out.println("name: " + name + " , password: " + password);//输出从client发送过来的内容

		response.getWriter().print("server have get data");//给client响应一句话
	}

如在控制台看到下面測试结果。则表明訪问成功:

服务端:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQva2luZ2FiY2Rl/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >

client:

时间: 2025-01-16 23:04:10

curl的封装的相关文章

php curl函数封装

<?php     /*cURL 是一个利用URL语法规定来传输文件和数据的工具,支持很多协议,如HTTP.FTP.TELNET等.PHP也支持 cURL 库.本文将介绍 cURL 的一些高级特性,以及在PHP中如何运用它.     封装php curl 直接可以使用 */ function curl_post ($url, $postfields = '', $headers = '', $timeout = 20, $file = 0){         $ch = curl_init();

curl类封装

<?php /**   * @author askwei **/   class CURL   {      private $ch;      private $url = "http://www.baidu.com";     private $flag_if_have_run;   //标记exec是否已经运行     private $set_time_out = 20;  //设置curl超时时间     private $cookie_file = "&qu

对curl的封装

http.h #ifndef _HTTP_H_ #define _HTTP_H_ #include <string> #include <set> #include <curl/curl.h> namespace tools { class CCurlWrapper { public: CCurlWrapper (); ~CCurlWrapper (); int PostFile (const std::string& strUrl, const std::st

cocos2dx 3.3rc0 踩坑日记(一)------ 弱联网 Curl

这两天看了视频学习了下弱联网技术,用的是Curl,具体使用方法我就多说了,可以参考官方样例和下面的文章,解释的很清楚. [Curl (libcurl) 开发 之一]Cocos2dx之libcurl(curl_easy)的编程教程(帮助手册)! CURL使用2 我要说的我又踩到一个坑...为什么是又呢...天生就是来踩坑的... 先说下使用之前需要加入curl.h的路径$(EngineRoot)external\curl\include\win32和链接库libcurl_imp.lib 如图所示:

file_get_contents无法请求https连接的解决方法 php开启curl

file_get_contents无法请求https连接的解决方法 方法1: PHP.ini默认配置下,用file_get_contents读取https的链接,就会如下错误: Warning: fopen() [function.fopen]: Unable to find the wrapper "https" - did you forget to enable it when you configured PHP? 解决方案有3:1.windows下的PHP,只需要到php.i

PHP ElasticSearch的使用

系统是Windows server 2003. ElasticSearch是一个基于Lucene的稳定的.分布式.RESTFul的搜索引擎.其实所谓的RestFul就是它提供URL供你调用(建立索引和进行检索),不过直接这样使用实在是太凶残了.所以,它也提供了一系列client包,相当于将curl请求封装了,client包支持的语言包括Java.PHP.Python.Ruby和Perl等等. PHP版的client包叫做elasticsearch-php,可以在Git_hub上下载.地址如下:h

[原创]cocos2dx加载网络图片&amp;异步加载图片

[动机] 之前看到一款卡牌游戏,当你要看全屏高清卡牌的时候,游戏会单独从网络上下载,本地只存了非高清的,这样可以省点包大小,所以我萌生了实现一个读取网络图片的类. [联想] 之前浏览网页的时候经常看到一张图片渐进(由模糊变清晰)的显示,如果在游戏中,诸如像显示高清卡牌的时候,使用有这种方式去显示一张图片,这样的体验应该会稍微好些 [相关知识] png interlaced:png图片在导出的时候是可以选择 interlaced (Adam7)的,这样的存储的png在网页上显示会渐进显示, 这种i

解决file_get_contents无法请求https连接的方法

PHP.ini默认配置下,用file_get_contents读取https的链接,就会报如下错误,本文给出解决方法 错误: Warning: fopen() [function.fopen]: Unable to find the wrapper "https" - did you forget to enable it when you configured PHP? 解决方案有3: 1.windows下的PHP,只需要到php.ini中把extension=php_openssl

cocos2dx获取网络时间(一)

今天在公司的cocos2dx项目中遇到一个需求,需要获取网络时间和系统时间对比,目的是防止用户更改系统时间进行某些非法操作 . 那么cocos2dx怎么来获取网络时间呢 ?我整理的思路如下: (1)由一个web api可以返回当前的网络时间 (2)cocos2dx通过http请求该api获取数据到本地 (3)cocos2dx解析数据得到当前的网络时间 一:首先就需要一个web接口来提供网络时间的数据,我在这里自己搭建一个WCF服务返回需要的数据. 新建WCF服务应用程序 , 项目命名为NetTi