前言 大学以来一直想做一个OJ,终于可以开始,而且是用新学的Go来写,心里还是挺兴奋的。 项目启动,要搭架子,第一件事,当然是选择一个包管理工具。Go的包管理还是挺混乱的,没有一个能像Java的Maven一样足够强大&一统天下,尽管优秀的第三方工具已有十来种,且官方也开始着手开发(快统一江湖吧)。 (ps:虽然包管理很让人糟心,但这并不能影响我对这门语言的热爱) glide 安装 go get github.com/Masterminds/glide 使用 进入项目文件夹。!记住,项目必须放在src下,否则会出现很多问题,包括其他包管理工具! cd $GOPATH/src/your_project 创建glide.yaml文件,并进行相应配置选项 glide init 修改glide.yaml,如果是刚创建的空项目,可以略过这一步。 默认,glide.yaml生成会加入所有import语句的包路径,那么也就包含我们项目内部的包路径,因此我们 继续阅读 >>


师毅 17/10/02 05:23:28
前言 这一阵子,刚换了落脚地儿,没想好该去折腾什么,恰好看到可以用git page搭建一个博客,就搞了搞。关于主题啊,配置啊什么的,网上都有好多,偏偏迁移这个事儿挺麻烦,幸好有找到一前辈的脚本,可以将CSDN的博客导出为markdown格式,但是其导出来的md文件并不能直接用hexo,想要显示的好一些还需要再用脚本将它二次润色。 本人重写了润色的脚本,并增加了对CSDN的分类的爬取,将其作为hexo md文件里面的标签。 记录于此,方便大家。 还有,欢迎访问我的新博客 shiyi.fightcoder.com 环境 python 2.7 这个就不说了,os-x,linux都是自带的,window的话自己下个就完了。 BeautifulSouphttps 去BeautifulSoup官网下载源码包,解压后进入BeautifulSoup文件夹下执行下面命令即可。 python setup.py install html2text 下载源码包:html2text-201 继续阅读 >>


师毅 17/06/18 21:53:27
方法1. 使用sleep或者usleep 这种方法很简单,这里就不具体描述,它的缺点也很明确:精度不够,特别是在系统负载比较大时,会发生超时现象。 方法2. 使用信号量SIGALRM + alarm() alarm也称为闹钟函数,alarm()用来设置在经过参数seconds指定的秒数后传送信号SIGALRM给目前的进程。如果参数seconds为0,则之前设置的闹钟会被取消,并将剩下的时间返回。要注意的是,一个进程只能有一个闹钟时间,如果在调用alarm之前已设置过闹钟时间,则任何以前的闹钟时间都被新值所代替。 那么我们可以使用signal函数设定SIGALRM的处理函数,然后使用alarm定时发送SIGALRM来达到我们的目的。 #include <stdio.h> #include <signal.h> #include <unistd.h> void timer(int sig) { if(SIGALRM == sig) { 继续阅读 >>


师毅 17/03/02 23:06:51
通常,I/O复用机制都需要事件分享器。分享器对象可将来自事件源的I/O事件分离出来,并分发到对应的Read/Write事件处理器。开发人员预先注册需要处理的事件及该事件对应的事件处理器。 Reactor和Proactor都涉及到了事件分享器,不同的是,Reactor是基于同步I/O的,而Proactor是与异步I/O相关。 在Reactor模式中,事件分离器等待某个事件或者某个操作的状态发生,比如文件描述符可读写或是socket可读写,事件分离器就将这个时间传给事先注册的事件处理器(事件处理函数或者回调函数),由后者来做实际的读写操作。 而在Proactor模式中,事件处理器直接发起一个异步读写操作,发起时,需要提供用于存放读到数据的缓存区、读的数据大小。以及这个请求完成后的回调函数等信息。事件分离器收到请求后,默默等待这个请求的完成,然后转发完成事件给对应的事件处理器。这种异步模式的典型实现是基于操作系统底层异步API的,所以我们可以称之为“系统级别”的或者“真正意义上”的异步,因为具体的读写操 继续阅读 >>


师毅 17/03/01 18:40:34
背景 在中国的互联网诸多业务领域中,游戏一直是充当“现金牛”而存在的。但是,在游戏服务器端开发领域中的很多重要问题,并没有被明确的分辨出其特异性,从而得到专门的对待。我们不管是在业界开源领域,还是内部分享中,很少会有专门针对游戏业务特征进行专门设计的组件、类库或者框架。我们从游戏的客户端方面来看,一款专业的游戏客户端引擎,已经是游戏开发的标配,比如最早的Flash Builder,到后期的Cocos2d-X,Unity,Unreal;但是服务器端,我们几乎找不到同样重量级的产品。 游戏服务器和一般服务器的区别   在游戏服务器端开发所有要面对的问题中,有两个是最核心和最普遍的:一是和客户端的通讯;二是游戏登录用户的数据处理。对于和客户端通讯的这个问题,大量的游戏开发者会使用“通用”的开源组件,比如Protocol Buffer,Thrift,Jetty,Node.js等等通信或RPC框架。虽然针对游戏,还是要做大量的改造,但一般都有很多现成的代码可供修改。   在一般的互联网应用中,我们一般 继续阅读 >>


师毅 17/02/27 02:57:55
卡牌、跑酷等弱交互服务端 卡牌跑酷类因为交互弱,玩家和玩家之间不需要实时面对面PK,打一下对方的离线数据,计算下排行榜,买卖下道具即可,所以实现往往使用简单的 HTTP服务器: 登录时可以使用非对称加密(RSA, DH),服务器根据客户端uid,当前时间戳还有服务端私钥,计算哈希得到的加密 key 并发送给客户端。之后双方都用 HTTP通信,并用那个key进行RC4加密。客户端收到key和时间戳后保存在内存,用于之后通信,服务端不需要保存 key,因为每次都可以根据客户端传上来的 uid 和 时间戳 以及服务端自己的私钥计算得到。用模仿 TLS的行为,来保证多次 HTTP请求间的客户端身份,并通过时间戳保证同一人两次登录密钥不同。 每局开始时,访问一下,请求一下关卡数据,玩完了又提交一下,验算一下是否合法,获得什么奖励,数据库用单台 MySQL或者 MongoDB即可,后端的 Redis做缓存(可选)。如果要实现通知,那么让客户端定时15秒轮询一下服务器,如果有消息就取下来,如果没消息可以逐步 继续阅读 >>


师毅 17/02/24 22:48:49
TCP服务特点 面向连接、基于字节流和可靠传输。 TCP的面向连接是什么意思? 通信双方都必须先建立连接,然后才能开始数据的读写,双方都必须为该连接分配必要的内核资源,以管理连接的状态和连接上数据的传输。 同时,TCP连接是全双工的,就是说,双方数据的读写,可以通过一个连接进行,完成数据交换之后,通信双方都必须断开连接,以释放系统资源。而且,TCP连接是一对一的,所以,基于广播和多播的应用程序不能使用TCP服务,而无连接协议UDP,倒非常适合广播和多播。 字节流服务和通信报区别 主要体现在通信双方是否执行相同次数的读写操作。 如图所示,当发送端应用程序同时执行多次写操作时,TCP模块必须先将这些数据放入发送缓冲区中,当TCP模块真正发送数据时,发送缓冲区中这些数据才会被封装成一个或多个TCP报文段发出,简言之,TCP模块发出的报文段个数与发送端应用程序执行的写操作次数之间没有固定的数量关系。 同时,当接收端收到一个或多个TCP报文段后,TCP模块要将它们携带的应用数据根据的T 继续阅读 >>


师毅 17/02/20 02:22:13
在Linux中经常发现空闲内存很少,似乎所有的内存都被系统占用了,表面感觉是内存不够用了,其实不然。这是Linux内存管理的一个优秀特性,主要特点是,无论物理内存有多大,Linux 都将其充份利用,将一些程序调用过的硬盘数据读入内存(buffer/cache),利用内存读写的高速特性来提高Linux系统的数据访问性能。在这方面,区别于Windows的内存管理。本文从Linux的内存管理机制入手,简单介绍linux如何使用内存、监控内存,linux与windows内存管理上的区别简介,linux内存使用的一大特点(buffer/cache的异同)。 一、Linux内存管理机制 物理内存和虚拟内存   我们知道,直接从物理内存读写数据要比从硬盘读写数据要快的多,因此,我们希望所有数据的读取和写入都在内存完成,而内存是有限的,这样就引出了物理内存与虚拟内存的概念。   物理内存就是系统硬件提供的内存大小,是真正的内存,相对于物理内存,在linux下还有一个虚拟内存的概念,虚拟内存就是为了满足物 继续阅读 >>


师毅 17/02/16 04:07:24
前言 ps:一直希望有个游戏服务端的技能树,此文算是指明方向,故记录于此。 知道该去哪打怪、打什么怪,升级才快。 本文作为游戏服务器端开发的基本大纲,是游戏实践开发中的总结。第一部分专业基础,用于指导招聘和实习考核, 第二部分游戏入门,讲述游戏服务器端开发的基本要点,第三部分服务端架构,介绍架构设计中的一些基本原则。 希望能帮到大家。 一、专业基础 1.1 网络 1.1.1 理解TCP/IP协议 网络传输模型 滑动窗口技术 建立连接的三次握手与断开连接的四次握手 连接建立与断开过程中的各种状态 TCP/IP协议的传输效率 思考: 1)请解释DOS攻击与DRDOS攻击的基本原理 2)一个100Byte数据包,精简到50Byte, 其传输效率提高了50% 3)TIMEWAIT状态怎么解释? 1.1.2 掌握常用的网络通信模型 Select Epoll,边缘触发与平台出发点区别与应用 Select与Epol 继续阅读 >>


师毅 17/02/15 02:50:03
什么是三次握手 学过网络编程的人,应该都知道TCP建立连接的三次握手,下面简单描述一下这个过程。 如图所示 第一次握手:客户端发送TCP包,置SYN标志位为1,将初始序号X,保存在包头的序列号(Seq)里。 第二次握手:服务端回应确认包,置SYN标志位为1,置ACK为X+1,将初始序列号Y,保存在包头的序列号里。 第三次握手:客户端对服务端的确认包进行确认,置SYN标志位为0,置ACK为Y+1,置序列号为Z。 为什么不是两次 我们先来将三次握手这个过程捋一遍。(S-服务端,C-客户端) 第一次握手后,S可以确认自己收报文与C发报文的功能都正常,而C呢,它什么都不能确认。 第二次握手后,C可以确认自己的收发报文与S的收发报文功能都正常,也就是认为连接已建立。 那么第三次呢,S也可以确认双方能够正常通信。 假想一下,如果我们去掉了第三次呢? 因为我们不进行第三次握手,所以在S对C的请求进行回应(第二次握手)后,就会理所当然的认为连接已建立,而如 继续阅读 >>


师毅 17/02/09 16:33:45