🚙

💨 💨 💨

×

  • Categories

  • Archives

  • Tags

  • About

boost之program_options

Posted on 08-15-2016 | In Misc

介绍

命令行接口是普遍,基础的人机交互接口,从命令行提取程序的运行时选项的方法有很多。

你可以自己编写相对应的完整的解析函数,或许你有丰富的C语言编程经验,熟知getopt()函数的用法,又或许使用Python的你已经在使用optparse库来简化这一工作。

大家在平时不断地谈及到“不要重复造轮子”,那就需要掌握一些顺手的库,这里介绍一种C++方式来解析命令行选项的方法,就是使用Boost.Program_options库。

program_options提供程序员一种方便的命令行和配置文件进行程序选项设置的方法。

使用program_options库而不是你自己动手写相关的解析代码,因为它更简单,声明程序选项的语法简洁,并且库自身也非常小。

将选项值转换为适合的类型值的工作也都能自动完成。

库有着完备的错误检查机制,如果自己手写解析代码时,就可能会错过对一些出错情况的检查了。

最后,选项值不仅能从命令行获取,也能从配置文件,甚至于环境变量中提取,而这些选择不会增加明显的工作量。

示例说明

以下面简单的hello程序进行说明,默认打印hello world,如果传入-p选项,就会打印出人的姓名,另外通过传入-h选项,可以打印出帮助选项。

略微看一眼代码文件和相应的屏幕输入输出,然后我们再一起来看看这些是如何发生的。

//hello.cpp 
#include <iostream>
#include <string>
#include <boost/program_options.hpp>

using namespace std;
int main(int argc, char* argv[])
{
using namespace boost::program_options;
//声明需要的选项
options_description desc("Allowed options");
desc.add_options()
("help,h", "produce help message")
("person,p", value<string>()->default_value("world"), "who")
;

variables_map vm;
store(parse_command_line(argc, argv, desc), vm);
notify(vm);

if (vm.count("help")) {
cout << desc;
return 0;
}
cout << "Hello " << vm["person"].as<string>() << endl;
return 0;
}

下面是在Windows命令提示符窗口上的输入输出结果,其中”>”表示提示符。


>hello
Hello world

>hello -h
Allowed options:
-h [ --help ] produce help message
-p [ --person ] arg (=world) who

>hello --person len
Hello len

首先通过options_description类声明了需要的选项,add_options返回了定义了operator()的特殊的代理对象。

这个调用看起来有点奇怪,其参数依次为选项名,选项值,以及选项的描述。

注意到示例中的选项名为”help,h”,是因为声明了具有短选项名和长选项名的选项,这跟gnu程序的命令行具有一致性。

当然你可以省略短选项名,但是这样就不能用命令选项简写了。

第二个选项的声明,定义了选项值为string类型,其默认值为world.

接下来,声明了variables_map类的对象,它主要用来存储选项值,并且能储存任意类型的值。

然后,store,parse_command_line和notify函数使vm能存储在命令行中发现的选项。

最后我们就自由地使用这些选项了,variables_map类的使用就像使用std::map一样,除了它必须用as方法去获取值。

如果as方法调用的指定类型与实际存储的类型不同,就会有异常抛出。

具有编程的你可能有这样的经验,使用cl或gcc对源文件进行编译时,可直接将源文件名放置在命令行中,而无需什么选项字母,如gcc a.c之类的。

prgram_options也能处理这种情况,在库中被称为”positional options”(位置选项),但这需要程序员的一点儿帮助才能完成。

看下面的经过对应修改的代码,我们无需传入”-p”选项,就能可指定”person”选项值

positional_options_description p;
p.add("person", -1);
store(command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
>hello len
Hello len

前面新增的两行是为了说明所有的位置选项都应被解释成”person”选项,这里还采用了command_line_parser类来解析命令行,而不是用parse_command_line函数。

后者只是对前者类的简单封装,但是现在我们需要传入一些额外的信息,所以要使用类本身。

选项复合来源
一般来说,在命令行上指定所有选项,对用户来说是非常烦人的。

如果有些选项要应用于每次运行,那该怎么办呢。

我们当然希望能创建出带有些常用设置的选项文件,跟命令行一起应用于程序中。

当然这一切需要将命令行与配置文件中的值结合起来。

比如,在命令行中指定的某些选项值应该能覆盖配置文件中的对应值,或者将这些值组合起来。

下面的代码段将选项通过文件读取,这文件是文本格式,可用”#”表示注释,格式如命令行中的参数一样,选项=值

ifstream ifs("config.cfg");
store(parse_config_file(ifs,config),vm);
notify(vm);

参考

Boost.prgram_options库文档

关于UNP与APUE与TLPI三本大部头的阅读建议(着重讲UNP)

Posted on 08-11-2016 | In Linux
  • 这本书不能一次性所有都想看完。

    要有目的性的看,因为这本书类似于百科全书所有都讲, 不分轻重, 如果都看,硬啃,只会迷失了自己,反而不知道看了什么

  • 这本书不能单独看。

    这本书必须配合TCP/IP详解和UNIX环境高级编程(简称APUE)以及The Linux Programming Interface(不知道这本书的译名是什么, 简称TLPI)来看

  • 个人看的是卷一第三版,因当前工作经验范围和阅历受限,对于IT码农,IPv6的和SCTP的章节暂且略过,所以目前大概划出的必看章节(其他可挑选)是

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 11
    • 13
    • 16
    • 22
    • 26
    • 30

. . .

服务器模型总结

Posted on 08-08-2016 | In NP

关于Reactor模式讲解请转 此文

服务器模型总结

其中“互通”指的是如果开发chat服务,多个客户连接之间是否能方便地交换数据(chat也是三大TCP网络编程案例之一)。

对于echo/httpd/Sudoku这类“连接相互独立”的服务程序,这个功能无足轻重,但是对于chat类服务却至关重要。

“顺序性”指的是在httpd/Sudoku这类请求响应服务中,如果客户连接顺序发送多个请求,那么计算得到的多个响应是否按相同的顺序发还给客户(这里指的是在自然条件下,不含刻意同步)。

方案0

方案0 这其实不是并发服务器,而是iterative 服务器,因为它一次只能服务一个客户。代码见[UNP]中的Figure 1.9,[UNP]以此为对比其他方案的基准点。这个方案不适合长连接,倒是很适合daytime这种write-only短连接服务。

. . .

Reactor模式讲解

Posted on 08-07-2016 | In NP

关于服务器模型总结请转 此文
, 文中也有Reactor的讲解.

对于 IO 来说,我们听得比较多的是:

  • BIO: 阻塞 IO
  • NIO: 非阻塞 IO
  • 同步 IO
  • 异步 IO

以及其组合:

  • 同步阻塞 IO
  • 同步非阻塞 IO
  • 异步阻塞 IO
  • 异步非阻塞 IO

. . .

重新看unix网络编程的一些心得

Posted on 08-02-2016 | In NP
  • 老书新看, 有了许多不同的见解, 也准备拿出以前自己私人的老笔记做修正放到博客里, 加深理解.
  • 在这个浮躁人人都能写书的时代基本要看一本书需要挑很久, 谁写的, 写得怎么样, 是否是业界经典, 都要需要一一斟酌各种查证方可, 不然看一本烂书事半功倍, 浪费生命,影响效率, 被误导跑偏, 能让人静下心来的书籍不多, 能让人看好几遍仍回味无穷的经典就更少了
  • 陈硕说过, 学东西不要只是从网上看点大牛的博客总结就行了, 总要完整地看些相关领域的经典著作的, 系统的知识结构打下坚实的基础才能继续看有关优化效率方面的书籍, 深以为然
  • 孟岩说, 最近不止一次听到当一个人拥有相关领域的知识基础之后就可以找一本effective*的书来研读了, 颇有道理
  • 看书的顺序忌胶柱鼓瑟, 并不是他的目录结构怎么编排你就该怎么看的, 大多数经典书籍基本都是面面俱到, 如果直接跟着这种面向知识体系本身的编排思路去看, 容易迷失乏味而无法继续, 应该找到属于自己看书顺序
  • 个人总结的看书顺序是先翻阅自己感兴趣的,接着仔细观察他的目录来确定他的编排思路, 然后花一到两天的时间通览全书以获得大体知识体系构架, 之后找到实战性最强的章节来实操并逐个突破实战过程中的各个知识点

快速完成一个简易SLG游戏思路二

Posted on 07-30-2016 | In GS

ChatServer

从登录成功就开始连接,
注册一个Chat_ID,
Player_ID 和 Chat_ID相互对应,
会注册相应的房间频道,
并为每位 Player 存了一份黑名单,
在客户端做了本地黑名单,
聊天服务器也做了黑名单二次验证处理.

  • 世界频道 : 则用MsgServer的非实时推送思路
  • 私密聊天 : 则选择 WorkerMan 的TCP,

MsgServer

  • 实时推送 : WorkerMan 的 TCP
  • 非实时推送 : 客户端定时15秒轮询一下服务器,如果有消息就取下来,如果没消息可以逐步放长轮询时间,比如30秒;如果有消息,就缩短轮询时间到10秒,5秒,

. . .

快速完成一个简易SLG游戏思路一

Posted on 07-30-2016 | In GS

LoginServer(Gate)

当完成渠道SDK回调验证之后,
验证完玩家信息,
用了Nginx的负载均衡给每位玩家分配一台不繁忙的游戏服务器,
在Redis中存了一份玩家在线有效时间key,
这个key也可以用来完成封号操作

MainServer

因为弱交互/短连接的关系,
大多数情况玩家和玩家之间不需要实时面对面PK,
打一下对方的离线数据,
计算下排行榜,排行榜是实时计算的,
存在Redis里, 做了分页处理
买卖下道具即可.

所以 MainServer 选择了:

  • yii
  • Redis
  • MySQL
  • Nginx

. . .

多人快节奏游戏四之延迟补偿实现爆头

Posted on 07-19-2016 | In GS

原文出处

Fast-Paced Multiplayer (Part IV): Lag Compensation


Introduction

The previous three articles explained a client-server game architecture which can be summarized as follows:



  • Server gets inputs from all the clients, with timestamps


  • Server processes inputs and updates world status


  • Server sends regular world snapshots to all clients


  • Client sends input and simulates their effects locally


  • Client get world updates and



    • Syncs predicted state to authoritative state


    • Interpolates known past states for other entities




From a player’s point of view, this has two important consequences:



  • Player sees himself in the present


  • Player sees other entities in the past



This situation is generally fine, but it’s quite problematic for very time- and space-sensitive events; for example, shooting your enemy in the head!


Lag Compensation


So you’re aiming perfectly at the target’s head with your sniper rifle. You shoot - it’s a shot you can’t miss.


But you miss.


Why does this happen?


Because of the client-server architecture explained before, you were aiming at where the enemy’s head was 100ms before you shot - not when you shot!


In a way, it’s like playing in an universe where the speed of light is really, really slow; you’re aiming at the past position of your enemy, but he’s long gone by the time you squeeze the trigger.


Fortunately, there’s a relatively simple solution for this, which is also pleasant for most players most of the time (with the one exception discussed below).


Here’s how it works:



  • When you shoot, client sends this event to the server with full information: the exact timestamp of your shot, and the exact aim of the weapon.


  • Here’s the crucial step. Since the server gets all the input with timestamps, it can authoritatively reconstruct the world at any instant in the past. In particular, it can reconstruct the world exactly as it looked like to any client at any point in time.


  • This means the server can know exactly what was on your weapon’s sights the instant you shot. It was the past position of your enemy’s head, but the server knows it was the position of his head in your present.


  • The server processes the shot at that point in time, and updates the clients.



And everyone is happy!


The server is happy because he’s the server. He’s always happy.


You’re happy because you were aiming at your enemy’s head, shot, and got a rewarding headshot!


The enemy may be the only one not entirely happy. If he was standing still when he got shot, it’s his fault, right? If he was moving… wow, you’re a really awesome sniper.


But what if he was in an open position, got behind a wall, and then got shot, a fraction of a second later, when he thought he was safe?


Well, that can happen. That’s the tradeoff you make. Because you shoot at him in the past, he may still be shot up to a few milliseconds after he took cover.


It is somewhat unfair, but it’s the most agreeable solution for everyone involved. It would be much worse to miss an unmissable shot!


Conclusion


This ends my series on Fast-paced Multiplayer. This kind of thing is clearly tricky to get right, but with a clear conceptual understanding about what’s going on, it’s not exceedingly difficult.


Although the audience of these articles were game developers, it found another group of interested readers: gamers! From a gamer point of view it’s also interesting to understand why some things happen the way they happen.


Further Reading


As clever as these techniques are, I can’t claim any credit for them; these articles are just an easy to understand guide to some concepts I’ve learned from other sources, including articles and source code, and some experimentation.

1…141516171819202122232425262728293031323334…37
Mike

Mike

🚙 🚗 💨 💨 If you want to create a blog like this, just follow my open-source project, "hexo-theme-neo", click the GitHub button below and check it out ^_^ . It is recommended to use Chrome, Safari, or Edge to read this blog since this blog was developed on Edge (Chromium kernel version) and tested on Safari.

11 categories
289 posts
111 tags
about
GitHub Spotify
© 2013 - 2025 Mike