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

使用 acl 库开发简单的客户端与服务器程序

阅读更多

      之前写过一些如何使用 acl 的服务器框架编写服务器程序的技术文章(http://zsxxsz.iteye.com/category/210570http://zsxxsz.iteye.com/category/80224),如果仅是写一些简单的服务器程序,有时倒不必如此麻烦, acl 的 C++ 库部分也提供了一些简单的服务器类,本文将介绍如何使用这些简单的类来实现一些服务器程序和网络客户端程序。

      首先介绍 acl 中的服务器类:server_socket。该类定义了如下几个简单方法:

 

	/**
	 * 开始监听给定服务端地址
	 * @param addr {const char*} 服务器监听地址,格式为:
	 *  ip:port;在 unix 环境下,还可以是域套接口,格式为:
	 *   /path/xxx
	 * @return {bool} 监听是否成功
	 */
	bool open(const char* addr);

	/**
	 * 关闭已经打开的监听套接口
	 * @return {bool} 是否正常关闭
	 */
	bool close();

	/**
	 * 接收客户端连接并创建客户端连接流
	 * @param timeout {int} 在阻塞模式下,当该值 > 0 时,采用超时
	 *  方式接收客户端连接,若在指定时间内未获得客户端连接,则返回 NULL
	 * @return {socket_stream*} 返回空表示接收失败
	 */
	socket_stream* accept(int timeout = 0);

	/**
	 * 获得监听的地址
	 * @return {const char*} 返回值非空指针
	 */
	const char* get_addr() const
	{
		return addr_;
	}

 

      使用上述网络服务类的步骤是:调用 open 监听本机的一个网络地址(如果是UNIX平台,还可以监听UNIX域套接口)------> 调用 accept 方法等待远程客户端连接本服务器 ------> 当服务器程序接收到客户端连接时 accept 方法返回客户端连接网络流(socket_stream) ------> 启动一个线程处理这个客户端连接。下面为一个简单的服务器程序:

 

#include "acl_cpp/lib_acl.hpp"

// 处理客户端连接的线程类
class client_thread : public acl::thread
{
public:
	client_thread(acl::socket_stream* client)
	: client_(client)
	{
	}

	~client_thread()
	{
		delete client_;
	}

protected:
	// 实现基类 acl::thread 中定义的纯虚方法
	void* run()
	{
		acl::string buf;
		while (true)
		{
			// 从客户端连接读一行数据,第二个参数为 false 意思是希望
			// socket_stream 在读到一行数据时保留 \r\n
			if (client_->gets(buf, false) == false)
				return NULL;

			printf("gets one line: %s", buf.c_str());

			// 回写所读到的一行数据
			if (client_->write(buf) == -1)
				return NULL;
		}
	}

private:
	acl::socket_stream* client_;
};

int main(void)
{
	const char* addr = "0.0.0.0:8080";
	acl::socket_server server;

	// 监听本机网络地址
	if (server.open(addr) == false)
	{
		printf("listen addr: %s error: %s\r\n", addr, acl::last_serror());
		return -1
	}

	while (true)
	{
		// 等待客户端连接本服务器程序
		acl::socket_stream* client = server.accept();
		if (client == NULL)
		{
			printf("accept error: %s\r\n", acl::last_serror());
			return -1;
		}

		// 创建一个子线程用来处理该客户端连接
		client_thread* thread = new client_thread(client);

		// 将线程设为分离模式,这样当线程退出时会自行释放线程相关资源
		thread->set_detachable(true);

		// 启动该线程
		thread->start();
	}

	return 0;
}

       上面例子非常简单,毋庸详述,关于如何使用 acl 编写多线程程序,请参照:使用 acl_cpp 库编写多线程程序。下面再给出一个简单的网络客户端例子:

#include "acl_cpp/lib_acl.hpp"

int main(void)
{
	const char* server_addr = "127.0.0.1:8080";
	int   conn_timeout = 10 /* 连接服务器超时时间,单位:秒 */
	int   rw_timeout = 10 /* 网络 IO 超时时间,单位:秒 */;
	acl::socket_stream conn;

	// 连接远程服务器
	if (conn.open(server_addr, conn_timeout, rw_timeout) == false)
	{
		printf("connect server: %s error: %s\r\n",
			server_addr, acl::last_serror());
		return -1;
	}

	const char* req = "hello world!\r\n";

	acl::string buf;

	// 向服务器写一行数据,同时从服务器读一行数据,循环 10 次
	for (int i = 0; i < 10; i++)
	{
		// 向服务器发送一行数据
		if (conn.write(req, strlen(req)) == -1)
		{
			printf("write request to server error: %s\r\n",
				acl::last_serror());
			return -1;
		}

		// 从服务器读一行数据,注:第二个参数为默认的 true,意思是获得
		// 一行数据后自动将尾部的 \r\n 去掉
		if (conn.gets(buf) == false)
		{
			printf("gets one line from server error: %s\r\n",
				acl::last_serror();
			return -1;
		}

		printf("response: %s\r\n", buf.c_str());
	}

	return 0;
}

 

 

   参考链接:

   技术博客:http://zsxxsz.iteye.com/

   download: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

 

0
0
分享到:
评论

相关推荐

    acl 工程是一个跨平台的网络通信库及服务器编程框架,同时提供更多的实用功能库

    通过该库,用户可以非常容易地编写支持多种模式(多线程、多进程、非阻塞、触发器、UDP方式、协程方式)的服务器程序,WEB 应用程序,数据库应用程序。此外,该库还提供了常见应用的客户端通信库(如:HTTP、SMTP、...

    Java服务器程序设计

    用java进行客户端的applet (小程序)开发的技术已广为使用,而用java进行服务器端的servlet(服务器小程序)开发则尚需揭开其神秘的面纱,本书正是基于这样的目的编写的。全书从java服务器的体系结构、开发工具和...

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

    除了匿名访问用户(Anonymous)外,IIS中的FTP将使用Windows 2000自带的用户库(可在“开始→程序→管理工具→计算机管理”中找到“用户”一项来进行用户库的管理)。 最后,关键一步还有就是将你的电脑变为网络中的...

    ASP.net入门教程

    您可以使用与公共语言运行库 (CLR) 兼容的任何语言来编写应用程序的代码,这些语言包括 Microsoft Visual Basic、C#、JScript .NET 和 J#。使用这些语言,可以开发利用公共语言运行库、类型安全、继承等方面的优点的...

    JavaBaasServer:JavaBaas服务器应用程序

    JavaBaas JavaBaas是基于Java语言开发的后台服务框架,其核心设计目标是实现移动客户端,网页应用的后台数据存储,物理文件存储,消息推送等功能,极大地降低了后台开发难度,实现了快速开发。使用JavaBaas提供的...

    JAVA_API1.6文档(中文)

    javax.management.remote.rmi RMI 连接器是供 JMX Remote API 使用的一种连接器,后者使用 RMI 将客户端请求传输到远程 MBean 服务器。 javax.management.timer 提供对 Timer MBean(计时器 MBean)的定义。 javax...

    unbound-reversecache:具有Python模块的未绑定Docker容器,用于存储反向DNS查找信息

    这样的想法是,如果客户端和鱿鱼使用的是同一个DNS服务器,则DNS服务器应该能够告诉squid哪些主机名与对客户端请求的DNS回复相关联。 这样,鱿鱼可以更好地处理作用于域的ACL。 你好,世界 $ docker run -it ...

    ngx-admin-dotnet-starter

    Angular 10 ngx-admin .NET Starter仪表板 这是具有.NET后端的ngx-admin信息中心...使用JWT令牌的身份验证已实现并与客户端和服务器端集成 基本角色管理和ACL已到位 用于数据访问的实体框架,能够轻松地用其他数据访问

Global site tag (gtag.js) - Google Analytics