多人在线斗地主游戏开发——自定义TCP网络通信协议包格式
什么叫做通信协议?为什么制定通信协议? 怎么制定通信协议? 不知道大家有没有迷茫过这个问题,反正我是有的,,,
想我在刚接触网络编程的时候,是linux下用socket懵懵懂懂地按照pdf书籍上的代码敲了个非常简单的C/S架构的 聊天程序,
Client端发一个字符串,服务器接收到打印后,再返回一个字符串,敲完了后,自己运行着这个‘很牛 很高大上’的程序,玩得不亦乐乎,同时脑子里迸发了一大堆的想法,终于会网络编程了,之前写的程序只能在本地运行,现在应该可以利用socket写出网络通信的程序了,我可以把自己写的‘游戏’、‘软件’发给远在他方的朋友,一起联网运行(事实上,想多了,理想是丰满的,现实是异常骨感的)。
经过了一番思考,动手利用socket写了个简单的发送文件的程序,Client发送FileName至Server, Server收到后返回“OK”,然后Client开始读取文件数据,并send.
其实这里的Client发送FileName,服务器返回OK, 可以说就是所谓的通信协议了,只不过是简陋得有点可怜的通信协议。
通信协议,实际上就是一种通信的约定,我发什么数据给你,你根据我发的这个数据,要返回什么数据给我,例如下面这个不是很好的例子:
上面就是一个简单登录协议, 开发者在动手敲代码之前,就已经规定了Client会发送哪些数据,服务器要怎样响应数据,如Client 发送‘用户名和密码数据,验证登录’, Server收到后根据协议,就知道这条指令是什么意思,需要我做什么事情,然后我做完了之后该怎么返回结果给Client, 按照上面定好的协议,Server如果验证成功,则返回B 代表的指令, 如果验证失败,则返回C代表指令,而且只能返回这两者其一,不能返回其他数据, 一般协议之外的其他消息数据应该被程序认为是不合法的数据,无效的数据。
如果Server返回的是B, 那么Client就知道账户密码正确,登录成功了,如果B的指令数据中含有Hall Server(大厅服务器)的IP和Port的话, Client就知道,它可以连接游戏大厅了
如果Server返回的是C, 那么Client就知道验证失败了,就会做失败的处理。
所以,通信协议就是一个约定,一个规定,一份对应的请求和响应指令,我发送什么指令给你,你根据我的指令判断 你需要做什么操作,然后根据协议约定的返回结果的数据格式,返回结果给我,我收到你的返回,根据协议上的约定,我就知道接下来我该怎么去做。
那到这里了,大家可能想问了,在我不知道什么是通信协议的时候,我就已经在用着了,就像上面发送文件的程序一样,我发个字符串给服务器,服务器给我返回一个字符串就行了,那我就按照这样就可以了,何必要再花时间费脑子去制定一个协议呢?
那不知道大家在写socket TCP程序的时候,有没有遇到过粘包的问题,那时候我和两个同学,写一个局域网斗地主游戏,在tcp通信的时候,经常会遇到这个问题,当Client有连续发送“OK”、“bige”两条消息给服务器的时候,理想状态是,服务器接收到“OK”,然后做相应处理,然后接收到“bige”,再做相应处理, 而实际上呢,服务器接收到的是“OKbige”, 然后导致服务器不知道这是条什么命令,然后无任何相应,甚至出错。
socket Tcp是流式地发送数据,没有上一条数据和下一条数据之间的界限,属于是水乳交融,无缝连接的。
那么该怎么解决连包的问题呢?
我们可以通过制定一份通信协议来解决连包问题,同时也大大降低程序通信的混乱性,提升代码可读性和健壮性。
通过阅读了多个开源游戏服务器的网络通信模块,以及一些文档资料,我大概确定怎样制定一份协议,(我知道这可能不是一份完美的协议格式,可能存在一些问题,如果有何建议的话,恭请不吝指教)如下:
一条协议数据应该由三部分组成:协议头 + 指令数据 + 校验码
1)协议头: 必须固定大小为多少字节,例如:
有了协议头后,解析协议数据的时候,先接受10个字节的协议头数据,然后在协议头中解析指令类型,再解析指令数据长度length,然后再读取length个字节的数据,这length个字节的数据就是一条单独的指令,后面还有数据的话,就等下次解析了。
2)指令数据: Client与Server之间具体的请求响应交互操作
3)校验码:
校验码一是校验协议包的完整性,二是校验协议包的合法性,防止有其他人恶意 发送消息给Server,造成Server的资源消耗等
所以完整的协议格式应该如下(序号可以视情况选择用不用):
发送方 根据此协议格式组织 协议包,发送给接收方,接收方接收后的解析步骤:
1)读取10字节协议头, 解析出指令长度len
2)接着后面读取len个字节的数据,此时,已经读取了len+10字节数据,刚好就是一个完整的协议包
3)将前len+10-2个字节数据,进行校验算法的校验,生成出两字节的校验位
4)将生成的校验位与接收到的协议包中的校验位进行比较,如果相同则,指令正确,如果不同,则校验失败,数据异常,可以选择丢掉数据等处理
5)校验成功后,根据协议包中的指令类型,将指令分发到对应功能的接口模块,进行处理。
此外,通常情况下,为了防止tcp通信的协议包被抓包破解,泄漏程序的业务流程,造成极大的安全隐患,在发送组织好的协议包之前,还会用加密算法,将指令数据进行加密,然后再发送至接收端,接收端,先进行解密,再效验数据。
网络通信中用到的通信格式,还有Json、XML、谷歌的protobuf等等
多人在线斗地主游戏开发——自定义TCP网络通信协议包格式相关推荐
- 网络游戏demo开发实例:多人在线RPG游戏(MMO RPG)demo的开发记录(第0篇)
最近在业余时间制作一个MMO RPG的demo,代码提交在github上,有兴趣的朋友可以自己导出代码(https://github.com/changjixiong/MMO-RPGGame), 方法 ...
- 全球最大多人在线创作游戏Roblox暂时关闭 官方称将尽快恢复运行
10月31日消息,据网友爆料,世界最大的多人在线创作游戏Roblox近日突然下线. Roblox官网只留下了一张图片,图片显示,"正在让事情变得更好,稍后就会回来". 10月29日 ...
- 想要和朋友一起打猎吗?狩猎场Online多人在线打猎游戏,快来玩吧!
想要和朋友一起打猎吗?狩猎场Online多人在线打猎游戏,快来玩吧! posted on 2016-08-15 22:47 雨亭 阅读( ...) 评论( ...) 编辑 收藏 转载于:https:/ ...
- 棋牌微信小游戏之多人在线斗地主源码分享
游戏说明: 这是一款多人在线的斗地主棋牌游戏,拥有随机匹配功能,有三人同时匹配即可开始游戏.游戏支持微信约战,玩家通过在微信上发送邀请信息给微信好友,好友点击信息即可进入游戏. (PS:需要自己配置自 ...
- java斗地主游戏开发 算法思路讲解
上学期刚开学的时候我特别沉迷于斗地主 充了6块钱赢了30万豆 然后一夜之间破产 越想越气 然后我就有一个大胆的想法开发一个斗地主现在这个斗地主能在控制台上运行 本文主要讲解我在开发斗地主时研究的算法思 ...
- 正在做的一款HTML5多人在线扑克牌游戏:99分
用Node.JS做服务端,用WebSockets通信,实现HTML5多人在线游戏. 这款扑克牌游戏名称叫99分,源于活动聚会时常多人玩的一种扑克游戏,特别适合6人.8人.10人玩. 这个游戏由3个爱好 ...
- Java网络编程,使用Java实现UDP和TCP网络通信协议,以及基于UDP的在线聊天室。
文章目录 前言 一.网络编程概念 1.网络 2. 网络编程的目的 3.想要达到这个效果需要什么 4.网络分层 二.网络编程Java类 1.IP地址:InetAddress 2.端口 3.TCP连接 3 ...
- 网络游戏demo开发实例:多人在线RPG游戏(MMO RPG)demo的开发记录(第3篇)
version4 主要内容:透明贴图 所属部分:客户端 代码地址 https://github.com/changjixiong/MMO-RPGGame, 如何获得代码,请参考如何用SVN从githu ...
- Linux项目--多人在线聊天系统的开发
项目名称:群聊工具的开发 系统原理:该项目是源于<Linux高性能服务器编程>一书中所提到的多进程或者多线程编程的部分,利用多线程编程来实现一个简单的多人聊天室.在多进程或多线程编程中,最 ...
最新文章
- 厉害了,程序员的高考试卷,你能拿几分?
- Confluence 6 使用 WebDAV 客户端来对页面进行操作
- 原型模式、模板方法、迪米特法则、外观模式
- 英伟达jetson TX1的caffe-ssd配置
- centos7花里胡哨之终端美化
- java高并发(十六)J.U.C之ForkJoin
- Android自定义控件学习(六)-------使视图互动
- 6.3 二进制文件操作案例精选
- 【SQL】BETWEEN
- a标签创建超链接,利用a标签创建锚点
- JAVA怎么打开pkg_PKG文件在电脑上怎么打开!(普通PC)
- 南京师范计算机科学研究生分数线,2020南京师范大学考研复试分数线已公布
- UWB DW1000 TWR测距定位功能实现
- 更改Linux系统的主机名(hostname)两种实用的方法
- Intellij IDEA误删文件如何恢复
- 用Tina-TI软件仿真并分析RC积分电路和微分电路
- 睡眠周期时长测试软件,成为时间管理达人必备的六款软件(干货)
- java s c r ipt_Java Scr ipt高级应用与实践_前端开发教程_源雷技术空间
- 在hexo中使用mathjax的方法
- 函数调用函数实现(判断二月有多少天)