来源:http://ciniao.me/article.php?id=14

---------------

刺鸟原创文章,转载请注明出处
    前面的工作都已准备就绪,现在我们得来看看服务端怎么和客户端之间进行通信了,Python和FLASH之间的通信,我整理为以下3种:

1、用现成的协议及类库处理,比如:pyamf
    2、自己封包进行二进制数据流通信
    3、用JSON字符串通信

一、JSON和二进制数据流的优缺比较
    pyamf有比较现成的文档,因此,这里我主要研究研究后两种。我们先简单分析下JSON和数据流各自的优缺点:
    JSON:
    优点:数据结构灵活,无需先制定复杂的协议;跨语言之间基本都有完整的解决方案。
    缺点:传送的数据因为要增加json的特征符(',"",:,{等),导致数据量较大;明文传输,无安全性可言。
    二进制数据流:
    优点:数据量小,无协议文档的话,较难破解内容。
    缺点:数据不灵活,需要先制定足够完善的协议文档。

权衡利弊,在当前项目中,采用二进制数据流是更为合适的方案。

二、拆包和粘包
    我们下面来了解下python对于数据流通信这块的功能。根据TCP/IP通信的特点,不管是采用JSON字符串,还是二进制数据流,都必须面临的一个问题是:数据的拆包和粘包,具体的问题表现如下:
    采用如下代码,向socket服务器发送5000长度的数据,可以看到,在数据大于4000左右的时候被拆包,触发了服务端的2次dataReceived事件。

conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conn.connect(("127.0.0.1", 5200))
conn.send('abcdefghij'*500)

服务端接收情况:

也即是说,在这里我们得粘包,保证数据完整后,才执行对应的逻辑。还有另外一种情况:客户端两次短暂的间隔时间内向服务端发送数据流时,TCP协议会将这2次数据合并为一次后,发送给服务端,如果遇到这样的情况,就需要我们对数据进行拆包处理。

三、常见的数据格式
    传输的数据中,常见的包括以下类型:字符串(长度可变),字节(1位),长整数(4位),无符号整形(4位),短整形(2位)。以上数据中,字符串是长度未定的,因此我们得使用一个短整型在字符串前,以便程序能知道后面的string占了几位。
    另外,为了计算封包的完整性,我们需要在封包首尾各指定一特殊的标示位。为了快速的读取数据,我们需要在封包头记录其长度。综上,我们制定了如下封包格式:

0x11 + 封包长度 + 协议号 + 数据 + 0x22

当中协议号int型(如:3290),如果数据是string,则保存为 short(str长度) + string(str内容)

四、python的二进制处理库
    有了封包格式,我们再来看下python中如何编码实现封包,这时,我们需要用到struct库,struct库主要有以下3个方法:

struct.pack(fmt,v1,v2,.....)

将v1,v2...等参数的值进行pack处理,pack的格式由fmt指定。被pack参数必须严格符合fmt。最后返回一个包装后的字符串。

struct.unpack(fmt,string)

顾名思义,解包,返回一个由解包数据(string)按照fmt格式解包后的元组(即使仅有一个数据也会被解包成远祖)。

struct.calcsize(fmt)

用来计算fmt格式所描述的结构的大小

其中,fmt的格式所代表的含义和更多对struct的介绍,请浏览官方文档。

五、我们的pack
    接下来,需要写一个方法,来按照我们的封包格式,对数据进行pack处理。

#coding:utf-8
#基于python2.6
'''
按照我的习惯,重写struct的格式化符为:
s=字符串
b=字节
i=长整数
u=无符号整形
n=短整形
'''
datafmt = {'1001':'ssbi',#指定1001协议的数据格式,如果按如上指定,则表示该封包由#字符串 + 字符串 + 字节 + 长整型#构成
}
import struct
#对数据进行pack数据 comid(string)=协议号 data(list)=数据内容
def pack(comid,data):global datafmtif comid not in datafmt:print comid,'协议fmt格式读取错误'fmtStr = datafmt[comid]fmtStrRes = []idx = 0fixString ={}for k in fmtStr:if k=='n':fmtStrRes.append('h')elif k=='b':fmtStrRes.append('b')elif k=='u':fmtStrRes.append('I')elif k=='i':fmtStrRes.append('i')elif k=='s':_strLength = len(data[idx])fixString[idx] = _strLength #记录str的长度fmtStrRes.append('h'+ str(_strLength) +'s')idx = idx + 1fmt = '<'+''.join(fmtStrRes)#将字符串的长度值插入到data中if len(fixString)>0:idx = 0for k,v in fixString.items():data.insert(k+idx,v)idx = idx + 1print 'data=',dataprint 'fmt=',fmtres = struct.pack(fmt,*data)print 'pack=',respack('1001',['abc','中文',3,7654])

运行看看:

至于unpack和拆包粘包,就交给你来自己练手了,应该没有难度了吧!

#本文由刺鸟原创,欢迎转载,但请保留出处,也欢迎对本文感兴趣的同学多多交流。#

------

转载于:https://www.cnblogs.com/ezhong/p/3385834.html

转:: 刺鸟:用python来开发webgame服务端(4)相关推荐

  1. 聚播微信多开客服系统二次开发SDK服务端接口

    聚播微信多开客服系统二次开发SDK服务端接口 case HeartBeatReq: {// 客户端发送的心跳包heartBeatReqHandler.handleMsg(ctx, msgVo);bre ...

  2. python搭建客户端和服务端

    python搭建客户端和服务端 前言 一.客户端搭建 搭建过程整理 TCP客户端 2.x版本 3.x版本 UPD客户端 2.x版本 3.x版本 二.TCP服务端搭建 搭建过程整理 2.x版本 3.x版 ...

  3. C++后端开发程序员应该彻底搞懂的【libevent网络库】,libevent组件构成以及编程要领丨Linux服务器开发丨服务端编程

    90分钟搞懂libevent网络库 1. 服务端事件组成 2. libevent组件构成以及编程概要 3. memcached是如何使用libevent 视频讲解如下,点击观看: C++后端开发程序员 ...

  4. 聚播微信群控云控引擎二次开发SDK服务端对接接口

    聚播微信群控云控引擎二次开发SDK服务端对接接口 case HeartBeatReq: {// 客户端发送的心跳包heartBeatReqHandler.handleMsg(ctx, msgVo);b ...

  5. 17 SSR:使用 React.js 开发 Serverless 服务端渲染应用

    今天我想和你聊一聊怎么用 Serverless 开发一个服务端渲染(SSR)应用. 对前端工程师来说,Serverless 最大的应用场景之一就是开发服务端渲染(SSR)应用.因为传统的服务端渲染应用 ...

  6. C++ 开发SOAP服务端和SOAP客户端

    C++ 开发SOAP服务端和SOAP客户端 作者:flyfish  2012-5-12 目的:利用gSOAP自带的Calc例子 仿写一个 网络中使用计算器 客户端通过http发送xml格式的数据请求, ...

  7. 使用KBEngine开发UE4服务端——开发详解

    使用KBEngine开发UE4服务端--开发详解 1. 简述 开始正式进入开发,网络上关于开发和修改文件的文章较少,这里会记录自己开发过程中需要更改的地方和一些流程. 2. 前期的配置说明 根据前文配 ...

  8. Python 主流棋牌游戏 服务端 框架分析 原创笔记

    经测试此产品运营稳定 包含数十款房卡子游戏.俱乐部(五级权限).比赛场 客户端采用Lua脚本开发 .后端Python 看过一些棋牌产品 很多产品基于此套棋牌框架开发而来 算市面上一个主流框架 但却没有 ...

  9. 【转】使用Apache CXF开发WebServices服务端

    原地址:http://cnjava.blog.51cto.com/1208887/335630 在前一篇的博客中,我使用Xfire1.x来开发了WebServies的服务端. 但是如果你访问Apach ...

  10. grpc(3):使用 golang 开发 grpc 服务端和client

    1,关于grpc-go golang 能够能够做grpc的服务端和client. 官网的文档: http://www.grpc.io/docs/quickstart/go.html https://g ...

最新文章

  1. django-restframework使用
  2. [51NOD1847]奇怪的数学题(杜教筛+min_25筛+第二类斯特林数)
  3. http 和 https_HTTPS与HTTP区别
  4. Android SharedPreferences总结及优化
  5. 【机器学习】sclearn分类算法-决策树、随机森林
  6. Vicor再携创新产品“登陆”ODCC大会,有详情!
  7. python运用在哪些地方_必看 | 2020年,Python十大应用领域介绍!
  8. criteria函数_1.2.21 EXCEL篇之函数篇-数学与三角函数1
  9. 抽象类应用模板方法模式和接口应用之策略设计模式
  10. C语言 循环群,数学函数符号
  11. 张宇:【线性代数】公式汇总!
  12. linux下的文件io编程实现文件的拷贝
  13. 电工技师技能实训考核装置QY-W601C
  14. SpringMVC框架 -- ModelAndView的用法
  15. CCA分析图如何解读_BI报表控件Wyn使用教程:如何使用网状/雷达图进行数据分析...
  16. DongTai被动型IAST工具部署
  17. exchange创建邮箱组_Exchange批量创建用户组及启用通讯组邮箱
  18. blockchain-explorer(pg版) 区块浏览器部署及配置详解
  19. 克里斯蒂安贝尔_克里斯蒂安贝尔解释为何只演3次蝙蝠侠
  20. 北京化工大学2018年10月程序设计竞赛 F. 罗dalao的密码(递归)

热门文章

  1. 用英文给领导写建议信
  2. Fast RTPS原理与代码分析(2):动态发现协议之参与者发现协议PDP
  3. 阿里巴巴高级Java面试题(首发,70道)
  4. word文件转换成PDF文件
  5. HTML5期末考核大作业,网站——旅游景点。 学生旅行 游玩 主题住宿网页
  6. 牡丹-洛阳牡丹:洛阳牡丹
  7. Python 计时器倒计时弹窗提醒
  8. STM32F407音乐播放器设计WM8978使用
  9. pcb上钽电容丝印图_pcb钽电容正负极该如何识别
  10. 内存超频时序怎么调_内存时序怎么调