`
asyty
  • 浏览: 345715 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

HandlerSocket C++客户端 例子

阅读更多

HandlerSocke源码t自带C++客户端的so库以及c++例子(和下面的第一个基本一样),只不过没什么具体的文档介绍,于是给个例子(可以看一下安装包里的协议说明,更容易理解)

 

 

//======================================
// Name        : hsTest.cpp
// Author      : asyty
// Version     :
// Copyright   : Your copyright notice
// Description : hsClient
//======================================

#include<iostream>
#include<handlersocket/hstcpcli.hpp>
#include<handlersocket/string_util.hpp>

using namespace dena;
using namespace std;

int main() {

/*********创建client***********/
	config conf;
	conf["host"] = "127.0.0.1";
	conf["port"] = "9998";

	socket_args sock_args;
	sock_args.set(conf);
	hstcpcli_ptr cli = hstcpcli_i::create(sock_args);

/*******通过索引打开连接	************/
	int code = 0;
	size_t numflds = 0;

 //写请求buffer,column之间除了逗号不允许空格,通过下面的request_send发送请求
							// db name // table // index
	cli->request_buf_open_index(1, "test", "table", "index_1", "colum1,colum2");   

	do {           //发送request_buf_open_index请求
		if (cli->request_send() != 0) {
			fprintf(stderr, "request_send: %s\n", cli->get_error().c_str());
			break;
		}
		if ((code = cli->response_recv(numflds)) != 0) {
			fprintf(stderr, "response_recv: %s\n", cli->get_error().c_str());
			break;
		}
	} while (false);
	cli->response_buf_remove();

/*********获取数据************/
	char key_buf[32] = { 0 };
	uint32_t uid = 2;
	snprintf(key_buf, 32, "%u", uid);
	const string key(key_buf);
	const string_ref keyref(key.data(), key.size());
	const string kTestEqualOp("=");
	const string_ref kTestEqualOpRef(kTestEqualOp.data(), kTestEqualOp.size());

	cli->request_buf_exec_generic(1, kTestEqualOpRef, &keyref, 1, 0, 0, string_ref(), 0, 0);

	do {//发送request_buf_exec_generic
		if (cli->request_send() != 0) {
			fprintf(stderr, "request_send: %s\n", cli->get_error().c_str());
			break;
		}
		if ((code = cli->response_recv(numflds)) != 0) {
			fprintf(stderr, "response_recv: %s\n", cli->get_error().c_str());
			break;
		}

		while (true) {
			const string_ref * const row = cli->get_next_row();
			if (row == 0) {
				break;
			}

			for (size_t i = 0; i < numflds; ++i) {
				const string val(row[i].begin(), row[i].size());
				printf(" %s", val.c_str());
			}
			printf("\n");
		}
	} while (false);

	cli->response_buf_remove();
	cli->close()

	return 0;
}

 

对于多线程的使用,hstcpcli_i这个结构体部分结构如下

 

namespace dena {

struct hstcpcli : public hstcpcli_i, private noncopyable {
  hstcpcli(const socket_args& args);
  virtual void close();
  virtual int reconnect();
              ................
  virtual int request_send();
  virtual int response_recv(size_t& num_flds_r);
              ................
 private:
  int read_more();
  void clear_error();
  int set_error(int code, const std::string& str);
 private:
  auto_file fd;
  socket_args sargs;
  string_buffer readbuf;
  string_buffer writebuf;
  size_t response_end_offset; /* incl newline */
  size_t cur_row_offset;
  size_t num_flds;
  size_t num_req_bufd; /* buffered but not yet sent */
  size_t num_req_sent; /* sent but not yet received */
  size_t num_req_rcvd; /* received but not yet removed */
  int error_code;
  std::string error_str;
  std::vector<string_ref> flds;
};

它其实就是socket客户端,有两个string buffer 一个负责存发送数据 一个负责接收数据,如果多个请求同时发送,接收数据就会各种混乱出错。。。所以 它本身是不支持并发的,除非自己写代码控制并发。。。

 

因此 多线程的操作应该使用不同的hstcpcli,open index时可以使用相同的index_id

 

 

//============================================================================
// Name        : hsMultiTest.cpp
// Author      : asyty
// Version     :
// Copyright   : Your copyright notice
// Description : multithread test
//============================================================================

#include<iostream>
#include<pthread.h>
#include<handlersocket/hstcpcli.hpp>
#include<handlersocket/string_util.hpp>

using namespace dena;
using namespace std;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int pthread_id = 1;

void* cli_thread(void *args) {

	pthread_mutex_lock(&mutex);
	int tid = pthread_id;
	pthread_id++;
	pthread_mutex_unlock(&mutex);

	config conf;
	conf["host"] = "127.0.0.1";
	conf["port"] = "9998";

	socket_args sock_args;
	sock_args.set(conf);
	hstcpcli_ptr cli = hstcpcli_i::create(sock_args);

	int code = 0;
	size_t numflds = 0;
	cli->request_buf_open_index(tid, "test", "table",
			"PRIMARY", "colum2,colum3");
	do {
		if (cli->request_send() != 0) {
			fprintf(stderr, "request_send: %s\n", cli->get_error().c_str());
			cli->close();
			pthread_exit(NULL);
		}
		if ((code = cli->response_recv(numflds)) != 0) {
			fprintf(stderr, "response_recv: %s\n", cli->get_error().c_str());
			cli->close();
			pthread_exit(NULL);
		}
	} while (false);

	cli->response_buf_remove();


	char key_buf[32] = { 0 };
	uint32_t uid = 0;

	const string kTestEqualOp("=");
	const string_ref kTestEqualOpRef(kTestEqualOp.data(), kTestEqualOp.size());

	for (uid = 1000 * tid + 1; uid <= 1000 * tid + 1000; uid++) {
		snprintf(key_buf, 32, "%u", uid);
		const string key(key_buf);
		const string_ref keyref(key.data(), key.size());
		cli->request_buf_exec_generic(tid, kTestEqualOpRef, &keyref, 1, 0, 0,
				string_ref(), 0, 0);

		do {
			if (cli->request_send() != 0) {
				fprintf(stderr, "request_send: %s\n", cli->get_error().c_str());
				break;
			}
			if ((code = cli->response_recv(numflds)) != 0) {
				fprintf(stderr, "response_recv: %s\n",
						cli->get_error().c_str());
				break;
			}

			while (true) {
				const string_ref * const row = cli->get_next_row();
				if (row == 0) {
					break;
				}

				for (size_t i = 0; i < numflds; ++i) {
					const string val(row[i].begin(), row[i].size());
					printf(" %s", val.c_str());
				}
				printf("\n");
			}

		} while (false);
		cli->response_buf_remove();
	}
	cli->close();
}

int main(int argc, char** argv) {

	pthread_t *id;
	int tid, ret, ths;
	struct timeval	start, end;

	if(argc < 2)
		return 0;
	ths = atoi(argv[1]);
	if(ths <= 0)
		return 0;

	id = new pthread_t[ths];

	for (tid = 1; tid <= ths; tid++) {
		ret = pthread_create(&id[tid], NULL, cli_thread, (void*) &tid);
		if (ret != 0) {
			printf("Create pthread error!\n");
		} else {
			printf("create pthread %d\n", tid);
		}
		usleep(1000);
	}
	printf("This is the main process.\n");

	for (tid = 0; tid < ths; tid++) {
		pthread_join(id[tid], NULL);
	}
	delete[] id;
	return 0;
}

 

C++客户端和JAVA客户端(某淘宝人士开发的hs4j)相比,连接延时几乎可以忽略不计,在同样的机器上测试并发,在1000并发数下,java客户端读取性能能飙到15万/秒,C++能达到40万/秒,性能相差还是很大的,只不过hs4j用起来更方便

 

转载请注明源 

http://asyty.iteye.com/blog/1556070

 

 

分享到:
评论
1 楼 执念鱼 2012-11-26  
你好,本人是一个写JAVA的,由于公司项目要求,我现在在用C++有个小问题请教,功能是这样的,用C++自身的库文件编写一个客户端可以给服务器端传递一些信息,感觉对您应该是件简单的事,能否不吝赐教,给个代码,您上面的例子
#include<handlersocket/hstcpcli.hpp> 
#include<handlersocket/string_util.hpp> 
 
using namespace dena; 
我用的就找不到,在此先谢过了

相关推荐

    HSPHP:PHP HandlerSocket客户端

    有关HandlerSocket的更多信息,请查看HandlerSocket上的。安装,请在您的php项目目录中运行以下命令: php composer.phar require tz-lom/hsphp --no-update使用范例选择 $ c = new \ HSPHP \ ReadSocket ();$ c -&gt;...

    MySQL插件HandlerSocket.zip

    HandlerSocket 是MySQL的一个插件,用于跳过MySQL的SQL层面,直接访问内部的InnoDB存储引擎。

    acl-master.zip_ACL库_c++ acl_git acl-master

    acl_cpp 是基于 acl 库的 C++ 库,包括 MIIME 解析、Handlersocket 客户端库、数据库连接池(支持mysql/sqlite)、WEB 编程、数据库编程、阻塞/非阻塞数据流等内容。

    HandlerSocket

    HandlerSocket的应用场景:MySQL自身的局限性,很多站点都采用了MySQL+Memcached的经典架构,甚至一些网站放弃MySQL而采用NoSQL产品,比如Redis/MongoDB等。不可否认,在做一些简单查询(尤其是PK查询)的时候,很多...

    HandlerSocket插件1

    HandlerSocket插件1

    php-handlersocket:一个使用HandlerSocket NoSQL MySQL插件的PECL扩展

    关于HandlerSocket的文档很少。 MySQL插件作者的有一些幻灯片。 日本最大的社交游戏平台的数据库基础设施架构师的博客。 另一篇有关在基于RedHat的系统上安装HandlerSocket并使其运行的博客。 使用此PHP扩展在另...

    HandlerSocket详细介绍

    HandlerSocket详细介绍 mysql和memcached的集合

    MySQL HandlerSocket插件安装配置教程

    一、HandlerSocket是什么?HandlerSocket是akira higuchi写的一个MySQL的插件。以MySQL Daemon Plugin的形式提供类似NoSQL的网络服务,通过这个插件,你可以直接跟MySQL后端的存储引擎做key-value式的交互,省去了...

    php-handlersocket

    PHP调用MySQL插件HandlerSocket,基于kjdev/php-ext-handlersocketi

    mysql-handlersocket-1.0.6-1.DC.1.x86_64

    mysql-handlersocket-1.0.6-1.DC.1.x86_64

    常用开源NoSQL原理与应用 Redis、Hash算法、LSM算法、HandlerSocket、分布式数据库 共35页.ppt

    Redis、Hash算法数据库、LSM算法数据库、HandlerSocket、分布式数据库

    handlersocket-go:一个用于连接HandlerSocket的Go库(github.comahigutiHandlerSocket-Plugin-for-MySQL)

    handlersocket-go 转到用于连接到HandlerSocket Mysql插件的库。 参见github.com/ahiguti/HandlerSocket-Plugin-for-MySQL/ 安装 $ go get github.com/bketelsen/handlersocket-go 阅读示例-最佳示例在TEST文件中。...

    php HandlerSocket的使用

    Memcache数据一致性的问题:当MySQL数据变化后,如果不能及时有效的清理掉过期的数据,就会造成...面对这些问题,HandlerSocket项目是个不错的解决方案,它通过插件的方式赋予MySQL完整的NoSQL功能,从原理上讲,它跳

    acl 框架库-其他

    1、常见网络应用库:SMTP 客户端库/PING 库/memcache 客户端库/handlersocket 客户端库/beanstalk 客户端库 2、HTTP 网络库:HTTP 客户端/服务端库,C++版 HttpServlet 类,HTTP COOKIE/HTTP SESSION 等 3、邮件解析...

    TDH_Socket_Plugin_for_MySQL.zip

    TDH_Socket 是一个MySQL daemon 插件, 类似于HandlerSocket。现在TDH_Socket能接受客户端的TCP请求,并且直接通过MySQL的Handler层访问数据,绕开了SQL解析等一系列逻辑。TDH_Socket的Java客户端可以通过在客户端...

    handlersocket介绍及如何做性能测试

    HandlerSocket是日本人akirahiguchi写的一个MySql的插件。通过这个插件,你可以直接跟MySQL后端的存储引擎做key-value式的交互,省去了MySQL上层的SQL解释、打开关闭表、创建查询计划等CPU开销。按照作者给出的数据...

    MongoDB、HandlerSocket和MySQL性能测试及其结果分析

    共涉及4台测试服务器:机器配置为:安装Webbench1.5,通过Webbench来压Web服务器。Nginx0.8.54+PHP5.3.3(php-fpm),安装有Mongodb和HandlerSocket的php驱动。...MongoDB版本:1.6.5MySQL版本:5.1.53HandlerSocket

Global site tag (gtag.js) - Google Analytics