C/S框架 st_asio_wrapper 开发教程(2019.10.17更新)(二)

如果你是偶然浏览到这里,请先看 C/S框架 st_asio_wrapper 开发教程(一)
源代码及例程下载地址:
git:https://github.com/youngwolf-project/st_asio_wrapper/
QQ交流群:198941541

六:开发教程(服务端)

服务端直接#include ext/tcp.h,就可实现一个简单的服务端了,如下(还演示了一个echo服务器,代码未列出):

//configuration
#define ST_ASIO_SERVER_PORT		9527
#define ST_ASIO_REUSE_OBJECT //use objects pool
#define ST_ASIO_ENHANCED_STABILITY
//configuration

#include "../include/ext/tcp.h"
using namespace st_asio_wrapper;
using namespace st_asio_wrapper::tcp;
using namespace st_asio_wrapper::ext;
using namespace st_asio_wrapper::ext::tcp;

#define QUIT_COMMAND	"quit"
#define RESTART_COMMAND	"restart"
#define LIST_ALL_CLIENT	"list_all_client"
#define LIST_STATUS	"status"

int main(int argc, const char* argv[])
{
	service_pump sp;
	server server_(sp);

	if (argc > 3)
		server_.set_server_addr(atoi(argv[2]) + 100, argv[3]);
	else if (argc > 2)
		server_.set_server_addr(atoi(argv[2]) + 100);
	else
		server_.set_server_addr(ST_ASIO_SERVER_PORT + 100);

	int thread_num = 1;
	if (argc > 1)
		thread_num = std::min(16, std::max(thread_num, atoi(argv[1])));

	sp.start_service(thread_num);
	while(sp.is_running())
	{
		std::string str;
		std::cin >> str;
		if (QUIT_COMMAND == str)
			sp.stop_service();
		else if (RESTART_COMMAND == str)
		{
			sp.stop_service();
			sp.start_service(thread_num);
		}
		else if (LIST_STATUS == str)
			printf("normal server, link #: " ST_ASIO_SF ", invalid links: " ST_ASIO_SF "\n", server_.size(), server_.invalid_object_size());
		else
		{
			//broadcast series functions call pack_msg for each client respectively, because clients may used different protocols(so different type of packers, of course)
			server_.broadcast_msg(str.data(), str.size() + 1, false);
			//send \0 character too, because demo client used basic_buffer as its msg type, it will not append \0 character automatically as std::string does,
			//so need \0 character when printing it.
		}
	}

	return 0;
}

        以上例子中,服务端从控制台接收数据,然后广播数据;当收到数据时,server会输出到控制台(st_asio_wrapper::socket实现);

        其中server server_;这行申请了一个普通的服务端,它的功能仅仅是接受连接,发送接收消息等。一般来说,需要从server_socket_base继承一个自己的套接字类,从server继承一个服务类。为此,服务端demo还演示了一个echo服务器(代码未列出),它会把收到的任何数据发送回去(大家可以学着做一个echo客户端,但不要echo服务端与echo客户端一同工作,否则就死循环了。
        start_service开启服务,stop_service结束服务(退出时必须明确调用),is_running判断服务的运行状态;如果想修改服务端地址,则在调用start_service之前调用set_server_addr函数;
        stop_service之后,可再次调用start_service开启服务;
        注意:server_base的del_socket一般用于服务端被动删除某条连接(即在错误发生的时候,比如在tcp::socket_base的on_recv_error和on_send_error里面调用,参看server_socket_base);服务端如果想主动关闭某条连接,建议调用这个socket的force_shutdown或者graceful_shutdown函数,它们的调用最终会促使on_recv_error的调用;
        重写server_base的on_accept函数,根据你自己的策略确定是否接受客户端的连接,接受返回true;
        server_base维护了一个链表(object_pool实现)用于保存所有的socket(这样带来几个好处:一、在广播消息的时候,很方便;二、可开启类似垃圾回收机制的自动清理已经关闭的连接的功能;三、可开启对象池功能),如果你想自己管理这些socket,可以在on_accept里面返回false,然后把它保存在自己的容器里面,并调用start(socket实现)以便开始接受数据(只调用一次即可);
        当然,你还可以在返回true的同时,自己也保存一份socket(此时就不要再调用start了),这样做不会带来多少内存消耗,因为它是用智能指针包装的,复制一份只是增加一个引用计数。至于这样做有什么好处,如果你想不到,说明你不需要,当你有需求的时候,你自然而然就会知道有什么用了,我在这里只是告诉大家可以这样做,有个印象即可;
 

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
st_asio_wrapper是一组库,功能是对boost.asio的包装(调试环境:boost-1.51.0),目的是简化boost.asio开发; 其特点是效率高、跨平台、完全异步(当然这是从boost.asio继承而来)、自动重连,数据透明传输,自动解决分包粘包问题(你可以像udp一样使用它); 注:只支持tcp协议; 教程:http://blog.csdn.net/yang79tao/article/details/7724514 2.3版更新内容: 消息(std::string包装)不再用boost::shared_ptr包装,之前有过度使用智能指针之嫌。效率上,std::string如果支持引用记数,或者编译器支持std::move语义,是没有损失的(因为也不存在内存的拷贝,反而省了智能指针使用上的开销),幸好vc支持std::move语义(虽然它不支持引用记数,linux则都支持)。这样带来一个问题,原来所有的接口中的boost::shared_ptr<std::string>数据型,全部换成了std::string引用,升级到2.3的朋友要注意修改之前重写虚函数的签名,如果不改,则重写肯定不生效,变成了新增加虚函数了(因为签名不一样)。这样向大家道歉,接口签名以后应该不会变化了,但可能增加接口; 修复使用std::advance的一个BUG,此BUG在linux下不存在,这里顺便向大家说一下,std::advance在vc和gcc下面,语义一样,但处理方式有些不同,一定要注意; 增加了个专门用于服务端压力测试的客户端框架st_test_client,并写了一个demo test_client,可以在performance_test目录下面找到; 把连接服务端逻辑从st_client剥离出来,定义了一个新的st_connector,st_client和st_test_client将从它继承; 增加对vc2010的支持,和编译时对编译器版本的检测,如果达不到vc2010及其以上的版本,st_asio_wrapper将直接报错。
st_asio_wrapper是一组,功能是对boost.asio的包装(调试环境:boost-1.51.0),目的是简化boost.asio开发; 其特点是效率高、跨平台、完全异步,当然这是从boost.asio继承而来; 自动重连,数据透明传输,自动解决分包粘包问题(你可以像udp一样使用它); 注:只支持tcp协议; 教程:http://blog.csdn.net/yang79tao/article/details/7724514 1.1版更新内容: 增加了自定义数据模式的支持,可用于st_asio_wrapper server与其它客户端的通信、或者st_asio_wrapper client与其它服务端的通信;当然,两端都是st_asio_wrapper的话,就用透明传输即可(1.0版已经支持了)。 1.2版更新内容: 修复BUG:当stop_service之后,再start_service时,client_base内部某些成员变量可能没有得到复位; 服务端增加修改监听地址功能,当然仍然要在start_service之前调用set_server_addr函数。 1.3版更新内容: 增加自定义消息格式的发送,这个本来是在1.1版本实现的,结果我漏掉了,只实现了自定义消息格式的接收。 1.4版更新内容: 将打包与解包器从client_base分离出来,以简化这个日益复杂的基; 可以在运行时修改打包解包器。 1.5版更新内容: 增加ipv6支持,默认是ipv4,服务端和客户端都通过设置一个ipv6的地址来开启这个功能; 增加了一些服务端helper函数,小改了一下客户端set_server_addr函数签名(调换了两个参数的位置以保持和服务端一样)。 1.6版更新内容: 增加了接收消息缓存(改动较大,on_msg的语义有所变化,请看开发教程第三篇)。 1.7版更新内容: 修复vc2010下编译错误; 修复默认解包器BUG(同时修改解包器接口); 修复log输出BUG; 更好的包装了服务端库,现在服务端可以像客户端一样简单的使用了(完全不用继承或者重写虚函数,申请一个对象即可); 结构大调整,名大调整,请参看开发教程第一篇。 1.8版更新内容: 增加健壮性和稳定性; 退出服务更新优雅。 1.9版更新内容: 提高代码通用性; 可以指定服务端同时投递多少个async_accept; 修复BUG,此BUG可能造成数据发送不完全。 2.0版更新内容: 服务端增加对象池功能; 优化美化代码; 更规范化接口签名。 2.1版更新内容: 修复BUG,此BUG会造成st_client在stop_service之后,仍然可能尝试重新连接服务器; 在消息发送的时候,增加了一个参数can_overflow,用于确定是否在缓存满的时候返回失败,这在某些不能阻塞等待直到缓存可用的场合非常有用,比如on_msg; 当消息接收缓存满的时候,st_socket现在可以保证消息不丢失,之前的行为是调用on_recv_buffer_oveflow之后,丢弃消息; 更规范化接口签名; 更多更新请看st_asio_wrapper_socket.h,所有更新都会罗列在这个头文件的开头处,另外st_asio_wrapper_server.h的开头部分注释也很重要,有工作原理相关的说明。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值