??xml version="1.0" encoding="utf-8" standalone="yes"?>久久本道综合久久伊人,久久亚洲AV无码精品色午夜麻豆 ,久久久久久亚洲精品不卡http://www.shnenglu.com/sunicdavy/archive/2021/12/27/217896.html战魂筑战魂筑Mon, 27 Dec 2021 11:05:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2021/12/27/217896.htmlhttp://www.shnenglu.com/sunicdavy/comments/217896.htmlhttp://www.shnenglu.com/sunicdavy/archive/2021/12/27/217896.html#Feedback0http://www.shnenglu.com/sunicdavy/comments/commentRss/217896.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/217896.html阅读全文

战魂筑 2021-12-27 19:05 发表评论
]]>
游戏与Web的服务器Ҏhttp://www.shnenglu.com/sunicdavy/archive/2018/08/29/215887.html战魂筑战魂筑Wed, 29 Aug 2018 03:16:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2018/08/29/215887.htmlhttp://www.shnenglu.com/sunicdavy/comments/215887.htmlhttp://www.shnenglu.com/sunicdavy/archive/2018/08/29/215887.html#Feedback0http://www.shnenglu.com/sunicdavy/comments/commentRss/215887.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/215887.htmlZ~写Zcellnet的新一代游戏服务器框架Q最q深入研I微服务QServiceMesh{概c研I过E中对Web和游戏两U服务器架构设计有一些心得,~写q记录下来?下文中,Game表示游戏服务器,Web表示Web服务? ``
状态缓?/span>
所谓状态缓存,是在内存而非专业数据~存服务器(如redisQ中保存和处理逻辑数据Q手动编写此q程较ؓJ琐但是效率较高Q但随着状态逻辑复杂性和q发、扩定w题提出,状态同步会变得来复杂?/span>
Game:
Z互性的服务器类型需要在服务器做~存Q逻辑~写也较为容易,无需处理事务q发问题。例如:l队Q匹配,战斗逻辑。服务器不能随意重启?/span>
׃互性的服务器类型可配合redis做成无状态服务器Q例如:LQ技能升U,领取物品{。服务器随时支持重启?/span>
游戏服务器ؓ了提高性能Q早期所有服务器都是使用状态缓存写法编写,特别是MMORPGq类Z互的游戏服务器尤Z重?/span>
Web:
均ؓ无状态服务器Q弱交互。用事务方式处理ƈ发逻辑Q例如:交易Q下单等?/span>
推送,单独发?/span>
q里提到的所谓推送,单独发送是与RPC区别的通讯Ҏ。RPC要求h必须有回应。而推送单独发送则更像是通知和广播,无需目的方返回Q何消息?/span>
Game:
扑ֈ服务器的SessionQ直接Send
通过中{服务器,或称Z心服务器q行注册/q播
客户端的model数据需要更新时Q服务器会主动推送消息?/span>
游戏服务器没有严格的RPC设计需求,推送和单独发送较Web服务器更多。而且游戏服务器多使用长连接,所以主动推送也比Web服务器来的方便一些?/span>
Web:
推送做成专有的服务Qƈ做排队和q发处理?/span>
可用?/span>
听说q游戏停服更斎ͼ支付宝服务器在刷二维码时停服了可一定被骂惨吧。WebҎ务器高可用性要求很高,游戏虽然也注重服务器E_性和可用性,但是׃版本q代更新频繁Q停服更新反而能获得玩家接受?/span>
Game:
游戏对可用性要求不高?/span>
游戏大版本更新时需要停服更新。支持热更新技术的服务器(例如ErlangQSkynetQ仅使用热更C复bugQ很直接更新新版本?/span>
不是所有的游戏服务器支持动态添加服务器?/span>
Web:
极高的可用性,服务不允许停服更斎ͼ使用蓝绿及灰度方式更新服务器?/span>
随时可以横向扩展服务器,提高服务器容量和承蝲?/span>
q接及传?/span>
均用TCP传输协议Q游戏服务器注重性能Q自有协议及二进制协议用较多?/span>
Web注重兼容和接口友好,使用JSON格式较多?/span>
Game:
使用长连接,需要从逻辑层维护连接状态及处理服务器不在线情况
使用自有包格式Q大部分使用protobuf或二q制格式?/span>
Web:
微服务大部分使用短连接,grpc支持http2长连?/span>
使用json~码方便调试和版本兼宏V?/span>
量限制
人数多了QQ何服务器都扛不住Q流量限制和d限制能有效保护服务器E_?/span>
Game:
单服有h数限Ӟ可以通过GM后台讄挡墙Q超q无法进?/span>
Web:
限流器中间gQ可以精到服务控制量
断流Q防止雪?/span>
Game:
游戏没有Q也不需要这U概念,游戏h不会H然升高Q即便有Q也通过GM后台Zؓ控制
Web:
断流器中间g
服务发现
如何扑ֈ服务器地址?/span>
服务有变化时Q通过Watchpȝ通知订阅者更新本地缓?/span>
服务器没有变化时Q用本地缓存找到服务地址
Game:
游戏服务器互怾赖复用只在很的范围内,因此无需在不同语a不同q程服务间获得地址Q大部分在配|文件中填写各服务的IP及地址卛_互相讉K?/span>
早期游戏自己~写服务器状态及地址发现服务?/span>
有用redis做服务发?/span>
Web:
使用服务发现pȝQ分布式部v。无需依赖配置文g
|关需?/span>
Game:
|关处理客户端上下线通知Q心跻Il持q接Q{发,q播上下行封?/span>
Web:
Ҏh地址路由Q无上下U概念,无心跟뀂广播通过消息推送系l完?/span>
׃W者从事游戏行业,对Web服务器概念在逐渐熟悉中,若有错误和不各位大{指出?/span>
本hC《Go语言从入门到q阶实战》,生动的语aQ例子带有各U彩蛋,L了解Go语言Ҏ,更有cellnet框架剖析解密
https://search.jd.com/Search?keyword=go%E8%AF%AD%E8%A8%80%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E8%BF%9B%E9%98%B6%E5%AE%9E%E6%88%98&enc=utf-8&suggest=1.def.0.V02&wq=Go%E8%AF%AD%E8%A8%80%E4%BB%8E&pvid=145d55a92cab4b07b71326f8beb1700b


战魂筑 2018-08-29 11:16 发表评论
]]>
Golang 热更新研I笔?/title><link>http://www.shnenglu.com/sunicdavy/archive/2017/07/06/215057.html</link><dc:creator>战魂筑</dc:creator><author>战魂筑</author><pubDate>Thu, 06 Jul 2017 04:47:00 GMT</pubDate><guid>http://www.shnenglu.com/sunicdavy/archive/2017/07/06/215057.html</guid><wfw:comment>http://www.shnenglu.com/sunicdavy/comments/215057.html</wfw:comment><comments>http://www.shnenglu.com/sunicdavy/archive/2017/07/06/215057.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/sunicdavy/comments/commentRss/215057.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/sunicdavy/services/trackbacks/215057.html</trackback:ping><description><![CDATA[<p data-source-line="1" style="box-sizing: border-box; margin-bottom: 16px; color: #333333; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 21px; widows: 1; background-color: #ffffff; margin-top: 0px !important;">本文主要研究游戏服务器带状态的热更新需?http的无状态热更新需求已l有成熟Ҏ, 故不在本文描q范?/p><h1><a href="file:///C:/Users/Davy/AppData/Local/Youdao/YNote/markdown/index.html#基本概念" style="box-sizing: border-box; color: #4078c0; text-decoration-line: none;"></a>基本概念</h1><ul data-source-line="6" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; padding-left: 2em; color: #333333; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 21px; widows: 1; background-color: #ffffff;"><li style="box-sizing: border-box;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">Golang的热更新采用什么机?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">使用go1.8提供的plugin包机制实?/p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">plugin包本w设计的目的是热更新?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">plugin包其实只是支持将代码分别~译为多个动态库,动态加载后q行 q不能完全支持类似C/C++的动态库方式处理代码</p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">带状态的q程热更新的基本概念及范围是什?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">数据部分(model)不更? 只更新逻辑部分(函数)</p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">表格和配|更新算热更C?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">? 但不是本文描q范?/p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">热更新能在windows上用么?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">不支?/p></li></ul><h1><a href="file:///C:/Users/Davy/AppData/Local/Youdao/YNote/markdown/index.html#代码及结? style="box-sizing: border-box; color: #4078c0; text-decoration-line: none;"></a>代码及结?/h1><ul data-source-line="29" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; padding-left: 2em; color: #333333; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 21px; widows: 1; background-color: #ffffff;"><li style="box-sizing: border-box;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">我能原来一个exe的代码编译ؓso提供lplugin使用?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">可以, 但是必须仍然保留main包作为插件入? q在main包内d提供lplugin调用入口.</p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">如果动态库中没有main? ~译出的so能用?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">不能, 包必d含main, 否则输出的是.a的文? plugin包加载会报错</p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">动态库? 非main包的的代码修改能做热更新?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;"><span style="box-sizing: border-box; font-weight: 600;">不能</span>!(崩溃了吧, 我提了一个issue: <a style="box-sizing: border-box; color: #4078c0; text-decoration-line: none; background-color: transparent;">https://github.com/golang/go/issues/20554</a>)</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">如果实做了修改, 底层会报? plugin was built with a different version of package</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">解决Ҏ: 修改plugin包底层实现ƈ重新~译 打开runtime/plugin.go, 注释以下代码 for _, pkghash := range md.pkghashes { if pkghash.linktimehash != *pkghash.runtimehash { return "", nil, pkghash.modulename } } 执行/usr/local/go/run.bash 重编?试</p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">代码中哪些可以被更新? Ҏ可以被更C? 闭包?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">只能更新拥有静态地址的结?例如: 包别函?cM于静态函?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">例如: svc_0.so里有一个Foo函数, svc_1.so修改了Foo函数实现, 热更新可实现</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;"><span style="box-sizing: border-box; font-weight: 600;">闭包=函数+捕获变量</span>, 实际上是一个动态结? 没有静态地址, 无法被更?/p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">各种包别变? l构体变? l构体方? 局部变量均不能被热更新, 但是变量g会被影响</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">新增l构可以被运?/p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">使用l构体方法调用了包别函? 包别函数能被更C?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">可以, 虽然Ҏ不能被更? 但方法被调用的包U别函数的地址是固定的, 所以可以被热更?/p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">init包初始化函数能用? 能被热更C?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">官方q样描述:</p><pre data-source-line="71" style="box-sizing: border-box; font-stretch: normal; font-size: 11.9px; line-height: 1.45; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; word-wrap: normal; margin-top: 0px; margin-bottom: 16px; padding: 16px; overflow: auto; border-radius: 3px; background-color: #f7f7f7;"><code style="box-sizing: border-box; display: inline; overflow: visible; padding: 0px; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; margin: 0px; font-size: 11.9px; border-radius: 3px; word-break: normal; border: 0px; line-height: inherit; word-wrap: normal; background: 0px 0px transparent;"><span style="box-sizing: border-box; font-weight: 700;">When</span> a plugin <span style="box-sizing: border-box; font-weight: 700;">is</span> first opened, the init functions <span style="box-sizing: border-box; font-weight: 700;">of</span> <span style="box-sizing: border-box; font-weight: 700;">all</span> packages <span style="box-sizing: border-box; font-weight: 700;">not</span> already part <span style="box-sizing: border-box; font-weight: 700;">of</span> the program are called. The main <span style="box-sizing: border-box; font-weight: 700;">function</span> <span style="box-sizing: border-box; font-weight: 700;">is</span> <span style="box-sizing: border-box; font-weight: 700;">not</span> run. A plugin <span style="box-sizing: border-box; font-weight: 700;">is</span> only initialized once, <span style="box-sizing: border-box; font-weight: 700;">and</span> cannot be closed</code></pre><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">插gW一ơ被打开? 其关联的, 没有成ؓE序的一部分的所有的包的init函数被调用. 插g的main函数不会被调? 插g只会被初始化一? 不能被关?/p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">因此, 需要手动将init函数Ҏ自己的函? l一在so的main包里调用</p></li></ul><h1><a href="file:///C:/Users/Davy/AppData/Local/Youdao/YNote/markdown/index.html#~译" style="box-sizing: border-box; color: #4078c0; text-decoration-line: none;"></a>~译</h1><ul data-source-line="80" style="box-sizing: border-box; margin-top: 0px; padding-left: 2em; color: #333333; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 21px; widows: 1; background-color: #ffffff; margin-bottom: 0px !important;"><li style="box-sizing: border-box;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">如何~译获得plugin包支持的动态库</p><pre data-source-line="82" style="box-sizing: border-box; font-stretch: normal; font-size: 11.9px; line-height: 1.45; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; word-wrap: normal; margin-top: 0px; margin-bottom: 16px; padding: 16px; overflow: auto; border-radius: 3px; background-color: #f7f7f7;"><code style="box-sizing: border-box; display: inline; overflow: visible; padding: 0px; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; margin: 0px; font-size: 11.9px; border-radius: 3px; word-break: normal; border: 0px; line-height: inherit; word-wrap: normal; background: 0px 0px transparent;">SVCNAME=<span style="box-sizing: border-box; color: teal;">$1</span> SVCVER=<span style="box-sizing: border-box; color: teal;">$2</span> TIMESTAMP=`date <span style="box-sizing: border-box; color: #dd1144;">'+%Y%m%d_%H%M%S'</span>` go build -v -buildmode=plugin --ldflags=<span style="box-sizing: border-box; color: #dd1144;">"-pluginpath=${SVCNAME}_${TIMESTAMP}"</span> -o ${SVCNAME}<span style="box-sizing: border-box; color: teal;">_</span>${SVCVER}.so ${SVCNAME}</code></pre><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">-buildmode=plugin是重要参?/p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">--ldflags里的-pluginpath的作用是: 每次~译的内部识别\径都是不同的, 避免重复加蝲的警?/p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">参? <a style="box-sizing: border-box; color: #4078c0; text-decoration-line: none; background-color: transparent;">https://github.com/golang/go/issues/19004</a></p></li></ul><img src ="http://www.shnenglu.com/sunicdavy/aggbug/215057.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/sunicdavy/" target="_blank">战魂筑</a> 2017-07-06 12:47 <a href="http://www.shnenglu.com/sunicdavy/archive/2017/07/06/215057.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MMO怽技术研I?/title><link>http://www.shnenglu.com/sunicdavy/archive/2017/04/08/214817.html</link><dc:creator>战魂筑</dc:creator><author>战魂筑</author><pubDate>Sat, 08 Apr 2017 06:41:00 GMT</pubDate><guid>http://www.shnenglu.com/sunicdavy/archive/2017/04/08/214817.html</guid><wfw:comment>http://www.shnenglu.com/sunicdavy/comments/214817.html</wfw:comment><comments>http://www.shnenglu.com/sunicdavy/archive/2017/04/08/214817.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/sunicdavy/comments/commentRss/214817.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/sunicdavy/services/trackbacks/214817.html</trackback:ping><description><![CDATA[<h1>怽技?/h1><p data-source-line="3" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #333333; font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 22.4px; widows: 1; background-color: #ffffff;">怽技术大规模出现在魔兽世界WLK版本, 现在应用已经q泛应用在各UMMORPG游戏? 下面对相位技术的做法q行单归Ux?/p><h2><a href="file:///C:/Users/Davy/AppData/Local/Youdao/YNote/markdown/index.html#表现分类" style="box-sizing: border-box; color: #4078c0; text-decoration-line: none;"></a>表现分类</h2><h3><a href="file:///C:/Users/Davy/AppData/Local/Youdao/YNote/markdown/index.html#副本怽" style="box-sizing: border-box; color: #4078c0; text-decoration-line: none;"></a>副本怽</h3><p data-source-line="10" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #333333; font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 22.4px; widows: 1; background-color: #ffffff;">早期副本的出? 避免抢怪问? 所? 副本其实本n是一U相位技? 只不q实现时, 我们一般会小队和怪物直接预分配在独立的一个副本实例中(所以副本原文也是实例的意?</p><h3><a href="file:///C:/Users/Davy/AppData/Local/Youdao/YNote/markdown/index.html#分线怽" style="box-sizing: border-box; color: #4078c0; text-decoration-line: none;"></a>分线怽</h3><p data-source-line="15" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #333333; font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 22.4px; widows: 1; background-color: #ffffff;">怽技术还没有正式命名? 同一个场? 玩家q到不同的分U看到的玩家不一? 也是属于怽的一U? 当然, 如果是组队玩? 服务器默认会分配所有队伍玩家在同一个线(位面)</p><h3><a href="file:///C:/Users/Davy/AppData/Local/Youdao/YNote/markdown/index.html#真相? style="box-sizing: border-box; color: #4078c0; text-decoration-line: none;"></a>真相?/h3><p data-source-line="20" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #333333; font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 22.4px; widows: 1; background-color: #ffffff;">副本怽和分U相位其实都是静态相? 一旦进? 中途不会有切换或者؜合查看的q程. 真相位可以在一个场景中,动态切换相? 怽内和怽外所以不?/p><p data-source-line="22" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #333333; font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 22.4px; widows: 1; background-color: #ffffff;">我们常见的真怽表现? <span style="box-sizing: border-box; font-weight: bolder;">怽中的角色+玩家+队伍成员</span></p><p data-source-line="24" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #333333; font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 22.4px; widows: 1; background-color: #ffffff;">在护送Q务时, q会在上面所见角色中叠加世界中的所有角? 也就是说, 你和队伍成员可以看到的角? 其他人看不到, 其他Z看不C和你的队伍成?/p><hr style="box-sizing: content-box; overflow: hidden; height: 4px; padding: 0px; margin: 16px 0px; border-width: 0px; border-style: initial; border-bottom-color: #eeeeee; color: #333333; font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 22.4px; widows: 1; background: #e7e7e7;" /><p data-source-line="28" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #333333; font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 22.4px; widows: 1; background-color: #ffffff;">Z清晰的简单的描述, 我ؓ怽创徏如下概念与名?/p><h2><a href="file:///C:/Users/Davy/AppData/Local/Youdao/YNote/markdown/index.html#怽客体" style="box-sizing: border-box; color: #4078c0; text-decoration-line: none;"></a>怽客体</h2><p data-source-line="33" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #333333; font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 22.4px; widows: 1; background-color: #ffffff;">表现为除玩家外的角色(怪物,交互物体与相位可见场?</p><h3><a href="file:///C:/Users/Davy/AppData/Local/Youdao/YNote/markdown/index.html#U有客体" style="box-sizing: border-box; color: #4078c0; text-decoration-line: none;"></a>U有客体</h3><p data-source-line="37" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #333333; font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 22.4px; widows: 1; background-color: #ffffff;">q是最常见的一U相位内角色</p><ul data-source-line="39" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; padding-left: 2em; color: #333333; font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 22.4px; widows: 1; background-color: #ffffff;"><li style="box-sizing: border-box;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">持有变量</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">取PhasingID?为PhasingTargetID</p></li><li style="box-sizing: border-box;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">生成规则</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">当玩家开启相位后, 在玩家相位内<span style="box-sizing: border-box; font-weight: bolder;">生成的角?/span>为私有客?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">此时, ?PhasingTargetID讄为相位生成者的实例ID</p></li><li style="box-sizing: border-box;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">删除规则</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">如果玩家退出相? U有客体会存在一D|间或按照需求删?/p></li></ul><h3><a href="file:///C:/Users/Davy/AppData/Local/Youdao/YNote/markdown/index.html#公共客体" style="box-sizing: border-box; color: #4078c0; text-decoration-line: none;"></a>公共客体</h3><p data-source-line="55" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #333333; font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 22.4px; widows: 1; background-color: #ffffff;">一般指提前攄在场景中, 世界内不可见, 但是能被同相位玩家可?且同怽玩家都可以互相可?比如: 只要接了同一个Q务的玩家, 都可以看到的NPC</p><ul data-source-line="58" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; padding-left: 2em; color: #333333; font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 22.4px; widows: 1; background-color: #ffffff;"><li style="box-sizing: border-box;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">持有变量</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">取PhasingID?为PublicPhasingID</p></li><li style="box-sizing: border-box;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">生成规则</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">通过场景~辑? 攄角色? 讄其可被观察到的Q务ID</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">角色被加载后, Q务ID讄到StaticPhasingID</p></li><li style="box-sizing: border-box;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">删除规则</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">场景删除, 角色删除</p></li></ul><h2><a href="file:///C:/Users/Davy/AppData/Local/Youdao/YNote/markdown/index.html#怽M" style="box-sizing: border-box; color: #4078c0; text-decoration-line: none;"></a>怽M</h2><p data-source-line="75" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #333333; font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 22.4px; widows: 1; background-color: #ffffff;">包含玩家与同队伍玩家</p><ul data-source-line="78" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; padding-left: 2em; color: #333333; font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 22.4px; widows: 1; background-color: #ffffff;"><li style="box-sizing: border-box;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">开启相位后, 可见U有客体+公有客体</p></li><li style="box-sizing: border-box;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">队长视ؓ怽M, 单h? 自己为队?/p></li><li style="box-sizing: border-box;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">队伍其他成员׃n队长的私有相位客?/p></li><li style="box-sizing: border-box;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">队伍其他成员Ҏ自己的PublicPhasingID匚w目标对象的PublicPhasingID时可互相可见</p></li><li style="box-sizing: border-box;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">持有变量</p></li></ul><p data-source-line="88" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #333333; font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 22.4px; widows: 1; background-color: #ffffff;">怽开启时, 取PhasingID? 色实例ID</p><p data-source-line="90" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #333333; font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 22.4px; widows: 1; background-color: #ffffff;">怽关闭? 取PhasingID? ?</p><p data-source-line="92" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #333333; font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 22.4px; widows: 1; background-color: #ffffff;">PublicPhasingID</p><h2><a href="file:///C:/Users/Davy/AppData/Local/Youdao/YNote/markdown/index.html#可见规则" style="box-sizing: border-box; color: #4078c0; text-decoration-line: none;"></a>可见规则</h2><p data-source-line="98" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #333333; font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 22.4px; widows: 1; background-color: #ffffff;">当两个角色的PhasingID相等? M与私有客体互相可?/p><p data-source-line="100" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #333333; font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 22.4px; widows: 1; background-color: #ffffff;">当两个角色的PublicPhasingID相等? M与公有客体互相可?/p><p data-source-line="102" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #333333; font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 22.4px; widows: 1; background-color: #ffffff;">可以通过开兌|? 是否在可见的怽客体基础? 叠加世界角色(护送Q?</p><h2><a href="file:///C:/Users/Davy/AppData/Local/Youdao/YNote/markdown/index.html#U束" style="box-sizing: border-box; color: #4078c0; text-decoration-line: none;"></a>U束</h2><ul data-source-line="106" style="box-sizing: border-box; margin-top: 0px; padding-left: 2em; color: #333333; font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 22.4px; widows: 1; background-color: #ffffff; margin-bottom: 0px !important;"><li style="box-sizing: border-box;">玩家同时只能看见1个相?/li></ul><img src ="http://www.shnenglu.com/sunicdavy/aggbug/214817.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/sunicdavy/" target="_blank">战魂筑</a> 2017-04-08 14:41 <a href="http://www.shnenglu.com/sunicdavy/archive/2017/04/08/214817.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Golang的简单反性能试http://www.shnenglu.com/sunicdavy/archive/2016/08/12/214152.html战魂筑战魂筑Fri, 12 Aug 2016 07:26:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2016/08/12/214152.htmlhttp://www.shnenglu.com/sunicdavy/comments/214152.htmlhttp://www.shnenglu.com/sunicdavy/archive/2016/08/12/214152.html#Feedback0http://www.shnenglu.com/sunicdavy/comments/commentRss/214152.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/214152.html试用例

我们对Golang的结构体变量赋? 以及单参数函数调用进行反和native操作的测?pre>

 

package main

 

import (

"reflect"

"testing"

)

 

type data struct {

Hp int

}

 

const AssignTimes = 100000000

 

func TestNativeAssign(t *testing.T) {

 

v := data{Hp: 2}

 

for i := 0; i < AssignTimes; i++ {

v.Hp = 3

}

 

}

 

func TestReflectAssign(t *testing.T) {

 

v := data{Hp: 2}

 

vv := reflect.ValueOf(&v).Elem()

 

f := vv.FieldByName("Hp")

 

for i := 0; i < AssignTimes; i++ {

 

f.SetInt(3)

}

 

}

 

func TestReflectFindFieldAndAssign(t *testing.T) {

 

v := data{Hp: 2}

 

vv := reflect.ValueOf(&v).Elem()

 

for i := 0; i < AssignTimes; i++ {

 

vv.FieldByName("Hp").SetInt(3)

}

 

}

 

func foo(v int) {

 

}

 

const CallTimes = 100000000

 

func TestNativeCall(t *testing.T) {

for i := 0; i < CallTimes; i++ {

 

foo(i)

}

}

 

func TestReflectCall(t *testing.T) {

 

v := reflect.ValueOf(foo)

 

for i := 0; i < CallTimes; i++ {

 

v.Call([]reflect.Value{reflect.ValueOf(2)})

}

}

性能试数据

=== RUN TestNativeAssign
?PASS: TestNativeAssign (0.03s)
=== RUN TestReflectAssign
?PASS: TestReflectAssign (0.41s)
=== RUN TestReflectFindFieldAndAssign
?PASS: TestReflectFindFieldAndAssign (9.86s)
=== RUN TestNativeCall
?PASS: TestNativeCall (0.03s)
=== RUN TestReflectCall
?PASS: TestReflectCall (21.46s)

试评测

  • 在结构体变量赋值测试用例中, 我们发现TestReflectFindFieldAndAssign赋值格外的耗时. 分析性能点在FieldByNameq个函数? 我们查了下底层如何实现的:

// FieldByName returns the struct field with the given name

// and a boolean to indicate if the field was found.

func (t *structType) FieldByName(name string) (f StructField, present bool) {

// Quick check for top-level name, or struct without anonymous fields.

hasAnon := false

if name != "" {

for i := range t.fields {

tf := &t.fields[i]

if tf.name == nil {

hasAnon = true

continue

}

if *tf.name == name {

return t.Field(i), true

}

}

}

if !hasAnon {

return

}

return t.FieldByNameFunc(func(s string) bool { return s == name })

}

各位看官必须吐槽用for来遍历获取数? 但冷静下来分? q样做无可厚?
试想如果reflect包在我们使用ValueOf时用map~冲好一个结构体所有字D늚讉K数据? 肯定讉K指定字段速度会很?br>但是, 以空间换速度的需求其实最多满了1%的需?
同样的例子是囑ŞAPI里访问Shader变量的方? L默认使用字符串获? 速度很慢. 当你惛_速访问时, h前按需~存字段
那么, Golang使用的也是这L思\. 虽然暴力了一? 但是能够让程序跑? 性能优化的东西放在之后来? ~冲下就可以解决

  • 在调用测试用例中, 毫无悬念? 调用速度很慢
    因此, 我们在^时用反时, 量偏向于反变量缓冲存在下的变量赋值或者获?br>而调用的需求尽量减? 如果有goroutine存在的情况下, 则不必太多担?


战魂筑 2016-08-12 15:26 发表评论
]]>
服务器开发语a比较http://www.shnenglu.com/sunicdavy/archive/2016/01/05/212611.html战魂筑战魂筑Tue, 05 Jan 2016 08:51:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2016/01/05/212611.htmlhttp://www.shnenglu.com/sunicdavy/comments/212611.htmlhttp://www.shnenglu.com/sunicdavy/archive/2016/01/05/212611.html#Feedback10http://www.shnenglu.com/sunicdavy/comments/commentRss/212611.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/212611.html以下比较的基都是Z一U编E语a+一定的W三Ҏ者自q写的|络库和底层q行的,SkynetE微ҎQ但M比较合适放到比较中?/p>

C#

开发效率:Windows下可以通过VisualStudioq行开发,其他q_可以使用MonoDevelopQ非常方?/p>

q行效率QJIT的性能优化比较CQ能适应90%性能环境

部v便捷性:可以通过交叉~译生成其他q_的可执行文gQ通过monoq行可执行文?/p>

调试便捷性:VisualStudio和MonoDevelop调试均很方便Q?q可q程调试

上手度:对Cp语a熟悉的几天就可上?/p>

热更斎ͼ可以通过DLL方式q行

WebҎQ可做,代码比较啰嗦

崩溃处理Q可通过try catch捕获错误

|络库编写难度:一般,需注意gc问题

W三方网l库及框架数量:一?/p>

 

Golang

开发效率:?/p>

q行效率Qƈ发上非常有优势,对CPU利用率比较高Q原生运行无虚拟?/p>

部v便捷性:一ơ编译到处运行,无Q何运行库依赖

调试便捷性:实际操作中,单线E挂接调试器可行Q?但变量显CZ正确Q开发期基本采用日志方式q行查错

上手度:语言单,Ҏ少Q?新手1周能贡献代码

热更斎ͼ无法q行热更斎ͼ语言无法~译为DLLQ也不支持DLL加蝲Qlinuxq_?so加蝲忽略不计Q?/p>

WebҎQ非常方便, 代码_

崩溃处理Q崩溃后以命令行方式打印出栈Q程序内可以捕获M崩溃错误ql运?/p>

|络库编写难度:单,比C socket更简?/p>

W三方网l库及框架数量:偏少

 

Skynet(lua+C)

开发效率:Z动态语a的开发初ơ写比较快,后期l护和重构会耗费一定的旉在查错上

q行效率Q基于lua jit的运行效率还是能接受?/p>

部v便捷性:方便Q?只有底层修改需要重新编译, 大部分时间只用更新lua文g

调试便捷性:不是很方便,Z日志方式q行查错

上手度:lua语言Ҏ有部分和Cp语a有一定差异,ZActor模型的思想学习Q适应需要耗费一定的旉

热更斎ͼcM于ErlangQ可_到函数的热更新

WebҎQ有一些http支持Q通过C֌慢慢q行完善

崩溃处理Qlua天生可以捕获错误

|络库编写难度:自带Q无需~写

W三方网l库及框架数量:通过C֌慢慢完善

 

C++

开发效率:~译慢,文g多,通用库少

q行效率Qnative速度标杆

部v便捷性:~写各类的make门槛较高

调试便捷性:可通过VisualStudioq行Windowsq_调试

上手度:2~3q经验的熟手仍然会写出崩溃和泄露代码

热更斎ͼ可通过DLLq行

WebҎQ代码啰嗦,W三方库?/p>

崩溃处理QWindows下可使用SEH捕获D异常,其他q_只能通过崩溃后进行coredump分析Q容错非常差

|络库编写难度:Zasio~写较ؓ单,但M看来隑ֺ不低

W三方网l库及框架数量:较多

 

以下是得?/p>

image

 

从发文时的项目对q些语言使用率来_JavaQErlangQC++~写的服务器较多QGolangQJavaScriptQC#是第二梯队,Skynet׃上手不是很容易,所以仅有两位数的团队在使用Q但M表现q是比较?

对于老团队, C++的服务器工具铑֒框架已经相对成熟Q?完全没必要更换新语言Q?只是在对接sdk感觉困难Ӟ可以试Golangq些对web有优势的语言q行混合语言开?

对于新团队,开发效率,上手度和部v效率是优先选择的,C#QGolangQJavaScriptq些新兴语言会让你事半功?

对于大规模无需选服的服务器Q?Skynet的actor模型Ҏ展会比较Ҏ

对于大公司,好项目,上线后需要通过热更新进行bug修补的,C#QC++QErlang会是首?

 

但ȝ一点, q是Ҏ团队熟悉度来选择语言QN然的使用新语a的风险也是很大的

战魂筑 2016-01-05 16:51 发表评论
]]>
开源Golang游戏服务器框架cellnethttp://www.shnenglu.com/sunicdavy/archive/2015/10/16/212026.html战魂筑战魂筑Fri, 16 Oct 2015 03:44:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2015/10/16/212026.htmlhttp://www.shnenglu.com/sunicdavy/comments/212026.htmlhttp://www.shnenglu.com/sunicdavy/archive/2015/10/16/212026.html#Feedback6http://www.shnenglu.com/sunicdavy/comments/commentRss/212026.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/212026.html?方便,高效的Go语言的游戏服务器框架

func server() {
 
    pipe := cellnet.NewEventPipe()
 
    evq := socket.NewAcceptor(pipe).Start("127.0.0.1:7234")
 
    socket.RegisterSessionMessage(evq, coredef.TestEchoACK{}, func(content interface{}, ses cellnet.Session) {
        msg := content.(*coredef.TestEchoACK)
 
        log.Println("server recv:", msg.String())
 
        ses.Send(&coredef.TestEchoACK{
            Content: proto.String(msg.String()),
        })
 
    })
 
    pipe.Start()
 
}
 
func client() {
 
    pipe := cellnet.NewEventPipe()
 
    evq := socket.NewConnector(pipe).Start("127.0.0.1:7234")
 
    socket.RegisterSessionMessage(evq, coredef.TestEchoACK{}, func(content interface{}, ses cellnet.Session) {
        msg := content.(*coredef.TestEchoACK)
 
        log.Println("client recv:", msg.String())
 
    })
 
    socket.RegisterSessionMessage(evq, coredef.SessionConnected{}, func(content interface{}, ses cellnet.Session) {
 
        ses.Send(&coredef.TestEchoACK{
            Content: proto.String("hello"),
        })
 
    })
 
    pipe.Start()
}

 

目地址: https://github.com/davyxu/cellnet



战魂筑 2015-10-16 11:44 发表评论
]]>
pp助手服务器端支付的RSA的奇葩公钥解密设?/title><link>http://www.shnenglu.com/sunicdavy/archive/2015/10/12/211993.html</link><dc:creator>战魂筑</dc:creator><author>战魂筑</author><pubDate>Mon, 12 Oct 2015 06:27:00 GMT</pubDate><guid>http://www.shnenglu.com/sunicdavy/archive/2015/10/12/211993.html</guid><wfw:comment>http://www.shnenglu.com/sunicdavy/comments/211993.html</wfw:comment><comments>http://www.shnenglu.com/sunicdavy/archive/2015/10/12/211993.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.shnenglu.com/sunicdavy/comments/commentRss/211993.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/sunicdavy/services/trackbacks/211993.html</trackback:ping><description><![CDATA[<p>最q接入pp助手的服务器端支? 按照PP官方提供的文档来? 需要服务器做RSA的验? </p> <p>首先我们来看?/p> <h1>RSA的几个标准用?/h1> <h2>非对U加密解?/h2> <p>假设A要把内容传输lB</p> <p>1. B生成RSA的公钥和密钥, q是成对出现? 密钥由B保存, 把公钥告诉A</p> <p>2. A用B的公钥加密内? q把密文内容传输lB</p> <p>3. B用密钥解?/p> <h2>验证</h2> <p>证明某个内容是你发的, 而不是被别h冒名替, 例如git的push中就带有q个功能</p> <p>假设A有内?  B要验证内容确实由A发出</p> <p>1. A生成公钥和密?/p> <p>2. A内容做一个hash, 把hash码用自己的密钥加密ƈ把这D密文发lB</p> <p>3. B用A的公钥对密文q行验证, 卛_认密文是否由A发出</p> <p> </p> <p>可以看出, 两种用法都是典型的非对称用法</p> <p>但PP助手却干了g奇的事?</p> <h1>非对U当对称法加解?/h1> <p>在PP SDK官方文档? 我们扑ֈ了PHP语言的验证方? Ҏ里用了q样一个API</p> <p><a >openssl_public_decrypt</a></p> <p>从官Ҏ档看得出q个使用openssl的算法库</p> <p> </p> <p>cM? q有Java, C++, Python语言的处理方?/p> <p>其中, C++也是用的openssl, Python则是需要预~译C库,在Ubuntu下需要手工patch M2Crypto的_ssl.c文g.</p> <p> </p> <p>先不说这些非正规的编?patchҎ会造成多大的问? 单就q个用公钥解密就很蛋?/p> <p>从之前的RSA法中了? 只有对公钥进行验证的Ҏ, 也就是只能得到是q是不是的结? 但PP的SDK则要求必ȝ公钥解密?/p> <p>解出的数据ؓ一Djson, 以对比是否有订单改.</p> <p> </p> <p>那么q种做法q效于, 用最单的异或+一个公钥进行订单加? 然后同样用这个公钥进行解?/p> <p>只不q用RSA感觉很高U?/p> <p>q种做法一旦公钥在PP助手服务器或者玩家的开发服务器, 甚至源代码泄? 那么马上有很大的伪造订单的危险</p> <p> </p> <p>我把q个做法发给朋友? 他们? 其实PP助手的开发者只用了RSA, 跟传输不是明文就好了, 至于什么信息安? 都是?</p><img src ="http://www.shnenglu.com/sunicdavy/aggbug/211993.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/sunicdavy/" target="_blank">战魂筑</a> 2015-10-12 14:27 <a href="http://www.shnenglu.com/sunicdavy/archive/2015/10/12/211993.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对golang服务器开发模式的一些思?/title><link>http://www.shnenglu.com/sunicdavy/archive/2015/09/09/211784.html</link><dc:creator>战魂筑</dc:creator><author>战魂筑</author><pubDate>Wed, 09 Sep 2015 11:06:00 GMT</pubDate><guid>http://www.shnenglu.com/sunicdavy/archive/2015/09/09/211784.html</guid><wfw:comment>http://www.shnenglu.com/sunicdavy/comments/211784.html</wfw:comment><comments>http://www.shnenglu.com/sunicdavy/archive/2015/09/09/211784.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.shnenglu.com/sunicdavy/comments/commentRss/211784.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/sunicdavy/services/trackbacks/211784.html</trackback:ping><description><![CDATA[<h1>多线E?同步d模型</h1> <p>在我们的游戏目中用的golang服务器开发方式如?/p> <p>1.多线E逻辑</p> <p>2.同步d. 也就是说, 每个Z个线E?goroutine), ioU程=逻辑U程</p> <p>q种方式的优?</p> <p>1. 同步d方式与h的思维方式cd</p> <p>2. 逻辑处理性能有一定提?/p> <p>在大规模使用q种模式~写逻辑? 我们发现了这U模式只?个缺? <strong>~写者需要处理多U程关系</strong></p> <p>但这本n实直接致命? 回想C++时代, 多线E处理时, 调试重现的困䏀?脑补景象太惨不敢直视</p> <h1>单线E?异步多进E模?/h1> <p>在C++时代, 我曾l编写过一套asio的C++服务器框? 采用io多线E? 逻辑单线E? 依赖着C++高性能的优? 让开发便L单且无需兛_U程问题.</p> <p>那么Cgolang时代, Z么不能试下单U程异步多进E方式来~写逻辑?</p> <p>与多U程同步dҎ? 我们发现, 两者优~点互补. 那这回C领域选型问题? 对于游戏服务器需要的上手? 开发便? 压力降低(非MMO)q些特点来说, 单线E异步多q程再合适不q了</p> <p>那么, 我们在用golang~写单线E异步多q程服务器应该注意哪些点?</p> <p>1. socket处理完全装, 只通过channel抛出到逻辑U程排队处理</p> <p>2. 数据? rpc及其他io处理, 一律改为异步回调模? 不用同步接?/p> <p>3. 玩家存盘提交数据可以考虑复制q提交到存盘U程方式, 提高性能. </p> <p>4. 采用多进E架? 比如讄兌E? 把io压力分散到进E中</p> <p>5. 逻辑~写? 不允怋用go开U程及channel, 有需要提高性能部分需要单独编?/p> <p> </p> <h1>Actor模型的痛</h1> <p>cellnet在开发时本来考虑使用actor模型来进一步简化多U程逻辑的麻? l历了一D|间的原型开发后, 发现了一些问? 列D如下:</p> <p>1. golang的强cd不适合actor模型q种l常需要动态生成各cL息的模型, 但skynet(C+lua)/erlang有天生优势</p> <p>2. actor模型本n不是万能? 不能解决所有需? 特别是游?/p> <p>3. actor模型理解到应用有一定的隑ֺ. 本nq需要搭建框? 上手复杂</p> <p>M, 看过一些erlang及skynet的用? 没有应用的很U正且成熟的成功actor模型案例, 从传lsocket服务器框架跨到actor模型会扯到蛋, 因此, 后期cellnet会考虑回归到成熟的socket服务器框? 把架构做到简单上? 高扩展上.</p><img src ="http://www.shnenglu.com/sunicdavy/aggbug/211784.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/sunicdavy/" target="_blank">战魂筑</a> 2015-09-09 19:06 <a href="http://www.shnenglu.com/sunicdavy/archive/2015/09/09/211784.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>大服务器架构讨论http://www.shnenglu.com/sunicdavy/archive/2015/07/21/211321.html战魂筑战魂筑Tue, 21 Jul 2015 02:30:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2015/07/21/211321.htmlhttp://www.shnenglu.com/sunicdavy/comments/211321.htmlhttp://www.shnenglu.com/sunicdavy/archive/2015/07/21/211321.html#Feedback8http://www.shnenglu.com/sunicdavy/comments/commentRss/211321.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/211321.html最q参加了一个大服务器架构讨论活? 记录下心?

概述

游戏客户端采用Cocos2dx-Lua的纯Lua~写逻辑, 服务器采用Golang作ؓ开发语a

游戏cdcM于COC,因此无需选服. 需要用大服务器架构进行处?

数据?/b>

采用Mongodb做持久存? redis做跨服通信数据交换

使用UCloud的云技? 省去了烦人的q维工作

通信及协?/b>

客户端和服务器通讯使用HTTP短连? Zjson的数据封包协?

服务器间大量使用Golang自带的json+rpcq行通信

服务器类?/b>

服务器类型大致分为逻辑服务?战斗服务? 中心服务?

逻辑服务?/b>

逻辑服务器负责日帔R辑及公共逻辑处理(好友, 公会)

1个逻辑服务器对应一个区, n个区均用Ucloud云Mongodbq行数据存储

战斗服务?/b>

战斗服务器是一个集? 集群会返回一个负载最低的服务器返回?

战斗服务器通过cgo技术与客户端C++/lua的战斗逻辑q行逻辑复用, 在此技术上q行

战斗逻辑的校?

中心服务?/b>

客户端登陆前, 在中心服务器q里获得可登陆的逻辑服务器地址, 同时做一个负载均?

短连?

评h

׃操作pȝ的技术趋于稳? 同时, 手游的弱交互型导致的游戏架构于? 因此|络负蝲不再是游戏服务器技术的瓉. 从经验看? 游戏服务器技? 更重要的是还是看数据库的选型及处理方? 

虽然Mongodb的性能上不如内存数据库. 但是从存储安全性上要比个h搭徏的内存数据库? 安全

外加上云技术的引用, 性能的瓶颈和q维的技术复杂度q刃而解

Redis用于跨服数据交互那是再好不过的数据中介了, 保证速度和稳定? l对不是造轮子能比拟?

短连接在手游上处理v来比长连接简单一? 无需做断UKq? 服务器的底层也是由Golang的框架库保证质量? 因此负蝲毫无问题. 服务器对内及对外均用jsonq行数据交换, 化了协议处理. 也方便了调试

json rpc的性能损耗对于整个逻辑的处理来说均可以忽略不计



战魂筑 2015-07-21 10:30 发表评论
]]>
游戏数据库选型mysql,mongo, redis, memcachedhttp://www.shnenglu.com/sunicdavy/archive/2015/06/19/210992.html战魂筑战魂筑Fri, 19 Jun 2015 08:23:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2015/06/19/210992.htmlhttp://www.shnenglu.com/sunicdavy/comments/210992.htmlhttp://www.shnenglu.com/sunicdavy/archive/2015/06/19/210992.html#Feedback5http://www.shnenglu.com/sunicdavy/comments/commentRss/210992.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/210992.html数据库选择历程

我们的项目一直用MySQL作ؓ数据? 无论是从C++的服务器, q是到Golang服务? 当年搞服务器? 看大部分人都是用SQL(MySQL/SQLServer), 而Mongo感觉像邪教一? 再加上服务器q是Linux比较正统, 所以果断选了MySQL.

刚开始感?游戏服务器的数据存储其实应该是蛮圣的过E? 那么多的数据, 需要按照MySQL一样分? 分字D存? Z查询, q要乖乖的学一下SQL的语?/p>

p么折腾了几年. 在云DB的蒙蔽下, 一直认为MySQL是做游戏服务器存储的专业技? 分布式和存储压力一定交l云DB来做. 直到真正试了下NoSQL在游戏服务器开发里的思\.

用了Golang, 才发现同步写逻辑是多么的优雅.

用了NoSQLpd的数据库, 才意识到: 游戏服务器的数据存储和游戏服务器的存盘两个概念差异其实蛮大的.

MySQL? 背包其实跟角色完全没有关p? 只是通过1个角色id映射q去, Zؓ的割裂了数据的关联? q硬生生的整Z概念叫结构化查询让你?/p>

NoSQL? 只是把数据库当成是存储点, 每个角色的数据是完整的一? 里面怎么存随你便. 每个角色通过id来查? 其他都没有了

于是? 游戏开发变得异常简? MySQL角色q门查询4~5ơ才能搞定要的数?而NoSQL一口气全查出来, 存盘也无需增量, 直接存盘可以了

所以现在觉? NoSQL的思\对于游戏服务器存储来说简直是完美?

转蝲h? 战魂筑http://www.shnenglu.com/sunicdavy

 

NoSQL数据库方案对?/h1>

NoSQL下实现方案很? 游戏常用的就q么3? mongo, redis, memcached

下面说下优缺?/p>

mongo

盘映射内存数据?/p>

value为documentcd, ZBSON的value序列?/p>

应用场景:

适合多写读, 例如日志和备?/p>

转蝲h? 战魂筑http://www.shnenglu.com/sunicdavy

 

redis

内存数据?/p>

单核

value限制512M

多种valuecd, 游戏用途用私有的序列化协?例如protobuf)

支持落地(bgsave)

用户: 新浪, 淘宝, Flickr, Github

应用场景: 适合d都很? 数据处理复杂{?/p>

转蝲h? 战魂筑http://www.shnenglu.com/sunicdavy

 

memcached

内存数据?/p>

多核

value限制1M

不支持落?持久?

用户: LiveJournal、hatena、Facebook、Vox

应用场景: 动态系l中的缓? 适合多读写

转蝲h? 战魂筑http://www.shnenglu.com/sunicdavy

个h评h

memcached 适合|页~冲, 游戏里很有使用. 目前只有腾讯云支持云memcached

redis非常适合游戏的内存数据库, 但是落地{略会比较复? 需要具体分? 可以参考后面的链接看下云风怎么处理q个问题

mongo数据库在早期q是非常不错的NoSQL的数据库. 工具比较方便, 可视? 但是随着q年来游戏的q发度越来越? 所以ؓ了一ơ到? 很多是选择了redis

下图参考自知乎问题. 链接在后面有提示, 若R权请联系删除

转蝲h? 战魂筑http://www.shnenglu.com/sunicdavy

image

参考链?

    谈谈陌陌争霸在数据库斚wt过的坑( Redis ?

http://blog.codingnow.com/2014/03/mmzb_redis.html

转蝲h? 战魂筑http://www.shnenglu.com/sunicdavy

Memcache,Redis,MongoDBQ数据缓存系l)ҎҎ与分?/p>

http://blog.csdn.net/suifeng3051/article/details/23739295

 

http://www.zhihu.com/question/31417262



战魂筑 2015-06-19 16:23 发表评论
]]>
golang的一个线E调度被停止的问题处?/title><link>http://www.shnenglu.com/sunicdavy/archive/2015/01/30/209677.html</link><dc:creator>战魂筑</dc:creator><author>战魂筑</author><pubDate>Fri, 30 Jan 2015 08:25:00 GMT</pubDate><guid>http://www.shnenglu.com/sunicdavy/archive/2015/01/30/209677.html</guid><wfw:comment>http://www.shnenglu.com/sunicdavy/comments/209677.html</wfw:comment><comments>http://www.shnenglu.com/sunicdavy/archive/2015/01/30/209677.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/sunicdavy/comments/commentRss/209677.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/sunicdavy/services/trackbacks/209677.html</trackback:ping><description><![CDATA[<p>最q发? golang写的游戏服务? 在非调试状态下, 一切正? 但是在挂接gdb调试? 无法收到|络消息. 打了很多日志, 发现, 只要有goroutine的地? 都没有切换进? </p> <p>回想了下, goroutine的调度规? 1.4之前, 在碰到syscall? goroutine会被调度q处? 1.4? 只要有函数调用时, 均会q行一ơ调? 密度比以前增加了, 更加接近真线E的处理. </p> <p>Ҏq个原理, 问题应该出现在服务器底层没有l系l提供调度机会的点上. 我们的服务器通过一个bool型的chanq行d, 让服务器l持dq行消息处理不退? 但是最qؓ了在windows下提供命令行支持, 增加了一些代? 如下</p> <div id="ygc4mqy" class="csharpcode"><pre class="alt"><span id="eqm8cc8" class="lnum"> 1: </span>func WaitForExit() {</pre><pre><span id="448k8co" class="lnum"> 2: </span> </pre><pre class="alt"><span id="so4wuwu" class="lnum"> 3: </span> <span id="cu844so" class="kwrd">if</span> len(peerMap) == 0 {</pre><pre><span id="a4kge84" class="lnum"> 4: </span> log.Println(<span id="ok8kkeu" class="str">"no peer running, exit!"</span>)</pre><pre class="alt"><span id="aomke8y" class="lnum"> 5: </span> <span id="ogoeia4" class="kwrd">return</span></pre><pre><span id="88qe8wm" class="lnum"> 6: </span> }</pre><pre class="alt"><span id="yi4y8eo" class="lnum"> 7: </span> </pre><pre><span id="q8ky4ww" class="lnum"> 8: </span> <span id="eyu444e" class="rem">// 命o行功能只在windows下启?/span></pre><pre class="alt"><span id="48s4s44" class="lnum"> 9: </span> <span id="g8i844y" class="kwrd">if</span> runtime.GOOS == <span id="s8mi84y" class="str">"windows"</span> {</pre><pre><span id="4eci44m" class="lnum"> 10: </span> reader := bufio.NewReader(os.Stdin)</pre><pre class="alt"><span id="84w4uwc" class="lnum"> 11: </span> </pre><pre><span id="48wio4k" class="lnum"> 12: </span> var running <span id="c4oieqw" class="kwrd">bool</span> = <span id="eamiks8" class="kwrd">true</span></pre><pre class="alt"><span id="ikes8ks" class="lnum"> 13: </span> </pre><pre><span id="8ie4i4k" class="lnum"> 14: </span> go func() {</pre><pre class="alt"><span id="cm8essy" class="lnum"> 15: </span> select {</pre><pre><span id="m4i4ucs" class="lnum"> 16: </span> <span id="444i4ee" class="kwrd">case</span> <-exitChan:</pre><pre class="alt"><span id="ug444c4" class="lnum"> 17: </span> running = <span id="q4m4g44" class="kwrd">false</span></pre><pre><span id="wq4i8mo" class="lnum"> 18: </span> }</pre><pre class="alt"><span id="466e44m" class="lnum"> 19: </span> }()</pre><pre><span id="c4g8c8e" class="lnum"> 20: </span> </pre><pre class="alt"><span id="uwiu84i" class="lnum"> 21: </span> <span id="o8s844u" class="kwrd">for</span> running {</pre><pre><span id="844ka44" class="lnum"> 22: </span> data, _, _ := reader.ReadLine()</pre><pre class="alt"><span id="ke884uk" class="lnum"> 23: </span> command := <span id="yc8iiy8" class="kwrd">string</span>(data)</pre><pre><span id="44y48e4" class="lnum"> 24: </span> </pre><pre class="alt"><span id="8waoaiy" class="lnum"> 25: </span> dispatchConsoleCommand(command)</pre><pre><span id="8844a84" class="lnum"> 26: </span> }</pre><pre class="alt"><span id="gq8m8ks" class="lnum"> 27: </span> } <span id="4aug4ge" class="kwrd">else</span> {</pre><pre><span id="g44siay" class="lnum"> 28: </span> <span id="iucyaaa" class="rem">// Linux环境</span></pre><pre class="alt"><span id="keo8mq8" class="lnum"> 29: </span> <-exitChan</pre><pre><span id="acgkomc" class="lnum"> 30: </span> }</pre><pre class="alt"><span id="aug8g8o" class="lnum"> 31: </span> </pre><pre><span id="i8qqgo8" class="lnum"> 32: </span>}</pre></div> <style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> <p>我暂时屏蔽了新加的这套功? l持<-exitChan, 问题马上解决</p> <p>l合前面的猜? 我估计在reader.ReadLine()函数? 没有l底层提供调度的Z, D其他goroutine无法q行, 造成服务器卡?/p> <p>技术讨论群:  309800774 Ƣ迎golang爱好者加? U技术研?/p><img src ="http://www.shnenglu.com/sunicdavy/aggbug/209677.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/sunicdavy/" target="_blank">战魂筑</a> 2015-01-30 16:25 <a href="http://www.shnenglu.com/sunicdavy/archive/2015/01/30/209677.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C/C++服务器架构机制设计ȝhttp://www.shnenglu.com/sunicdavy/archive/2014/12/18/209225.html战魂筑战魂筑Thu, 18 Dec 2014 08:39:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2014/12/18/209225.htmlhttp://www.shnenglu.com/sunicdavy/comments/209225.htmlhttp://www.shnenglu.com/sunicdavy/archive/2014/12/18/209225.html#Feedback1http://www.shnenglu.com/sunicdavy/comments/commentRss/209225.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/209225.htmlq期在写Zgo的游戏服务器框架, 在全面脱C/C++? 需要对老架构进行一个ȝ

ZC/C++游戏服务器框架M设计的还是不错的, 兄弟们M使用效果都是好评. 因ؓ在技术上喜欢"h", 所以在很多设计? 都是力求? 高效(开发效?.

Zd的异步DB查询pȝ, 带多重异步的同步

代码CZ:

   1:   
   2:  void BatchQueryPlayerInfo( uint32 ClientID, const std::string& AccountName, int64 CharID )
   3:  {
   4:      GDBExecutor->Commit
   5:          (    
   6:          dynamic_cast<DBDataTask*>( (new DBQueryCharInfo(  ClientID, CharID ) ) 
   7:          ->LinkAtomTask( new DBQueryQuest( ClientID, CharID ) )
   8:          ->LinkAtomTask( new DBQuerySkill( ClientID, CharID ) )
   9:          ->LinkAtomTask( new DBQueryHero( ClientID, CharID ) )
  10:          ->LinkAtomTask( new DBQueryAccountInfo( ClientID, AccountName ) )
  11:          ->LinkAtomTask( new DBQueryEquip( ClientID, CharID ) )
  12:          ->LinkAtomTask( new DBQueryObject( ClientID ,CharID ) )
  13:          ->LinkAtomTask( new DBQueryLevel(ClientID, CharID))
  14:          ->LinkAtomTask( new DBQueryChapter(ClientID, CharID))
  15:          ->LinkAtomTask( new DBQueryActivity( ClientID, CharID ))
  16:          )
  17:          );
  18:   
  19:  }

q段主要处理玩家在登陆时, 需要从DB查询大量的不同分cȝ数据. Z保证效率, 我让每个Taskq行执行, 然后通过一个机? 让所有Q务完成后, 回调W一个Q务的一个函? q样无需手动实现很多_合代码, 避免了反复调试和错误

Zprotobuf反射机制的语句自动合?/strong>

   1:  DBUpdateCharInfo::DBUpdateCharInfo( int64 CharID, const std::string& Buffer )
   2:  {
   3:      char buffer[256];
   4:   
   5:      sprintf( buffer, "update tb_char set $FIELD$ where charid = %lld;", CharID );
   6:          
   7:      ExecuteCommand( buffer, Buffer, dbopr::FET_Equation );
   8:  }

q段是一个典型的DBd, 构造函数提供了CharID和一个由l构体序列化好的buffer, $FIELD$字段, 是通过反射ҎBuffer内容, 自动填充字段

q段例子? $FIELD$可以填充?hp=100, mp=100之类? 自动填充避免了因为添加字D늚到处d代码, q需要调? Ҏ搞错

 

配置pȝ概念

Z同一个配|系l? 分层实现不同的需? 更简单的? 解决?个实际问题是:

自己改了配置文g中的ip, 上传svn? 覆盖了别人的配置, 很多人的解决Ҏ都是, 本地配置不提? 但同旉题又来了:

当配|中有别人新加的pȝ配置, 怎么保证每个人都能更新到?

上线? 服务器交付运l? 他们会对配置有一定程度的修改, q个时候怎么合ƈE序配置和运l配|?

其实对于冲突的需? 只要对系l进行分层就可以解决问题,我的处理方式:

配置分ؓ:

全局配置: 所有服务的M配置

单服务配|? 本服务的配置, 涉及|络及逻辑

本地配置: q个配置每个Z? 不上传SVN

命o行配|? 格式和前面的一? q块可以通过q维q行配置

Ml构其实是OO的派生概? 下层可以覆盖, 修改上层的配|?/p>

 

服务器互联及识别框架

基本功能: Z一些简单的配置可以将多台服务? 同种cȝ不同服务器互相连接v? 断线自动重连.

服务器连接后, 所有服务器可知晓ƈ可自动按需q接

逻辑端也很方便的q行q播或者单独发送等

也就是说, 每个服务器的q接和接受端都是带识别名U或id?

后面觉得q套东西实在是做的复? 多整ZC心服务器来做. 但好Ҏ架稳定下来了, 也就好了.

 

Zlua的服务器web后台框架

思想是很不错?  C++ 配合lua本nl对是个p|

问题出在web处理,本n都是一个同步阻塞过E? 而这个后台框架是异步方式来做, 所以特别别?/p>

不过比v以前的本地GMpȝ, q块的设计是伟大的进?/p>

 

现在正在设计Zgolang的服务器框架, 基本框架已经完工, {待~写逻辑后的实战试

以上的很多思想在golang的服务器框架都有改进, 特别是golang本n做web也是优秀? 外加martiniq种牛X框架, 更是水到渠成

如果你对服务器框架设计有特别的认? 或者想撞思想, 可以加博客群 309800774或者我的qq: 20998333讨论



战魂筑 2014-12-18 16:39 发表评论
]]>
在liteide中, 自动getW三方包http://www.shnenglu.com/sunicdavy/archive/2014/11/27/208971.html战魂筑战魂筑Thu, 27 Nov 2014 09:19:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2014/11/27/208971.htmlhttp://www.shnenglu.com/sunicdavy/comments/208971.htmlhttp://www.shnenglu.com/sunicdavy/archive/2014/11/27/208971.html#Feedback2http://www.shnenglu.com/sunicdavy/comments/commentRss/208971.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/208971.htmlLiteIDE中有一个get按钮可以模拟go get –v 的操?/p>

image

但默认因为找不到git而报错?解决Ҏ如下Q?/p>

?a title="http://git-scm.com/downloads" >http://git-scm.com/downloads下蝲对应q_git

在LiteIDE的查?>~辑环境变量中, 修改PATHQ?加入git路径。例?/p>

PATH=c:\mingw64\bin;%GOROOT%\bin;c:\Program Files (x86)\Git\bin;%PATH%

再按下Get键, W三方包׃自动更新?/p>

战魂筑 2014-11-27 17:19 发表评论
]]>
Linux x64q_golua的安装及使用http://www.shnenglu.com/sunicdavy/archive/2014/03/18/206207.html战魂筑战魂筑Tue, 18 Mar 2014 04:51:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2014/03/18/206207.htmlhttp://www.shnenglu.com/sunicdavy/comments/206207.htmlhttp://www.shnenglu.com/sunicdavy/archive/2014/03/18/206207.html#Feedback0http://www.shnenglu.com/sunicdavy/comments/commentRss/206207.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/206207.htmlq里使用的golua版本?a title="https://github.com/aarzilli/golua" >https://github.com/aarzilli/golua

按照作者的安装Ҏ在天朝行不通的, 原因你懂?/p>

因此q入q个链接, 点击双的Download ZIP下蝲快照?/p>

下蝲好后攑ֈ你的GOPATH指定路径, 整理路径如下

github.com\aarzilli\golua\

其下的目录如?/p>

example\
    lua\
    LICENSE
    README.md
    TODO

然后准备lua5.1的开发包

lua-5.1.4.tar.gz

q有2个第三方依赖?/p>

readline-6.2.tar.gz

ncurses-5.9.tar.gz

直接configure ?gt; make install 装好

 

go env认你的GOPATH已经指向你的开发目?/p>

golua默认使用cgoq行~译, 可能会报? 修改lua.go的cgo定义如下

#cgo linux,!llua,!luaa LDFLAGS: -llua -lm –ldl

q入$GOPATH\src\github.com\aarzilli\golua\lua

执行go install

完成



战魂筑 2014-03-18 12:51 发表评论
]]>
[转]Go 1.3+ ~译器变?/title><link>http://www.shnenglu.com/sunicdavy/archive/2014/01/22/205525.html</link><dc:creator>战魂筑</dc:creator><author>战魂筑</author><pubDate>Wed, 22 Jan 2014 04:23:00 GMT</pubDate><guid>http://www.shnenglu.com/sunicdavy/archive/2014/01/22/205525.html</guid><wfw:comment>http://www.shnenglu.com/sunicdavy/comments/205525.html</wfw:comment><comments>http://www.shnenglu.com/sunicdavy/archive/2014/01/22/205525.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/sunicdavy/comments/commentRss/205525.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/sunicdavy/services/trackbacks/205525.html</trackback:ping><description><![CDATA[<h3>概述</h3> <p>目前Go~译器是C写的Q是时候换成Go啦?<h5>背景</h5> <p>“gc"Go工具链来自Plan 9~译器的工具链。组装器、C~译器和链接器基本没变。Go的编译器(cmd/gc,cmd/5g,cmd/6g,cmd/8g)是配合工具链写的新的CE序?<p>目起始Ӟ用C而不是Go写编译器有很多好处。突出的比如Q首先,那时候Goq不存在Q没法儿写编译器。而且实际上,q存在Q也会经常有明显的不兼容的变化。用C不用Go可以避免初始和持l开发导致的问题。然而如今Go 1已经E_Q所以这些持l的问题减少了很多?<p>持箋开发的问题已经消除Qؓ了让Go实现的编译器比C更有吸引力,另一些工E问题出玎ͼ <ul> <li> <p>写正的Go代码比写正确的C代码更容易?/p> <li> <p>调试错误的Go代码比调试错误的C代码更容易?/p> <li> <p>使用Go~译器需要对Go有一定理解。而用C~译器还需要一定理解C?/p> <li> <p>Go使ƈ发执行比C更方ѝ?/p> <li> <p>Go有更好的标准支持模块化,自动重写Q单元测试和性能分析?/p> <li> <p>Go比C更有?fun)?/p></li></ul> <p>Z以上理由Q我们相信是时候用Go写Go~译器啦?<h5>计划设想</h5> <p>我们打算用自动化译工具来用Go重写现在C的编译器。这个翻译需要一些阶D,从Go 1.3开始持l到未来的发行版?<p>W一阶段。开发和调试一个自动化译工具。这可以在日常开发时同步q行。而且Qh们还可以在这个阶DؓC~译器l改q。这个工具工作量很大Q不q我们有信心完成q个Ҏ使命的工兗有许多C的观忉|法儿直接转换成GoQmacros(?Qunions(联合Q共用体,)Qbit fields(位域)可能最先考虑。比较幸q(不是巧合Q,q些功能功能用的,都会被翻译掉。指针运和数组也需要一些{换工作,管~译器里很少。编译器里主要是tree(?和linked list(链表)。翻译工具会保留注释和C代码的结构,所以翻译后的代码和当前的编译器代码一样可阅读?<p>W二阶段。用译工具转换C代码到GoQƈ删除C源码。这时我们已l开始翻译,但是Goq是q行在C~译器上。非怹观的Q这可能发生在Go 1.3。不q更可能是Go 1.4?<p>W三阶段。用一些工P可能来自gofix和the Go oracleQ拆分编译器到包Q清理和文档化代码,d适当的单元测试。这是编译器会是地道的GoE序。目前打在Go 1.4实现?<p>W四a阶段。用标准的分析和测试工具优化编译器的CPU和内存用。可能要引入q行。如果真q样Q?a >Race Detector</a>(Go的ƈ行竞争检工?)会有很大帮助。这目标在Go 1.4Q可能部分会延后?.5。基本的优化分析会在W三阶段完成?<p>W四b阶段。(和四a几段同时q行Q当~译器依照明昄界限分割成包之后Q需要明引入一个中介码Q在l构无关的无序树(Node_s)和结构相关的有序链表(Prog_s)之间。这个中介码应该不依赖整体架构,但是包含准确的执行顺序信息,可以用于有顺序但是结构无关的操作的优化,比如清理多余的nil和出界。这些过E基?a >SSA</a>Q静态单赋|Q你可以从Alan Donovan?go.tools/ssa 包中了解更多?<p>W五阶段。替换go/parser和go/types到最斎ͼ全新Q的版本。Robert Griesemer参考现在的l验Q讨Z设计新的parser和types的可能。如果联pM们到~译器后端,怿对设计新的API有很大帮助?<p><strong>自展QBootstrappingQ?/strong>用Go语言实现的Go的编译器Q从一开始就要考虑如何自展。我们考虑的规则就是Go1.3~译器必ȝGo1.2~译QGo1.4的编译器必须由Go1.4~译Q以此类推?<p>q时Q我们就有了一个清晰的程来生成当前的E序Q编译Go1.2的工具链Q由C~写Q,然后使用它编译Go1.3的工具链Q以此类推。这里需要一个脚本来做这个事情,来保证只会消耗CPU的时间而非某个人的旉。这L自展Q每个机器只会做一ơ,Go1.x的工具链会在本C留,q在执行all.bash来编译Go1.(x+1)工具铄时候被再次使用?<p>昄Q随着旉的推U这U自举方式是不充分的。在后面的多个版本被发布之前Qؓ~译器写一个后端来生成C代码也许是一个更有意义的事情。这些C代码不要求效率或可读性,只要正确卛_。这些C代码会被签入,像我们{օ由yacc生成的y.tab.c文g一栗这P自展q程׃变成Q先用gcc~译C代码生成一个自展编译器Q然后用这个自展编译器来编译真正的~译器。类g另一个自展过E,q个自展~译器将会在本地保留Qƈ在每ơ执行all.bash的时候重复用(不用重新~译Q?<p><strong>替代选择</strong>q有一些比较明昄替代ҎQ需要我们说明一下ؓ什么放弃了q些选择?<p>从一开始写一个编译器。现在的~译器有一个非帔R要的特征Q他们能够正常工作(或者其臛_能够满所有用L要求Q。尽Go语言比较单,但是~译器中有很多细微的l节优化和改写,直接丢弃10或数q的在这上面的努力是比较愚蠢的?<p>对编译器q行人工译。我们已l以人工的方式翻译了一部分C/C++代码到Go语言了。这个过E是枯燥而且易错的,且这些错误非常的l微及难以发现。相反,使用机械译会Ş成一些比较一致的错误Q而这些错误是易于发现的;而且不会因ؓ枯燥的过E开差。Go~译器的代码明显的比我们译的代码多很多Q超q?0,000行C代码Q机械翻译会使这个过E容易一些。就像Dick Sites?974q说的一P“相比写E序Q我宁愿写一个程序来帮我写程序。?使用机械来翻译编译器也方便于在准备好切换之前Q我们可以l开发完善现有的CE序?<p>只翻译后端ƈ链接到go/parser和go/types.从前端传l后端的数据l构所包含的信息中Qgo/parser和go/types所能提供的除了API没其他的东西了。如果用这些库来替代前端,需要写代码来{换go/parser和go/types所能提供数据结构到后端Q这是一个非常宽泛且易出错的工作。我们相信用这些库是有意义的,但更明智的是Q等到将~译器代码调整的更像GoE序Q分成确定边界的、包含说明文档和单元试子包之后再用?<p>攑ּ现有的编译器Q用gccgoQ或者go/parser + go/types + LLVM, …)。现有的~译器是Go语言昑־比较灉|的一个重要组成部分。如果尝试用基于大量代码的GCC或LLVM来开发GoE序Q感觉会有碍到Go语言的灵zL。另外,GCC是大量C代码Q现在有部分C++Q、LLVM是大量C++代码的程序。以上列丄、用于解释不使用现有~译框架代码的几个原因,也都适用于更多的cM的代码库?<h5>C语言的长期?/h5> <p>临近l束Q这个计划还留下了由C写成的Plan9的工具链的一部分。在长期发展中,q是所有的C从代码树排除掉比较好。本章节推测了一下这件事会如何发生Q但不保证其指定会发生或者按照这U套路发生?<p>q行时包(runtime)?runtime包的大部分都是用C写成Q基于一些同L原因QGo~译器也是用C实现。但是,runtime包远比编译器的代码量要小Q且它现在已l是用Go和C混合~写。将C代码转换为Go代码Ӟ一ơ{化一部分貌似也是可行的。其中,主要部分有:调度器(schedulerQ,垃圾回收Qthe garbage collectorQ,散列映射表(hash mapQ的实现Q和channel的实现。(q里Go和C代码混合的很融洽Q是因ؓq里使用?c而不是gcc来编译的C代码。) <p>C~译器?Plan 9的C~译器本w就是用C写成Q如果我们要从Go包实现里面移除所有的C代码Q那么我们将U除q些~译工具Q“go tool 6c”等{,另外Q?c的文件也不被支持出现的Go包的目录里面。我们应该提前声明这L计划Q以便用C的第三方包有旉ȝ除这cC代码的用。(CgoQ由于用了gcc来替?cQ所以它仍然可以作ؓ一个途径来在Go包中使用C实现部分功能。)在Go1的兼Ҏ文档中没有包含工具链修改的描述Q也是说去掉C~译器是被允许的?<p>汇编器?Plan 9的汇~器也是用C实现的,但这个汇~器只不q是一pd解析树组成的单解析器Q这使得不论手动q是自动它译成Go语言都比较简单?<p>q接器?Plan 9的连接器也是由C写成。最q的一些工作,已经大部分的连接器工作攑ֈ的编译器中,而且Q也已经有个计划剩余的部分重写成一个新的、更单的GoE序。{Ud~译器的部分q接器代码,现在需要随着~译器的原有代码一赯行翻译?<p>ZLibmach的工? nm, pack, addr2line, 和objdump?Nm现在已经使用Go语言重写。Pack和addr2line可以M一天被重写。Objdump现在依赖于libmach的反汇编器,但这些{换ؓGo也是比较单的Q不论是使用机械q是人工译。所以基于这几点Qlibmach本n来也可以被U除?<p>  <p>来源: <a >http://www.oschina.net/translate/go-1-3-compiler-overhaul</a> <p>英文来源:<a title="https://docs.google.com/document/d/1P3BLR31VA8cvLJLfMibSuTdwTuF7WWLux71CYD0eeD8/preview?sle=true&pli=1" >https://docs.google.com/document/d/1P3BLR31VA8cvLJLfMibSuTdwTuF7WWLux71CYD0eeD8/preview?sle=true&pli=1</a></p><img src ="http://www.shnenglu.com/sunicdavy/aggbug/205525.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/sunicdavy/" target="_blank">战魂筑</a> 2014-01-22 12:23 <a href="http://www.shnenglu.com/sunicdavy/archive/2014/01/22/205525.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>go语言开发环境LiteIDE自动完成功能失效解决Ҏhttp://www.shnenglu.com/sunicdavy/archive/2014/01/03/205147.html战魂筑战魂筑Fri, 03 Jan 2014 11:10:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2014/01/03/205147.htmlhttp://www.shnenglu.com/sunicdavy/comments/205147.htmlhttp://www.shnenglu.com/sunicdavy/archive/2014/01/03/205147.html#Feedback2http://www.shnenglu.com/sunicdavy/comments/commentRss/205147.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/205147.html比较qLiteIDE和eclipse+goclipse, 最后还是觉得LiteIDEz?但发现其自动完成功能偶尔会出? 随即搜烦, 发现其用gocode的一个开源项目开了一个简单服? 为各UIDE提供高速的自动完成服务.在goclipse环境发现其报了版本不匚w的错, 而最qgo的更C是很频繁, 所以觉得应该是gocode版本q老造成.

搜烦到gocode的开发页?a >https://github.com/nsf/gocode  l果发现nsfq家伙居然也是luaBridge的作?

下蝲最新的gocode代码, 解压? ~译:

windows下命令行

go build gocode.go autocompletecontext.go autocompletefile.go client.go config.go cursorcontext.go decl.go declcache.go formatters.go os_windows.go package.go ripper.go rpc.go scope.go server.go utils.go

linux? 只需要将os_windows.go换ؓos_posix.go卛_

~译完成? 可执行文ggocode覆盖到liteIDE下的同名文g, 杀掉gocodeq程后重启liteIDE卛_

image



战魂筑 2014-01-03 19:10 发表评论
]]>
luabind 0.9.1在boost 1.49+和gcc-4.6.3以上版本的编译问题处?/title><link>http://www.shnenglu.com/sunicdavy/archive/2013/09/24/203409.html</link><dc:creator>战魂筑</dc:creator><author>战魂筑</author><pubDate>Tue, 24 Sep 2013 08:46:00 GMT</pubDate><guid>http://www.shnenglu.com/sunicdavy/archive/2013/09/24/203409.html</guid><wfw:comment>http://www.shnenglu.com/sunicdavy/comments/203409.html</wfw:comment><comments>http://www.shnenglu.com/sunicdavy/archive/2013/09/24/203409.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/sunicdavy/comments/commentRss/203409.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/sunicdavy/services/trackbacks/203409.html</trackback:ping><description><![CDATA[<p>boost更新?.53? 发现luabindL~译不过, 报错如下</p> <p>error: missing binary operator before token "("</p> <p>Ҏ老外的描q? boost中的BOOST_PP_ITERATION_FLAGS?.49版本后发生了一些变?</p> <p>在git扑ֈ一个patch, 链接<a >在此</a></p> <p>以下单描q?/p> <p>修改call_function.hpp, call_member.hpp及wrapper_base.hpp</p> <p>L#elif BOOST_PP_ITERATION_FLAGS() == 1</p> <p>更换?/p> <p>#else</p> <p>#if BOOST_PP_ITERATION_FLAGS() == 1</p><pre><p>然后在源码底部加一?endif卛_</p></pre><img src ="http://www.shnenglu.com/sunicdavy/aggbug/203409.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/sunicdavy/" target="_blank">战魂筑</a> 2013-09-24 16:46 <a href="http://www.shnenglu.com/sunicdavy/archive/2013/09/24/203409.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>捕获LinuxD错?Segment fault)q且打印错误堆栈http://www.shnenglu.com/sunicdavy/archive/2012/12/29/196809.html战魂筑战魂筑Sat, 29 Dec 2012 09:53:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2012/12/29/196809.htmlhttp://www.shnenglu.com/sunicdavy/comments/196809.htmlhttp://www.shnenglu.com/sunicdavy/archive/2012/12/29/196809.html#Feedback3http://www.shnenglu.com/sunicdavy/comments/commentRss/196809.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/196809.htmlLinux上跑服务器如果遇到程序崩溃是一件很苦恼的事? 再碰到重现很隄BUG, 估计只能通过传统的排查方法进?

在编写本文前, W者用过诸如libunwind{库q行错误时堆栈打? 但是其本w由于需要引用第三方? 使用q是E微ȝ.

l过Google? 居然扑ֈ一?a >好文, 光过捕获SIGSEGV信号, q迫使程序进入gdb调试阶段, 利用gdb强大的调试功能可以进行各U错误跟t? 此法已与Windows下程序崩溃后弹出VC调试几乎接近.

我在此文基础? 扩展了其通用性及便利?/p>

1. 使用gdb?-ex参数, 在挂接程序后, 执行bt指o打出E序堆栈

2. 信息重定向到自定义的文?在多q程都需要进行后台输出时带来更大的灵zL? 同时也解决了gdb只能在前台调试的问题

代码如下

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>

void dump(int signo)
{
        char buf[1024];
        char cmd[1024];
        FILE *fh;

        snprintf(buf, sizeof(buf), "/proc/%d/cmdline", getpid());
        if(!(fh = fopen(buf, "r")))
                exit(0);
        if(!fgets(buf, sizeof(buf), fh))
                exit(0);
        fclose(fh);
        if(buf[strlen(buf) - 1] == '/n')
                buf[strlen(buf) - 1] = '/0';
        snprintf(cmd, sizeof(cmd), "gdb %s %d -ex=bt > ./a.txt", buf, getpid());
        system(cmd);

        exit(0);
}

在服务器开启时,d signal(SIGSEGV, &dump ); q行信号处理挂接卛_

 

 

引用: http://blog.csdn.net/kakaka2011/article/details/6597857  作? kakaka2011



战魂筑 2012-12-29 17:53 发表评论
]]>
gh的boost::asio::async_read_untilhttp://www.shnenglu.com/sunicdavy/archive/2012/12/03/195921.html战魂筑战魂筑Mon, 03 Dec 2012 07:12:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2012/12/03/195921.htmlhttp://www.shnenglu.com/sunicdavy/comments/195921.htmlhttp://www.shnenglu.com/sunicdavy/archive/2012/12/03/195921.html#Feedback5http://www.shnenglu.com/sunicdavy/comments/commentRss/195921.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/195921.html最qؓ服务器添加XMLSocket与Flashq行通信, q种协议其实是一U以\0l尾的字W串协议, Z让asio兼容此协? 我从文档扑ֈ了async_read_until异步dpd, q个函数的原理时, l定一个streambuf, 和一个分隔符, asio到分隔W时q回, 你可以从streambuf中读取需要的数据. 看似很简? 我很快写好一个demo与Flashq行通信, l果发现在一个echo逻辑速度很快? 服务器居然ؕ包了, |上查了? 官方原文是这L:

”After a successful async_read_until operation, the streambuf may contain additional data beyond the delimiter. An application will typically leave that data in the streambuf for a subsequent async_read_until operation to examine.?/p>

意思是, streambuf中ƈ不一定是到分隔符前的所有数? 多余的数据可能一样会在streambuf? 也就是说, q需要自己再ơ处理一遍数?..

动手? async_read_until看似是一个废? 底层已经费了很多CPU在逐字W与分隔W的匚w? 抛上来的数据居然q是半成?

代码如下, 试通过, 但是实在很费解ؓ啥非要再做一?.

          boost::asio::streambuf* SB = SBP.get();

            // 讉K~冲
            const char* Buffs = boost::asio::buffer_cast<const char*>( SB->data() );

            uint32 DataSize = 0;
            for ( uint32 i = 0; i < SB->size(); ++i )
            {
                const char DChar = Buffs[i];

                // q里需要自己判断字W串内容, read_until的文档里q么说的
                if ( DChar == '\0' )
                {
                    DataSize = i;
                    break;
                }
            }

            if ( DataSize > 0 )
            {
                // 取成字符?/span>
                std::string FullText( Buffs, DataSize );
                
                // 消费
                SB->consume( DataSize );                

                mWorkService->post(
                    boost::bind(&AsioSession::NotifyReadString,
                    shared_from_this(),
                    FullText )
                    );

            }
  另外, Z保证输入性安? 可以在streambuf构造时加一个最大一个读取量, 过此量会返回报? 避免了缓冲区被撑爆的危险


战魂筑 2012-12-03 15:12 发表评论
]]>
MySQL++操作MySQL中造成Commands out of sync?014错误分析http://www.shnenglu.com/sunicdavy/archive/2012/06/13/178678.html战魂筑战魂筑Wed, 13 Jun 2012 09:57:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2012/06/13/178678.htmlhttp://www.shnenglu.com/sunicdavy/comments/178678.htmlhttp://www.shnenglu.com/sunicdavy/archive/2012/06/13/178678.html#Feedback0http://www.shnenglu.com/sunicdavy/comments/commentRss/178678.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/178678.htmlMySQL++在MySQL原始C接口上做了一些封? l操作带来很大便?

最q遇到DB服务器中报出一个MySQL的错?Commands out of sync; you can't run this command now,2014

查阅很多代码, 解决Ҏ都是使用C接口的方? 模仿其解x?在MySQL++中找C比较好的解决Ҏ:

ҎA: 清空每次未用的记录

for (int i = 1; DataQuery.more_results(); ++i)
{
   DataQuery.store_next();                
}

其中 DataQuerycd为mysqlpp::Query

 

ҎB: 对于存储q程?使用了多个select语句q回同样的列l果, 需要用以下语?/p>

static void print_multiple_results(Query& query)
{
    // 执行查询q输出结果表
 StoreQueryResult res = query.store();
 print_result(res, 0);
 for (int i = 1; query.more_results(); ++i) {
  res = query.store_next();
  print_result(res, i);
 }
}
 
参考文?http://hi.baidu.com/freeknight/item/ea9fd88e7d291f854514cf43


战魂筑 2012-06-13 17:57 发表评论
]]>
ZHG版本理软g的服务器/客户端数据版本发布流E?/title><link>http://www.shnenglu.com/sunicdavy/archive/2012/04/26/172798.html</link><dc:creator>战魂筑</dc:creator><author>战魂筑</author><pubDate>Thu, 26 Apr 2012 03:11:00 GMT</pubDate><guid>http://www.shnenglu.com/sunicdavy/archive/2012/04/26/172798.html</guid><wfw:comment>http://www.shnenglu.com/sunicdavy/comments/172798.html</wfw:comment><comments>http://www.shnenglu.com/sunicdavy/archive/2012/04/26/172798.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/sunicdavy/comments/commentRss/172798.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/sunicdavy/services/trackbacks/172798.html</trackback:ping><description><![CDATA[<h1><font face="Lucida Console">传统发布现状</font></h1> <p><font face="Lucida Console">传统的服务器/客户端版本发布流E都需要经历以下流E?</font></p> <p><font face="Lucida Console">1. 获取代码</font></p> <p><font face="Lucida Console">2. ~译代码</font></p> <p><font face="Lucida Console">3. 配|?二进制文? 资源打包</font></p> <p><font face="Lucida Console">4. 挂接q程服务器磁盘拷贝打包文?/font></p> <p><font face="Lucida Console">5. q程操作解压打包文g</font></p> <p><font face="Lucida Console">6. 修改讄,指向最新版?/font></p> <p><font face="Lucida Console">7. 重启服务?/font></p> <p><font face="Lucida Console">此流E繁?重复且无? 同时, ׃|络带宽,|速等U束, 每次若用完整包发布,传输h非常吃力</font></p> <p><font face="Lucida Console">本文讨论的外|服务器׃安全性要?止rootd,只能用普通帐L录或传输? 提权为rootl箋q行以上操作, 因此rsync的用受C重限?/font></p> <p><font face="Lucida Console">即便使用Windows下的同步软g, 也几乎不可能.</font></p> <h1><font face="Lucida Console">HGҎ及优势</font></h1> <p><font face="Lucida Console">HG作ؓ一个优U,y的跨q_代码理软g的特?正好能解决以上问? 主要Ҏ?</font></p> <p><font face="Lucida Console">1. 安装? 可以使用代码直接安装</font></p> <p><font face="Lucida Console">2. 利用本地映射版本可以Ҏ版本做差异比?/font></p> <p><font face="Lucida Console">3. 增量包传? 100%同步, 本地文g删除? q程文g也会同步删除</font></p> <p><font face="Lucida Console">4. 传输压羃</font></p> <p><font face="Lucida Console">5. 增量包可以打包ؓpatchq行ȝ更新</font></p> <p><font face="Lucida Console">6. 可以恢复CQ意版? 提交版本有据可查</font></p> <p><font face="Lucida Console"></font> </p> <p><strong><font face="Lucida Console">以下部vpȝ以CentOS为基, 其他pȝcM</font></strong></p> <p><strong><font face="Lucida Console">本文来自战魂筑的博?a href="http://www.shnenglu.com/sunicdavy">http://www.shnenglu.com/sunicdavy</a> 转蝲h明来?/font></strong></p> <h1><font face="Lucida Console">E服务器安装HG </font></h1> <h2><font face="Lucida Console">安装依赖?/font></h2> <p><font face="Lucida Console">yum install python-devel</font> </p> <h2><font face="Lucida Console">获取HG源码</font></h2> <p><font face="Lucida Console">wget </font><a ><font face="Lucida Console">http://mercurial.selenic.com/release/mercurial-2.1.tar.gz</font></a> </p> <p><font face="Lucida Console">tar zxvf ./mercurial-2.1.tar.gz</font> </p> <h2><font face="Lucida Console">~译安装</font></h2> <p><font face="Lucida Console">make all</font> </p> <p><font face="Lucida Console">make install</font> </p> <p><font face="Lucida Console">hg debuginstall</font> </p> <p><font face="Lucida Console"></font>  </p> <h1><font face="Lucida Console">使用HG同步数据</font></h1> <h2><font face="Lucida Console">创徏仓库</font></h2> <p><font face="Lucida Console">扑ֈ你需要同步的目录,q入目录</font></p> <p><font face="Lucida Console">执行</font></p> <p><font face="Lucida Console">hg init</font></p> <p><font face="Lucida Console">vi .hg/hgrc</font></p> <p><font face="Lucida Console">d以下内容,让这个仓库支持外部push</font></p> <p><font face="Lucida Console">[ui]</font></p> <p><font face="Lucida Console">username=<font color="#ff0000">服务器提交后看到的用户名</font></font></p> <p><font face="Lucida Console">[web]<br /></font></p> <p><div>push_ssl = false</div><font face="Lucida Console">allow_push=*<br /></font></p> <h2><font face="Lucida Console">同步</font></h2> <p><font face="Lucida Console">vi /etc/sysconfig/iptables</font></p> <p><font face="Lucida Console">dHG服务?000端口</font></p> <p><font face="Lucida Console">-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 8000 -j ACCEPT</font></p> <p><font face="Lucida Console">开启仓库同步服?/font></p> <p><font face="Lucida Console">hg serve</font></p> <p><font face="Lucida Console">本地机器同样扑ֈ文g?创徏仓库</font></p> <p><font face="Lucida Console">hg init</font></p> <p><font face="Lucida Console">以后每次需要同步时,使用命o,或者乌龟HG的界面工h取服务器数据卛_</font></p> <p><font face="Lucida Console">hg pull http://服务器地址:8000</font></p> <p><font face="Lucida Console"></font> </p> <p><font face="Lucida Console">版本提交Ҏ与HG日常使用cM, q里不再阐述</font></p> <h1><font face="Lucida Console">ȝ更新</font></h1> <p>对于某些服务器深处防火墙或者安全登录后?不能直接开?000端口的情?/p> <p>可以使用hg导出一个patch, 传输到远E服务器, 使用hg import PATCH 卛_</p><img src ="http://www.shnenglu.com/sunicdavy/aggbug/172798.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/sunicdavy/" target="_blank">战魂筑</a> 2012-04-26 11:11 <a href="http://www.shnenglu.com/sunicdavy/archive/2012/04/26/172798.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>让C/C++E序一ơ编译可以发布到多版本Linux之上http://www.shnenglu.com/sunicdavy/archive/2012/04/20/172108.html战魂筑战魂筑Fri, 20 Apr 2012 03:35:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2012/04/20/172108.htmlhttp://www.shnenglu.com/sunicdavy/comments/172108.htmlhttp://www.shnenglu.com/sunicdavy/archive/2012/04/20/172108.html#Feedback4http://www.shnenglu.com/sunicdavy/comments/commentRss/172108.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/172108.html最q页游开攑^台比较多, 每个q_要求的Linux版本各不相同, q给开发h员部|服务器带来了很大的困难. 在本机Linux~译的程?发布时即便将依赖的so附带到目标Linux环境,仍然会碰C赖及版本问题,例如:

[root@localhost bin]# ldd wkcenter
./wkcenter: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.11' not found (required by ./wkcenter)
./wkcenter: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.14' not found (required by ./wkcenter)
./wkcenter: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by ./wkcenter)
./wkcenter: /lib/libc.so.6: version `GLIBC_2.9' not found (required by ./wkcenter)
./wkcenter: /lib/libc.so.6: version `GLIBC_2.7' not found (required by ./wkcenter)
./wkcenter: /lib/libc.so.6: version `GLIBC_2.8' not found (required by ./wkcenter)
./wkcenter: /lib/libc.so.6: version `GLIBC_2.11' not found (required by ./wkcenter)

        linux-gate.so.1 =>  (0xffffe000)
        liblog4cpp.so.4 => not found
        libprotobuf.so.7 => not found
        libboost_filesystem.so.1.48.0 => not found
        libboost_system.so.1.48.0 => not found
        libboost_thread.so.1.48.0 => not found
        libboost_program_options.so.1.48.0 => not found
        libunwind-x86.so.7 => not found
        libluabind.so.0.9.0 => not found
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x008ae000)
        libm.so.6 => /lib/libm.so.6 (0x0044b000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00476000)
        libc.so.6 => /lib/libc.so.6 (0x002c1000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x0041d000)
        librt.so.1 => /lib/librt.so.1 (0x00440000)
        /lib/ld-linux.so.2 (0x002a2000)

上面U字部分表示glibc及glibcxx库依赖不正确. 本h使用的Linux~译版本为Mint 11(ZUbuntu), 一般Ubuntu发行版的glibc配备非常? 但是上文中的发布的Linux版本为CentOS 5.8

使用/lib/libc.so.6 查看libc版本?.5, q远低于开发环境的2.11

GNU C Library stable release version 2.5, by Roland McGrath et al.
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.1.2 20080704 (Red Hat 4.1.2-51).
Compiled on a Linux 2.6.9 system on 2012-02-21.
Available extensions:
        The C stubs add-on version 2.1.2.
        crypt add-on version 2.1 by Michael Glad and others
        GNU Libidn by Simon Josefsson
        GNU libio by Per Bothner
        NIS(YP)/NIS+ NSS modules 0.19 by Thorsten Kukuk
        Native POSIX Threads Library by Ulrich Drepper et al
        BIND-8.2.3-T5B
        RT using linux kernel aio
Thread-local storage support included.
For bug reporting instructions, please see:
<
http://www.gnu.org/software/libc/bugs.html>.

׃Linux操作pȝ的特有elf加蝲序. (可以参?a >此文). 虽然可以很大E度上解决Windows早期版本的dll hell问题, 但是l部|带来了很大隑ֺ

一般常见的解决Ҏ? 扑ֈ一个与目标Linux版本及glibc版本一致的Linux, 代码及依赖包放在之上编? 完成后再发布.q种Ҏ与Linux下常见Y件安装方法类? 但是对于商用服务器部|步骤来说未免繁? 安全性低.

q有一U方?使用静态链? 所有可执行文g文g依赖的静态库, pȝ?全部静态链接到可执行文件中,可以一ơ性解册个问?/p>

步骤:

    1. 在gcc链接命o行中d-static -static-libgcc -static-libstdc++

    2. 第三方依赖库打开静态链接开? 原来链?so的库,全改为链?a

    3. gcc寚w接库序很敏? 链接库顺序需要按照从前至后ؓ:  目产生的静态库 > W三方库静态库 > pȝ静态库

    4. 链接? 若有未解决的symbol, 可以试在最后添?lpthread?lrt解决

   

在发布版本Linux上运行可能遇到的问题:

terminate called after throwing an instance of 'std::runtime_error'

what(): locale::facet::_S_create_c_locale name not valid

解决Ҏ: 执行之前q行export LC_ALL="C"



战魂筑 2012-04-20 11:35 发表评论
]]>
Linux服务自动安装卸蝲部v脚本http://www.shnenglu.com/sunicdavy/archive/2012/04/12/171026.html战魂筑战魂筑Thu, 12 Apr 2012 01:33:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2012/04/12/171026.htmlhttp://www.shnenglu.com/sunicdavy/comments/171026.htmlhttp://www.shnenglu.com/sunicdavy/archive/2012/04/12/171026.html#Feedback0http://www.shnenglu.com/sunicdavy/comments/commentRss/171026.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/171026.html#!/bin/bash # chkconfig: 3 3 1 # description: svclauncher
ServicePath=/usr/local/bin

ServiceList=(
"wkcenterd --toc /home/davy/dev/kaze/Config/CenterService.toc --logfile /tmp/centerd.log"
"wkagentd --toc /home/davy/dev/kaze/Config/AgentService.toc --logfile /tmp/agentd.log"
)

StartAll()
{
    for((i = 0;i<${#ServiceList[*]};i=i+1))
    do

     echo "start:" $ServicePath/${ServiceList[i]}
     $ServicePath/${ServiceList[i]} > /dev/null &

    done
}

StopAll()
{
    for((i = 0;i<${#ServiceList[*]};i=i+1))
    do

     echo "stop:" $ServicePath/${ServiceList[i]}
     svcname=`echo ${ServiceList[i]} | awk '{print $1}'`
     killall $svcname > /dev/null

    done
}

RestartAll()
{
    StopAll
    StartAll
}


InstallService()
{
    svcname=`basename $0`
    chmod +x $svcname
    cp $svcname /etc/init.d
    ln /etc/init.d/$svcname /etc/rc3.d/S03$svcname
    ln /etc/init.d/$svcname /etc/rc0.d/K03$svcname
    chkconfig --add $svcname
    chkconfig $svcname on
    chkconfig --list | grep $svcname
}

UninstallService()
{
    svcname=`basename $0`
    chkconfig --del $svcname
    rm -f /etc/init.d/$svcname
    rm -f /etc/rc3.d/S03$svcname
    rm -f /etc/rc3.d/K03$svcname
}



case "$1" in
    start)
    StartAll
    ;;
    stop)
    StopAll
    ;;
    restart)
    RestartAll
    ;;
    install)
    InstallService
    ;;
    uninstall)
    UninstallService
    ;;
    *)
           echo "Usage: service $EXEC {install|start|stop|restart|uninst}"
       exit 1
esac
 
exit $? 



战魂筑 2012-04-12 09:33 发表评论
]]>
Linux下将ldd打印的依赖列表拷贝到指定目录http://www.shnenglu.com/sunicdavy/archive/2012/02/29/166791.html战魂筑战魂筑Wed, 29 Feb 2012 08:05:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2012/02/29/166791.htmlhttp://www.shnenglu.com/sunicdavy/comments/166791.htmlhttp://www.shnenglu.com/sunicdavy/archive/2012/02/29/166791.html#Feedback0http://www.shnenglu.com/sunicdavy/comments/commentRss/166791.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/166791.htmlLinux下的ldd命o可以查看一个可执行文g/׃n?静态库的依? 但是惛_到这些依赖文? 必须手动L,非常ȝ

q里是一个Shell可以依赖列表中的文件拷贝到指定目录

deplist=$( ldd $1 | awk '{if (match($3,"/")){ print $3}}' )
cp $deplist $2
代码解释: ldd导出列表, q个列表打印出来很丑

linux-gate.so.1 =>  (0x00ed2000)
    liblog4cpp.so.4 => /usr/local/lib/liblog4cpp.so.4 (0x00657000)
    libprotobuf.so.7 => /usr/local/lib/libprotobuf.so.7 (0x00360000)
    libboost_filesystem.so.1.48.0 => /usr/local/lib/libboost_filesystem.so.1.48.0 (0x00a9a000)
    libboost_program_options.so.1.48.0 => /usr/local/lib/libboost_program_options.so.1.48.0 (0x00110000)
    libboost_system.so.1.48.0 => /usr/local/lib/libboost_system.so.1.48.0 (0x00a85000)
    libboost_thread.so.1.48.0 => /usr/local/lib/libboost_thread.so.1.48.0 (0x00179000)
    libunwind-x86.so.7 => /usr/lib/libunwind-x86.so.7 (0x00821000)
    libluabindd.so.0.9.0 => /usr/local/lib/libluabindd.so.0.9.0 (0x00bb3000)
    libmysqlpp.so.3 => /usr/local/lib/libmysqlpp.so.3 (0x00de5000)
    libstdc++.so.6 => /usr/lib/i386-linux-gnu/libstdc++.so.6 (0x001a9000)
    libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0x00782000)
    libgcc_s.so.1 => /lib/i386-linux-gnu/libgcc_s.so.1 (0x00aea000)
    libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0x00447000)
    libpthread.so.0 => /lib/i386-linux-gnu/libpthread.so.0 (0x00abd000)
    librt.so.1 => /lib/i386-linux-gnu/librt.so.1 (0x00193000)
    libnsl.so.1 => /lib/i386-linux-gnu/libnsl.so.1 (0x00294000)
    libunwind.so.7 => /usr/lib/libunwind.so.7 (0x002ab000)
    libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0x00e8a000)
    libmysqlclient_r.so.16 => /usr/lib/libmysqlclient_r.so.16 (0x0083b000)
    /lib/ld-linux.so.2 (0x00608000)
    libz.so.1 => /lib/i386-linux-gnu/libz.so.1 (0x002c0000)

 

我们发现W一行的so没有对应的库地址, 因此我们使用awk的脚本功?判断W三个参?也就?>之后的\径必d?

之后第一行的输出重定向到变量? 再用cp指o从列表拷贝到指定目录



战魂筑 2012-02-29 16:05 发表评论
]]>
Linux服务器守护进E?自动启动+服务配置W记http://www.shnenglu.com/sunicdavy/archive/2012/02/28/166680.html战魂筑战魂筑Tue, 28 Feb 2012 02:52:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2012/02/28/166680.htmlhttp://www.shnenglu.com/sunicdavy/comments/166680.htmlhttp://www.shnenglu.com/sunicdavy/archive/2012/02/28/166680.html#Feedback4http://www.shnenglu.com/sunicdavy/comments/commentRss/166680.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/166680.html1.1 E添加守护进E?/h4>

参考链?a >http://yubosun.akcms.com/tech/linux-daemon-program.htm

   1:  #include <unistd.h> 
   2:  #include <signal.h> 
   3:  #include <sys/types.h> 
   4:  #include <sys/stat.h> 
   5:  #include <stdio.h> 
   6:  #include <stdlib.h>
   7:   
   8:  #ifndef NOFILE 
   9:  #define NOFILE 3 
  10:  #endif
  11:   
  12:  void init_daemon() 
  13:  { 
  14:          int pid; 
  15:          int i; 
  16:          if(pid = fork()) exit(0); //父进E,退?
  17:   
  18:          else if(pid < 0) exit(1); //forkp| 
  19:   
  20:          /* 子进El执?*/ 
  21:          setsid(); //创徏新的会话l,子进E成为组长,q与控制l端分离 
  22:   
  23:          /* 防止子进E(l长Q获取控制终?*/ 
  24:          if(pid = fork()) exit(0); //父进E,退?
  25:   
  26:          else if(pid < 0) exit(1); //fork错误Q退?
  27:   
  28:          /* W二子进El执?, W二子进E不再是会会话组l长*/ 
  29:   
  30:          //for(i = 0; i < NOFILE; i++) /* 关闭打开的文件描q符*/ 
  31:          //{ 
  32:          //close(i); 
  33:          //} 
  34:          chdir("/tmp"); /* 切换工作目录 */ 
  35:          umask(0); /* 重设文g创徏掩码 */ 
  36:          return; 
  37:  }
  38:   
  39:  int main(int argc, char* argv[])
  40:  {    
  41:      FILE *fp; 
  42:   
  43:      signal(SIGCHLD, SIG_IGN); /* 忽略子进E结束信P防止出现僵尸q程 */ 
  44:   
  45:      init_daemon(); 
  46:   
  47:      while(1) 
  48:      { 
  49:              sleep(1);
  50:              
  51:  // 注意, 日志写到q个目录
  52:              if((fp = fopen("/var/tmp/test.log", "a")) != NULL) 
  53:              { 
  54:                      fprintf(fp, "%s\n", "test message"); 
  55:                      fclose(fp); 
  56:              } 
  57:      } 
  58:   
  59:      return 0;
  60:  }

1.2 ~写服务脚本

参考链?a >http://blog.sina.com.cn/s/blog_57421ff80100c7nn.html

U色字是需要填写的部分, 文g头部分可以选填

   1:  #!/bin/bash
   2:   
   3:  # chkconfig: 3 3 1
   4:   
   5:  # description: web kill center
   6:   
   7:  EXEC_PATH=/usr/local/bin
   8:   
   9:  EXEC=CenterServiced
  10:   
  11:  PID_FILE=/var/run/CenterServiced.pid
  12:   
  13:  DAEMON=/usr/local/bin/CenterServiced
  14:   
  15:  if ! [ -x $EXEC_PATH/$EXEC ] ; then
  16:   
  17:  echo "ERROR: $EXEC_PATH/$EXEC not found"
  18:   
  19:  exit 1
  20:   
  21:  fi
  22:   
  23:  stop()
  24:   
  25:  {
  26:   
  27:  echo "Stoping $EXEC ..."
  28:   
  29:  killall $DAEMON >/dev/null
  30:   
  31:  echo "Shutting down $EXEC: [ OK ]"
  32:   
  33:  }
  34:   
  35:  start()
  36:   
  37:  {
  38:   
  39:  echo "Starting $EXEC ..."
  40:   
  41:  $DAEMON > /dev/null &
  42:   
  43:  echo "Starting $EXEC: [ OK ]"
  44:   
  45:  }
  46:   
  47:  restart()
  48:   
  49:  {
  50:   
  51:  stop
  52:   
  53:  start
  54:   
  55:  }
  56:   
  57:  case "$1" in
  58:   
  59:  start)
  60:   
  61:  start
  62:   
  63:  ;;
  64:   
  65:  stop)
  66:   
  67:  stop
  68:   
  69:  ;;
  70:   
  71:  restart)
  72:   
  73:  restart
  74:   
  75:  ;;
  76:   
  77:  status)
  78:   
  79:  status -p $PID_FILE $DAEMON
  80:   
  81:  ;;
  82:   
  83:  *)
  84:   
  85:  echo "Usage: service $EXEC {start|stop|restart|status}"
  86:   
  87:  exit 1
  88:   
  89:  esac
  90:   
  91:  exit $?
  92:   

1.3 创徏服务

参考链?a >http://hi.baidu.com/guanxiansun/blog/item/b4c7dcf55f6011e47709d724.html

服务文件拷贝到/etc/init.d?L扩展? 文g名即是服务名

chmod +x ./wkcenter

如果不设|启? 那么service中将无法扑ֈ该服务及操作

1.4 讄启动序

创徏启动链接

ln /etc/init.d/wkcenter /etc/rc3.d/S03wkcenter

创徏关闭链接

ln /etc/init.d/wkcenter /etc/rc0.d/K03wkcenter

1.5 d服务

chkconfig --add wkcenter

查看服务是否存在

chkconfig ?list | grep wkcenter

查看服务状?

chkconfig wkcenter on

注意, 认wkcenter?,3,4,5中Q意或者部分开? 必须为绿? 灰字代表服务无法开机启动或者其他问?

1.6 试

临时开启命令测?

service wkcenter start

1.7 QA

参考链? http://blog.526net.com/?p=1706

1. 服务切记不可攑֜用户home目录, 最好放?usr/local/bin目录, 日志写到var? 否则服务试正常,但是无法自动启动

2. Linux? 父进E启动的E序的生命期跟随父进E? 父进E可以是l端, 父进E一旦终? 子进E都必须l束. 因此守护q程需要脱ȝq程,避免被父q程生命期控?

战魂筑 2012-02-28 10:52 发表评论
]]>
跨^台Unicode与UTF8互{代码http://www.shnenglu.com/sunicdavy/archive/2012/02/27/166623.html战魂筑战魂筑Mon, 27 Feb 2012 06:21:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2012/02/27/166623.htmlhttp://www.shnenglu.com/sunicdavy/comments/166623.htmlhttp://www.shnenglu.com/sunicdavy/archive/2012/02/27/166623.html#Feedback9http://www.shnenglu.com/sunicdavy/comments/commentRss/166623.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/166623.html参考来?http://blog.csdn.net/flying8127/article/details/1598521

在原来原基础?代码整?q加强安全? q按照WindowsAPI设计, d输出~冲长度探测功能

当OutUTFString为NULL? 可以q行输出的UTF8字符串长度探?/p>

   1:  uint32 UniCharToUTF8(wchar_t UniChar, char *OutUTFString)
   2:      {
   3:   
   4:          uint32 UTF8CharLength = 0;
   5:   
   6:          if (UniChar < 0x80)
   7:          {  
   8:              if ( OutUTFString )
   9:                  OutUTFString[UTF8CharLength++] = (char)UniChar;
  10:              else
  11:                  UTF8CharLength++;
  12:          }
  13:          else if(UniChar < 0x800)
  14:          {
  15:              if ( OutUTFString )
  16:              {
  17:                  OutUTFString[UTF8CharLength++] = 0xc0 | ( UniChar >> 6 );
  18:                  OutUTFString[UTF8CharLength++] = 0x80 | ( UniChar & 0x3f );
  19:              }
  20:              else
  21:              {
  22:                  UTF8CharLength += 2;
  23:              }
  24:          }
  25:          else if(UniChar < 0x10000 )
  26:          {
  27:              if ( OutUTFString )
  28:              {
  29:                  OutUTFString[UTF8CharLength++] = 0xe0 | ( UniChar >> 12 );
  30:                  OutUTFString[UTF8CharLength++] = 0x80 | ( (UniChar >> 6) & 0x3f );
  31:                  OutUTFString[UTF8CharLength++] = 0x80 | ( UniChar & 0x3f );
  32:              }
  33:              else
  34:              {
  35:                  UTF8CharLength += 3;
  36:              }
  37:          }
  38:          else if( UniChar < 0x200000 ) 
  39:          {
  40:              if ( OutUTFString )
  41:              {
  42:                  OutUTFString[UTF8CharLength++] = 0xf0 | ( (int)UniChar >> 18 );
  43:                  OutUTFString[UTF8CharLength++] = 0x80 | ( (UniChar >> 12) & 0x3f );
  44:                  OutUTFString[UTF8CharLength++] = 0x80 | ( (UniChar >> 6) & 0x3f );
  45:                  OutUTFString[UTF8CharLength++] = 0x80 | ( UniChar & 0x3f );
  46:              }
  47:              else
  48:              {
  49:                  UTF8CharLength += 4;
  50:              }
  51:   
  52:          }
  53:   
  54:          return UTF8CharLength;
  55:      }

 

当OutUnicodeString为NULL? 可以q行输出的Unicode字符串长度探?/p>

 

   1:  uint32 UTF8StrToUnicode( const char* UTF8String, uint32 UTF8StringLength, wchar_t* OutUnicodeString, uint32 UnicodeStringBufferSize )
   2:      {
   3:          uint32 UTF8Index = 0;
   4:          uint32 UniIndex = 0;
   5:   
   6:          while ( UTF8Index < UTF8StringLength )
   7:          {
   8:              unsigned char UTF8Char = UTF8String[UTF8Index];
   9:   
  10:              if ( UnicodeStringBufferSize != 0 && UniIndex >= UnicodeStringBufferSize )
  11:                  break;
  12:   
  13:              if ((UTF8Char & 0x80) == 0) 
  14:              {
  15:                  const uint32 cUTF8CharRequire = 1;
  16:   
  17:                  // UTF8字码不
  18:                  if ( UTF8Index + cUTF8CharRequire > UTF8StringLength )
  19:                      break;
  20:   
  21:                  if ( OutUnicodeString )
  22:                  {
  23:                      wchar_t& WideChar = OutUnicodeString[UniIndex]; 
  24:   
  25:                      WideChar = UTF8Char;
  26:                  }
  27:   
  28:                  UTF8Index++;
  29:                  
  30:              } 
  31:              else if((UTF8Char & 0xE0) == 0xC0)  ///< 110x-xxxx 10xx-xxxx
  32:              {
  33:                  const uint32 cUTF8CharRequire = 2;
  34:   
  35:                  // UTF8字码不
  36:                  if ( UTF8Index + cUTF8CharRequire > UTF8StringLength )
  37:                      break;
  38:   
  39:                  if ( OutUnicodeString )
  40:                  {
  41:                      wchar_t& WideChar = OutUnicodeString[UniIndex]; 
  42:                      WideChar  = (UTF8String[UTF8Index + 0] & 0x3F) << 6;
  43:                      WideChar |= (UTF8String[UTF8Index + 1] & 0x3F);
  44:                  }
  45:                  
  46:                  UTF8Index += cUTF8CharRequire;
  47:              }
  48:              else if((UTF8Char & 0xF0) == 0xE0)  ///< 1110-xxxx 10xx-xxxx 10xx-xxxx
  49:              {
  50:                  const uint32 cUTF8CharRequire = 3;
  51:   
  52:                  // UTF8字码不
  53:                  if ( UTF8Index + cUTF8CharRequire > UTF8StringLength )
  54:                      break;
  55:   
  56:                  if ( OutUnicodeString )
  57:                  {
  58:                      wchar_t& WideChar = OutUnicodeString[UniIndex]; 
  59:   
  60:                      WideChar  = (UTF8String[UTF8Index + 0] & 0x1F) << 12;
  61:                      WideChar |= (UTF8String[UTF8Index + 1] & 0x3F) << 6;
  62:                      WideChar |= (UTF8String[UTF8Index + 2] & 0x3F);
  63:                  }
  64:                  
  65:   
  66:                  UTF8Index += cUTF8CharRequire;
  67:              } 
  68:              else if((UTF8Char & 0xF8) == 0xF0)  ///< 1111-0xxx 10xx-xxxx 10xx-xxxx 10xx-xxxx 
  69:              {
  70:                  const uint32 cUTF8CharRequire = 4;
  71:   
  72:                  // UTF8字码不
  73:                  if ( UTF8Index + cUTF8CharRequire > UTF8StringLength )
  74:                      break;
  75:   
  76:                  if ( OutUnicodeString )
  77:                  {
  78:                      wchar_t& WideChar = OutUnicodeString[UniIndex]; 
  79:   
  80:                      WideChar  = (UTF8String[UTF8Index + 0] & 0x0F) << 18;
  81:                      WideChar  = (UTF8String[UTF8Index + 1] & 0x3F) << 12;
  82:                      WideChar |= (UTF8String[UTF8Index + 2] & 0x3F) << 6;
  83:                      WideChar |= (UTF8String[UTF8Index + 3] & 0x3F);
  84:                  }
  85:   
  86:                  UTF8Index += cUTF8CharRequire;
  87:              } 
  88:              else ///< 1111-10xx 10xx-xxxx 10xx-xxxx 10xx-xxxx 10xx-xxxx 
  89:              {
  90:                  const uint32 cUTF8CharRequire = 5;
  91:   
  92:                  // UTF8字码不
  93:                  if ( UTF8Index + cUTF8CharRequire > UTF8StringLength )
  94:                      break;
  95:   
  96:                  if ( OutUnicodeString )
  97:                  {
  98:                      wchar_t& WideChar = OutUnicodeString[UniIndex]; 
  99:   
 100:                      WideChar  = (UTF8String[UTF8Index + 0] & 0x07) << 24;
 101:                      WideChar  = (UTF8String[UTF8Index + 1] & 0x3F) << 18;
 102:                      WideChar  = (UTF8String[UTF8Index + 2] & 0x3F) << 12;
 103:                      WideChar |= (UTF8String[UTF8Index + 3] & 0x3F) << 6;
 104:                      WideChar |= (UTF8String[UTF8Index + 4] & 0x3F);
 105:                  }
 106:   
 107:                  UTF8Index += cUTF8CharRequire;
 108:              }
 109:   
 110:   
 111:              UniIndex++;
 112:          }
 113:   
 114:          return UniIndex;
 115:      }

疗效: 用了此代码啊, 再也不用被iconv折磨?/p>

战魂筑 2012-02-27 14:21 发表评论
]]>
Linux/Windows下hash_map的表现差?/title><link>http://www.shnenglu.com/sunicdavy/archive/2012/02/23/166353.html</link><dc:creator>战魂筑</dc:creator><author>战魂筑</author><pubDate>Thu, 23 Feb 2012 10:54:00 GMT</pubDate><guid>http://www.shnenglu.com/sunicdavy/archive/2012/02/23/166353.html</guid><wfw:comment>http://www.shnenglu.com/sunicdavy/comments/166353.html</wfw:comment><comments>http://www.shnenglu.com/sunicdavy/archive/2012/02/23/166353.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/sunicdavy/comments/commentRss/166353.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/sunicdavy/services/trackbacks/166353.html</trackback:ping><description><![CDATA[<p>hash_map不是标准?因此不同q_下包含头文g不同, 前缀也不?q里使用了一个通用定义</p> <div id="iamyk4g" class="csharpcode"><pre><span id="ckwquai" class="lnum"> 1: </span>#ifdef _WIN32</pre><pre><span id="iysw8y8" class="lnum"> 2: </span> #include <hash_map></pre><pre><span id="884qc4m" class="lnum"> 3: </span> <span id="w4u444i" class="preproc">#define</span> HASHMAP_PREFIX stdext</pre><pre><span id="ywa84mu" class="lnum"> 4: </span><span id="aiuauc8" class="preproc">#else</span></pre><pre><span id="om88css" class="lnum"> 5: </span> #include <ext/hash_map></pre><pre><span id="omq84m4" class="lnum"> 6: </span> <span id="4cyaeuu" class="preproc">#define</span> HASHMAP_PREFIX __gnu_cxx </pre><pre><span id="uuoimu8" class="lnum"> 7: </span><span id="g8y48sk" class="preproc">#endif</span></pre></div> <p> <style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> </p> <p>对于初始桶大设|?Linux下用hash_map构造函数可以设|? Windows下则没有对应的设|函?</p> <p>查阅Windows下hash_map的源?q在hash_map()默认构造函数旁Ҏ加一个测试用初始桶设|函?/p> <div id="yguykiy" class="csharpcode"><pre><span id="aq48444" class="lnum"> 1: </span> hash_map( size_type _Buckets )</pre></div> <div id="sk8ys8y" class="csharpcode"><pre><span id="sqcqkki" class="lnum"> 2: </span> : _Mybase(key_compare(), allocator_type())</pre></div> <div id="88i8gyg" class="csharpcode"><pre><span id="aaeikk8" class="lnum"> 3: </span> {</pre></div> <div id="m8e4884" class="csharpcode"><pre><span id="o8ywaqy" class="lnum"> 4: </span> _Init( _Buckets );</pre></div> <div id="q8yo8ii" class="csharpcode"><pre><span id="c8m4qi8" class="lnum"> 5: </span> }</pre></div> <blockquote> </blockquote> <style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> <p>接下来用相同的试代码</p> <div id="og4giqg" class="csharpcode"><pre><span id="oeq4y44" class="lnum"> 1: </span> <span id="a48a4ua" class="kwrd">const</span> uint32 Buckets = 1000;</pre><pre><span id="mw444sq" class="lnum"> 2: </span> HASHMAP_PREFIX::hash_map<uint32,uint32> MyHash( Buckets );</pre><pre><span id="wmi8yg8" class="lnum"> 3: </span> </pre><pre><span id="mwimqg8" class="lnum"> 4: </span> TimeRuler Ruler;</pre><pre><span id="squqss8" class="lnum"> 5: </span> <span id="a8i84gg" class="kwrd">for</span> ( uint32 i = 0; i <1000000;i++)</pre><pre><span id="gwqmq84" class="lnum"> 6: </span> {</pre><pre><span id="igawmou" class="lnum"> 7: </span> MyHash[i] = i;</pre><pre><span id="88muggw" class="lnum"> 8: </span> }</pre><pre><span id="i4iy8yi" class="lnum"> 9: </span> </pre><pre><span id="o884mc4" class="lnum"> 10: </span> printf(<span id="ai88i4y" class="str">"%d\n"</span>, Ruler.GetCostTime() );</pre></div> <style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> <p>q里的TimeRuler是用boost timer的时间戳装</p> <p>Release下测试结?</p> <table style="color: #000000" border="0" cellspacing="0" cellpadding="2" width="400"> <tbody> <tr> <td valign="top" width="133">    OS \ Buckets</td> <td valign="top" width="133">          8 ( default )</td> <td valign="top" width="133">        1000 </td></tr> <tr> <td valign="top" width="133">     Win7</td> <td valign="top" width="133">         430ms</td> <td valign="top" width="133">      560ms</td></tr> <tr> <td valign="top" width="133">     Mint( VMware )</td> <td valign="top" width="133">         127ms</td> <td valign="top" width="133">      127ms</td></tr></tbody></table> <p> </p> <p>Windows的测试结果说? 不给出桶初始化函数是正确? 默认理比自p|更高效. </p> <p>Linuxq_感觉很诡? 不清楚是不是虚拟机造成的结果不准确</p><img src ="http://www.shnenglu.com/sunicdavy/aggbug/166353.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/sunicdavy/" target="_blank">战魂筑</a> 2012-02-23 18:54 <a href="http://www.shnenglu.com/sunicdavy/archive/2012/02/23/166353.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>luabind的正完整编译法http://www.shnenglu.com/sunicdavy/archive/2012/02/21/166118.html战魂筑战魂筑Tue, 21 Feb 2012 03:23:00 GMThttp://www.shnenglu.com/sunicdavy/archive/2012/02/21/166118.htmlhttp://www.shnenglu.com/sunicdavy/comments/166118.htmlhttp://www.shnenglu.com/sunicdavy/archive/2012/02/21/166118.html#Feedback1http://www.shnenglu.com/sunicdavy/comments/commentRss/166118.htmlhttp://www.shnenglu.com/sunicdavy/services/trackbacks/166118.html之前看了|上一?a >文章介绍luabind, 发现q种~译出来的luabind只会安装debug版本, release版本的so依然坦然的h在工E目?/p>

查阅bjam的参数说明及luabind的jamroot文gW?40行有如下文字

install stage
  : luabind
  : <location>$(stage-locate)
    <install-no-version-symlinks>on
    <install-dependencies>on
    <install-type>LIB
  ;

说明参数应该是这L: bjam install [stage]

而且文章中给出的是bjam install 因此默认试版也是正确? 而且估计作者只~译了调试版没有处理release版了

正确的luabind~译法应该是:

export BOOST_ROOT=/home/davy/dev/boost_1_48_0

export LUA_PATH=/usr/local/

/home/davy/dev/boost_1_48_0/bjam stage --toolset=gcc --with-date_time --with-fpic --with-filesystem link=static debug release

/home/davy/dev/boost_1_48_0/bjam install debug

/home/davy/dev/boost_1_48_0/bjam install release

 

我这里必L明bjam是因为boost的bjam版本高于默认安装的版? 因此使用高版本编?



战魂筑 2012-02-21 11:23 发表评论
]]>
Linux在VMware中网l设|?/title><link>http://www.shnenglu.com/sunicdavy/archive/2012/02/04/164934.html</link><dc:creator>战魂筑</dc:creator><author>战魂筑</author><pubDate>Sat, 04 Feb 2012 03:41:00 GMT</pubDate><guid>http://www.shnenglu.com/sunicdavy/archive/2012/02/04/164934.html</guid><wfw:comment>http://www.shnenglu.com/sunicdavy/comments/164934.html</wfw:comment><comments>http://www.shnenglu.com/sunicdavy/archive/2012/02/04/164934.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/sunicdavy/comments/commentRss/164934.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/sunicdavy/services/trackbacks/164934.html</trackback:ping><description><![CDATA[<p>q里使用的是Ubuntu的最行发行版Mint, 其他版本cM</p> <p>以下虚拟机内系l叫Guest, q行VMWare的系l叫Host</p> <p>VMWare的网l方式设为Bridge模式. 注意Host-Only模式只能与Hostq接,局域网的机器及互联|机器无法访?/p> <p><a href="http://www.shnenglu.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/Linux-VMware_A07B/image_6.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.shnenglu.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/Linux-VMware_A07B/image_thumb_2.png" width="306" height="276"></a></p> <p>在Guest的网l设|中,IP讄ZHost在一个局域网|段的IP, 讄DNS</p> <p><a href="http://www.shnenglu.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/Linux-VMware_A07B/image_4.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.shnenglu.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/Linux-VMware_A07B/image_thumb_1.png" width="402" height="292"></a></p> <p>关闭Guestpȝ</p> <p>接下来将Host的可以上|的q接d׃n,q连接到VMNet1</p> <p><a href="http://www.shnenglu.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/Linux-VMware_A07B/image_2.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.shnenglu.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/Linux-VMware_A07B/image_thumb.png" width="599" height="232"></a></p> <p>q入Guestpȝ, 试上网</p><img src ="http://www.shnenglu.com/sunicdavy/aggbug/164934.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/sunicdavy/" target="_blank">战魂筑</a> 2012-02-04 11:41 <a href="http://www.shnenglu.com/sunicdavy/archive/2012/02/04/164934.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.shnenglu.com/" title="精品视频久久久久">精品视频久久久久</a> <div class="friend-links"> </div> </div> </footer> <a href="http://www.btalhb.cn" target="_blank">ݺɫþۺ_</a>| <a href="http://www.u24373.cn" target="_blank">ŷþþþƷ</a>| <a href="http://www.vhro.cn" target="_blank">þҹɫƷwww</a>| <a href="http://www.caoyb.cn" target="_blank">Ļþ</a>| <a href="http://www.yrwe981.cn" target="_blank">Ʒþþþþ</a>| <a href="http://www.wxbdd.cn" target="_blank">ۺϾþþ</a>| <a href="http://www.shangzhew.cn" target="_blank">99þҹҹƷ</a>| <a href="http://www.zhhhtch.cn" target="_blank">˾Ʒ׽þ69</a>| <a href="http://www.kuhaoma.cn" target="_blank">þþþֻоƷ </a>| <a href="http://www.baaag.cn" target="_blank">޳avƬþ</a>| <a href="http://www.fq2.com.cn" target="_blank">þþžѾƷ6</a>| <a href="http://www.x6844.cn" target="_blank">þۺϾþۺϾþ</a>| <a href="http://www.englishtutor.com.cn" target="_blank">ƷۺϾþ</a>| <a href="http://www.369live.cn" target="_blank">99þþƷѿһ</a>| <a href="http://www.ikxc.cn" target="_blank">ŷ޹Ʒþø</a>| <a href="http://www.ilrf.cn" target="_blank">Ʒŷþþþ޹ </a>| <a href="http://www.h5982.cn" target="_blank">ɫ͵͵88ŷƷþþ</a>| <a href="http://www.xbvz.cn" target="_blank">ƷþĻ</a>| <a href="http://www.veyp.cn" target="_blank">͵͵þþþվ</a>| <a href="http://www.hqbtt.cn" target="_blank">þþþþùƷŮ</a>| <a href="http://www.7cdy.cn" target="_blank">þùƷþ</a>| <a href="http://www.ha9hpn.cn" target="_blank">޹һ˾þþƷ</a>| <a href="http://www.zhifuse.cn" target="_blank">ҹƷþþþþӰ777</a>| <a href="http://www.sowudi.com.cn" target="_blank">ԭۺϾþô˾Ʒ</a>| <a href="http://www.7cfw.cn" target="_blank">ɫɫۺϾþҹҹ</a>| <a href="http://www.suba400.cn" target="_blank">ԾþþӰԺ</a>| <a href="http://www.thinkct.com.cn" target="_blank">þۺϾɫۺϾ99</a>| <a href="http://www.ldg8.cn" target="_blank">Ʒþþþþ˳</a>| <a href="http://www.ks29n.cn" target="_blank">99þһa</a>| <a href="http://www.jlxrc.cn" target="_blank">ɫۺϾþʮ·</a>| <a href="http://www.etnz.cn" target="_blank">ھƷžžþþƷ</a>| <a href="http://www.ovnk.cn" target="_blank">ƷþþĻ</a>| <a href="http://www.wzorg.cn" target="_blank">2021ƷþþƷ</a>| <a href="http://www.lebow01.cn" target="_blank">þþþAVվ</a>| <a href="http://www.adpz.cn" target="_blank">ŷҹƷþþþþ˳</a>| <a href="http://www.yy2b.cn" target="_blank">þþƷһ </a>| <a href="http://www.ukja.cn" target="_blank">þseƷһƷ</a>| <a href="http://www.e9ir544.cn" target="_blank">þþƷƷƷ</a>| <a href="http://www.hgndg.cn" target="_blank">þþƷ69Ʒ</a>| <a href="http://www.freejavbt.cn" target="_blank">ŷ777Ʒþþþ</a>| <a href="http://www.duopudz.cn" target="_blank">26uuuþ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>