`
zsxxsz
  • 浏览: 444163 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

利用ACL开发并发网络服务器

阅读更多

1、概述
    本节结合 "利用ACL库开发高并发半驻留式线程池程序" 和 "利用ACL库快速创建你的网络程序" 两篇文章的内容,创建一个简单的线程池网络服务器程序。
2、并发式网络通信实例

#include "lib_acl.h"  /* 先包含ACL库头文件 */
#include <stdio.h>
#include <stdlib.h>

/**
 * 单独的线程处理来自于客户端的连接
 * @param arg {void*} 添加任务时的对象
 */
static void echo_client_thread(void *arg)
{
	ACL_VSTREAM *client = (ACL_VSTREAM*) arg;
	char  buf[1024];
	int   n;

	/* 设置客户端流的读超时时间为30秒 */
	ACL_VSTREAM_SET_RWTIMO(client, 30);

	/* 循环读客户端的数据,直到其关闭或出错或超时 */
	while (1) {
		/* 等待读客户端发来的数据 */
		n = acl_vstream_read(client, buf, sizeof(buf));
		if (n == ACL_VSTREAM_EOF)
			break;
		/* 将读到的数据写回至客户端流 */
		if (acl_vstream_writen(client, buf, n) == ACL_VSTREAM_EOF)
			break;
	}

	/* 关闭客户端流 */
	acl_vstream_close(client);
}

/**
 * 创建半驻留线程池的过程
 * @return {acl_pthread_pool_t*} 新创建的线程池句柄
 */
static acl_pthread_pool_t *create_thread_pool(void)
{
	acl_pthread_pool_t *thr_pool;  /* 线程池句柄 */
	int  max_threads = 100;  /* 最多并发100个线程 */
	int  idle_timeout = 10;  /* 每个工作线程空闲10秒后自动退出 */
	acl_pthread_pool_attr_t attr;  /* 线程池初始化时的属性 */

	/* 初始化线程池对象属性 */
	acl_pthread_pool_attr_init(&attr);
	acl_pthread_pool_attr_set_threads_limit(&attr, max_threads);
	acl_pthread_pool_attr_set_idle_timeout(&attr, idle_timeout);

	/* 创建半驻留线程句柄 */
	thr_pool = acl_pthread_pool_create(&attr);
	assert(thr_pool);
	return (thr_pool);
}

/**
 * 开始运行
 * @param addr {const char*} 服务器监听地址,如:127.0.0.1:8081
 */
static void run(const char *addr)
{
	const char *myname = "run";
	acl_pthread_pool_t *thr_pool;
	ACL_VSTREAM *sstream;
	char  ebuf[256];

	thr_pool = create_thread_pool();

	/* 监听一个本地地址 */
	sstream = acl_vstream_listen(addr, 128);
	if (sstream == NULL) {
		printf("%s(%d): listen on %s error(%s)\r\n",
				myname, __LINE__, addr,
				acl_last_strerror(ebuf, sizeof(ebuf)));
		return;
	}

	printf("%s: listen %s ok\r\n", myname, addr);
	while (1) {
		/* 等待接受客户端的连接 */
		ACL_VSTREAM *client = acl_vstream_accept(sstream, NULL, 0);
		if (client == NULL) {
			printf("%s(%d): accept error(%s)\r\n",
					myname, __LINE__,
					acl_last_strerror(ebuf, sizeof(ebuf)));
			break;
		}
		printf("accept one\r\n");
		/* 获得一个客户端连接流 */
		/* 开始处理该客户端连接流 */

		/**
		 * 向线程池中添加一个任务
		 * @param thr_pool 线程池句柄
		 * @param echo_client_thread 工作线程的回调函数
		 * @param client 客户端数据流
		 */
		acl_pthread_pool_add(thr_pool, echo_client_thread, client);
	}

	/* 销毁线程池对象 */
	acl_pthread_pool_destroy(thr_pool);
}

/**
 * 初始化过程
 */
static void init(void)
{
	/* 初始化ACL库 */
	acl_init();
}

/**
 * 使用提示接口
 * @param procname {cosnt char*} 程序名
 */
static void usage(const char *procname)
{
	printf("usage: %s listen_addr\r\n", procname);
	printf("example: %s 127.0.0.1:8081\r\n", procname);
	getchar();  
}

int main(int argc, char *argv[])
{
	if (argc != 2) {
		usage(argv[0]);
		return (0);
	}

	init();
	run(argv[1]);
	return (0);
}

 


    由上可以看出,创建一个并发式服务器程序也是如此的简单。 该例子可以同时运行在WIN32平台及UNIX平台(Linux, FreeBSD, Solaris-x86).

3、小结
    由以上例子可以看出,ACL库屏蔽底层SOCKET的细节操作,使网络编程变得简单,使使用者可以专心于其应用,而不是拘泥于SOCKET操作上,另外结合半驻留线程池的ACL库就可以开发高效的并发网络应用来。
  当然,以上例子也存在一个缺点,那就是当客户端并发连接比较高时,因为一个连接占用一个线程,所以高并发时就需要更多的线程(为了启动更多的线程,可以通过 acl_pthread_pool_set_stacksize 或 acl_pthread_pool_attr_set_stacksize 设置每个线程的堆栈为较小的值,如 500KB);而采用ACL库里的另一种编程技术--非阻塞式IO,可以使一个线程同时处理多个并发TCP连接,同时可以启动多个这样的非阻塞线程,从而可以更好地利用多核(一般是一个核可以启用一个非阻塞IO线程),将来,我们将会对此类问题进行讨论,并给出具体实例。

   acl 库的下载地址:http://acl.sourceforge.net/
   acl 库的在线帮助地址:http://acl.sourceforge.net/acl_help/index.html

 

4 参考

1)  利用ACL库快速创建你的网络程序--ACL_VSTREAM 流的使用

2)  利用ACL库开发高并发半驻留式线程池程序

 

下载:http://sourceforge.net/projects/acl/

svn:svn checkout svn://svn.code.sf.net/p/acl/code/trunk acl-code

github:https://github.com/acl-dev/acl

QQ 群:242722074

国内镜像:http://git.oschina.net/acl-dev/acl
微博:http://weibo.com/zsxxsz/

分享到:
评论
8 楼 zsxxsz 2017-05-03  
2202877 写道
你好,请问一下acl库是否可以移植到arm平台上,是否可以把要注意的地方说一下。谢谢

目前已经完全支持 Android, IOS 平台。
7 楼 zsxxsz 2012-12-26  
2202877 写道
acl_pthread.h中如果有pthread库(ACL_HAS_PTHREAD有定义),则将acl_pthread_coond_create在第40行重定义成pthread_cond_create,但是pthread库里好像没有pthread_cond_create函数,这里是不是有问题?

是的,这个函数是我扩展的,在UNIX平台下应该注掉。
6 楼 2202877 2012-12-26  
acl_pthread.h中如果有pthread库(ACL_HAS_PTHREAD有定义),则将acl_pthread_coond_create在第40行重定义成pthread_cond_create,但是pthread库里好像没有pthread_cond_create函数,这里是不是有问题?
5 楼 zsxxsz 2012-12-25  
2202877 写道
这两天做了个小程序,试用了这个库,还不错,非常感谢。
只是DOXYGEN生成的文档感觉还不是很理想,找api比较费劲,如果能弄成和apr的文档一样最好http://apr.apache.org/docs/apr-util/1.4/modules.html,个人意见哈,也可能是我不太习惯这种方式。


要想生成doxygen文档,必须先将 acl 里的头文件由 gb2312 格式转成utf-8格式,doxygen 自己的转码器有问题,我写过一个转码器来专门做这件事。不过我已经把生成的 API 文档上传到 sourceforge 了,http://sourceforge.net/projects/acl/files/doc/ 下的 acl_help_html.zip
4 楼 2202877 2012-12-25  
这两天做了个小程序,试用了这个库,还不错,非常感谢。
只是DOXYGEN生成的文档感觉还不是很理想,找api比较费劲,如果能弄成和apr的文档一样最好http://apr.apache.org/docs/apr-util/1.4/modules.html,个人意见哈,也可能是我不太习惯这种方式。

3 楼 2202877 2012-12-21  
zsxxsz 写道
ACL主要依赖于系统基本的库(其中库 lib_acl 当需要支持 mysql 时需要 mysql 的客户端库, 库 lib_protocol 仅依赖系统基础库,库 lib_acl_cpp 需要支持 zlib/polarssl 时也得需要这两个库, lib_tls 需要 openssl 库,lib_dict 需要 bdb 库)按道理说是可以移植到ARM上的,目前它支持LINUX/BSD/MAC/WIN32四个平台,如果有相应的开发环境,就可以移植。

好的,谢谢,我先试试。
2 楼 zsxxsz 2012-12-21  
ACL主要依赖于系统基本的库(其中库 lib_acl 当需要支持 mysql 时需要 mysql 的客户端库, 库 lib_protocol 仅依赖系统基础库,库 lib_acl_cpp 需要支持 zlib/polarssl 时也得需要这两个库, lib_tls 需要 openssl 库,lib_dict 需要 bdb 库)按道理说是可以移植到ARM上的,目前它支持LINUX/BSD/MAC/WIN32四个平台,如果有相应的开发环境,就可以移植。
1 楼 2202877 2012-12-21  
你好,请问一下acl库是否可以移植到arm平台上,是否可以把要注意的地方说一下。谢谢

相关推荐

    IIS6.0 IIS,互联网信息服务

    最后,关键一步还有就是将你的电脑变为网络中的一台服务器,所以你要在你的电脑中装上一个合适的代理服务器软件并运行。 二、本部分常见问题解答 Q:如何修改FTP服务器登录成功或退出时的系统提示信息? A:在相应...

    Fourinone分布式并行计算四合一框架

    对于大型互联网应用,高峰访问量上百万的并发读写吞吐量,会超出单台服务器的承受力,Fourinone提供了fa?ade的解决方案去解决大集群的分布式缓存,利用硬件负载均衡路由到一组fa?ade服务器上,fa?ade可以自动为缓存...

    fourinone-3.04.25

    对于大型互联网应用,高峰访问量上百万的并发读写吞吐量,会超出单台服务器的承受力,Fourinone提供了fa?ade的解决方案去解决大集群的分布式缓存,利用硬件负载均衡路由到一组fa?ade服务器上,fa?ade可以自动为缓存...

    Fourinone分布式计算框架

    对于大型互联网应用,高峰访问量上百万的并发读写吞吐量,会超出单台服务器的承受力,FourInOne提供了fa?ade的解决方案去解决大集群的分布式缓存,利用硬件负载均衡路由到一组fa?ade服务器上,fa?ade可以自动为缓存...

    JAVA_API1.6文档(中文)

    java.security.acl 此包中的类和接口已经被 java.security 包中的类取代。 java.security.cert 提供用于解析和管理证书、证书撤消列表 (CRL) 和证书路径的类和接口。 java.security.interfaces 提供的接口用于生成...

    java api最新7.0

    org.ietf.jgss 此包提供一个框架,该框架允许应用程序开发人员通过利用统一的 API 使用一些来自各种基础安全机制(如 Kerberos)的安全服务,如验证、数据完整性和和数据机密性。 org.omg.CORBA 提供 OMG CORBA API ...

    JDK_1_6 API

    org.ietf.jgss 此包提供一个框架,该框架允许应用程序开发人员通过利用统一的 API 使用一些来自各种基础安全机制(如 Kerberos)的安全服务,如验证、数据完整性和和数据机密性。 org.omg.CORBA 提供 OMG CORBA API...

    [Java参考文档]

    jdk_api_1_6帮助开发 ...org.ietf.jgss 此包提供一个框架,该框架允许应用程序开发人员通过利用统一的 API 使用一些来自各种基础安全机制(如 Kerberos)的安全服务,如验证、数据完整性和和数据机密性。 org.omg....

    java jdk-api-1.6 中文 chmd

    java.lang 提供利用 Java 编程语言进行程序设计的基础类。 java.lang.annotation 为 Java 编程语言注释设施提供库支持。 java.lang.instrument 提供允许 Java 编程语言代理检测运行在 JVM 上的程序的服务。 java....

    Java 1.6 API 中文 New

    org.ietf.jgss 此包提供一个框架,该框架允许应用程序开发人员通过利用统一的 API 使用一些来自各种基础安全机制(如 Kerberos)的安全服务,如验证、数据完整性和和数据机密性。 org.omg.CORBA 提供 OMG CORBA API ...

    JavaAPI1.6中文chm文档 part1

    由于比较大分为两个部分,这是第一...org.ietf.jgss 此包提供一个框架,该框架允许应用程序开发人员通过利用统一的 API 使用一些来自各种基础安全机制(如 Kerberos)的安全服务,如验证、数据完整性和和数据机密性。 ...

    JavaAPI中文chm文档 part2

    由于文件比较大 分为两个部分,这是...org.ietf.jgss 此包提供一个框架,该框架允许应用程序开发人员通过利用统一的 API 使用一些来自各种基础安全机制(如 Kerberos)的安全服务,如验证、数据完整性和和数据机密性。...

    [Java参考文档].JDK_API 1.6

    org.ietf.jgss 此包提供一个框架,该框架允许应用程序开发人员通过利用统一的 API 使用一些来自各种基础安全机制(如 Kerberos)的安全服务,如验证、数据完整性和和数据机密性。 org.omg.CORBA 提供 OMG CORBA API ...

Global site tag (gtag.js) - Google Analytics