基于java nio的server设计

最近由于业务需要,写了一个 java server用来与我们的游戏服务器实现交互。 server只实现了最基本的功能: 维护多个长连接,发送与接收消息;连接建立及断开(主动与被动)。 在实现的过程中,最有意思的是java nio里的buffer,但我认为这是一个失败的设计。 java nio buffer三个主要的属性,position, limit, capacity. 通常来讲,传统的ringbuffer都会有一个read index和write index, 但buffer nio将两者统一为postion,然后弄出了读写模式切换的概念。 当从buffer里取出数据,即buffer.getXXX或者channel.write(buffer), 当往buffer里放入数据,即buffer.putXX或者channel.read(buffer), 的前后,经常要考虑模式的切换,比如调用flip,这样的设计增加了复杂性,对库的使用者带来困难(笔者才疏学浅,一直疑惑他们为什么这么设计,求高人指教),这本质上是因为position属性既要当作readindex来使用,又要当作writeindex来使用。 另外一点就是由于postion的大小不能超过limit和capacity, 导致使用的过程中经常需要compact, 每次compact会导致额外的内存拷贝;传统的ringbuffer会在writeindex < readindex在的时候才可能涉及到额外内存的拷贝。 也难怪,netty里抛弃了这种设计。

CURLOPT_POSTFIELDSIZE Post

最近用libcurl向某商web服务器作登录校验踩了一坑。 事情的表象是这样的,在windows上没有问题,linux上投递过去的数据乱码。但是如果将curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data)中的data写死,即写成字符串常量,也是没有问题的。 开始以为一些参数和环境的问题,查了半天问题依旧,才怀疑到变量生存周期的问题,将data生命期拉长,就好了。

关于shadowsocks

平时其实很少使用VPN,多是Mac上SSH+Socks代理,Windows上就myentunnel+Socks代理。近来工作原因,手机上需要VPN才用的较为频繁,然而最近经常不好使了,  换了几个,一直都不太稳定,原因嘛你懂的。 于是在自己国外的VPS上搭建了一个VPN,用的是shadowsocks搭建的服务器. 客户端的话Mac,  Android , Windows应该都有免费的,iPhone上现在要花16元。 搭建好,用的是443端口。一天之后,发现不行了,然后换了个端口,现在已经流畅运行好几天了,很开心:) 一般的翻墙,通过设置浏览器http代理或者socks (5)代理就可以了。shadowsocks显然做的更多。 出于习惯,想了想这个自己弄应该怎么实现。去看了下代码,服务端用的python,几千行代码挺简洁的; 客户端需要解决的问题复杂些, 涉及到TCP/IP协议栈。

IOS内存泄露

  App里的内存泄漏分为两类: Leaked memory: Memory unreferenced by your application that cannot be used again or freed (also detectable by using the Leaks instrument). Abandoned memory: Memory still referenced by your application that has no useful purpose. 利用XCode自带的Instrument,  可以分析出这些内存泄漏。 根据笔者的经验,Leaked memory能分析的是这样的一类内存泄漏: memAlloc = malloc(100); 当memAlloc没有被释放,此语句再次被执行的时候就会被Instruments的Leak工具检测出来。 麻烦的内存泄漏是Abandoned memory,这类内存一直被缓存,但其实已经没有用了,问题来了,什么是有用,什么是没用呢? Instrument工具给出的方案是https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/FindingAbandonedMemory.html#//apple_ref/doc/uid/TP40004652-CH80-SW1, 简单来说,用 Mark Generation 的方式,每次Mark的时候,都会生存一个内存快照,然后比较两个快照有什么不同。可想而知,这个是对稍微复杂点的场景来说,还是太不方便。 对于游戏来说,主要的消耗内存的就是纹理和音视频资源了,这一块除了设计好资源管理外,需要提供一个直观方便的dump info,随时能够查看资源分配和释放的情况。然后配合Instrument的工具,也足够使用了。 更高级的内存泄漏,依然是利去hook底层的内存分配和释放函数,IOS方面的内存泄漏可以参考: https://wereadteam.github.io/2016/02/22/MLeaksFinder/

Java中的字符编码

今天在接入某邻国的支付SDK的时候,碰上了一个乱码问题。 直接表现是,从数据库后台返回给前端网页上的中文及邻国文字都变成了问号,英文没有问题。 分析了一下,我们的数据库是采用UTF-8字符集的,new String(“dataValueXXX”, “UTF-8”)应该是没有问题的,于是设置了response.setContentType(“application/json;charset=UTF-8”);一切就OK了。 其实问题的根本主要是理解下Java的String是怎么处理字符集问题的。 记录一笔,只是感慨时光流逝,当年读书的时候做些项目也碰到过类似的问题,总觉得那时候一知半解还挺折腾,时光流逝,回过头去,看看文档,再想一想,看的明白点了。