zoukankan      html  css  js  c++  java
  • 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响应一句话
    	}
    
    如在控制台看到下面測试结果。则表明訪问成功:

    服务端:


    client:




  • 相关阅读:
    造轮子杂记2
    Net分布式系统之五:微服务架构
    C#设计模式:责任链模式
    NET Core1.0之CentOS平台开发控制台程序DEMO
    WCF Routing 服务
    设计模式之外观模式
    设计模式之简单工厂模式
    Eclipse快捷键总结
    Spring容器的初始化流程
    IOC容器的创建
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5088467.html
Copyright © 2011-2022 走看看