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

article/2025/9/13 18:43:35

来源: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


http://chatgpt.dhexx.cn/article/YI450LX6.shtml

相关文章

[转]用python来开发webgame服务端(3)

[刺鸟原创文章&#xff0c;转载请注明出处] 在之前的准备工作中&#xff0c;我们已经建立了一个socket服务器&#xff0c;并且经过了简单的测试&#xff0c;得到的结论是python可以满足我们的需求&#xff0c;那么接下来&#xff0c;我们要解决的是身为webgame服务端必须的几个…

转:: 刺鸟:用python来开发webgame服务端(2)

来源&#xff1a;http://ciniao.me/article.php?id10 --------------- 刺鸟原创文章&#xff0c;转载请注明出处 就在刚才&#xff0c;我们用基于python下的Twisted库写了一个简单的socket服务器&#xff0c;不知道它的性能和基本的承载到底如何呢&#xff1f;接下来&#…

转:: 刺鸟:用python来开发webgame服务端(3)

来源&#xff1a;http://ciniao.me/article.php?id11 --------------- 刺鸟原创文章&#xff0c;转载请注明出处 在之前的准备工作中&#xff0c;我们已经建立了一个socket服务器&#xff0c;并且经过了简单的测试&#xff0c;得到的结论是python可以满足我们的需求&#x…

用python来开发webgame服务端(4)

http://ciniao.me/article.php?id14 前面的工作都已准备就绪&#xff0c;现在我们得来看看服务端怎么和客户端之间进行通信了&#xff0c;Python和FLASH之间的通信&#xff0c;我整理为以下3种&#xff1a; 1、用现成的协议及类库处理&#xff0c;比如&#xff1a;pyamf …

用python来开发webgame服务端(2)

http://ciniao.me/article.php?id10 刺鸟原创文章&#xff0c;转载请注明出处 就在刚才&#xff0c;我们用基于python下的Twisted库写了一个简单的socket服务器&#xff0c;不知道它的性能和基本的承载到底如何呢&#xff1f;接下来&#xff0c;我们作一个简单的测试。 …

用python来开发webgame服务端(3)

刺鸟原创文章&#xff0c;转载请注明出处 在之前的准备工作中&#xff0c;我们已经 建立了一个socket服务器 &#xff0c;并且经过了 简单的测试 &#xff0c;得到的结论是python可以满足我们的需求&#xff0c;那么接下来&#xff0c;我们要解决的是身为webgame服务端必须…

用python来开发webgame服务端

刺鸟原创文章&#xff0c;转载请注明出处 在开始之前&#xff0c;先简单描述一下项目的特点&#xff1a;我要实现的是一个mmorpg的webgame&#xff0c;地图上需要看到其他的玩家&#xff0c;战斗系统采用半回合制的模式&#xff0c;所谓的半回合制&#xff0c;即是&#xff1a;…

用python来开发webgame服务端(1)

http://ciniao.me/article.php?id9 刺鸟原创文章&#xff0c;转载请注明出处 在开始之前&#xff0c;先简单描述一下项目的特点&#xff1a;我要实现的是一个mmorpg的webgame&#xff0c;地图上需要看到其他的玩家&#xff0c;战斗系统采用半回合制的模式&#xff0c;所谓…

server: WebGame服务端架构分析

MMORPG服务器架构 一.摘要 1.网络游戏 MMORPG 整体服务器框架&#xff0c;包括早期,中期&#xff0c;当前的一些主流架构 2.网络游戏网络层,包括网络 协议 , IO 模型&#xff0c;网络框架&#xff0c;消息编码等。 3.网络游戏的 场景 管理, AI &#xff0c; 脚本 的应用等。 4.…

WebGame服务端架构分析(一)

做webgame也有段时间了,最近上线的游戏还处于起步阶段,第二个月收入突破100万了,跟市面上大的webgame比起来,根本不算什么,但有收入总比没有好,呵呵,以后还需更加努力。现在总结一下自己webgame的架构设计,总结的目的一方面是为了共享给网上的朋友,也希望网友给我提出…

Webgame服务端分布式架构设计

Webgame服务端分布式架构设计 ——By King 最近在设计实现Webgame服务端游戏架构&#xff0c;跟大家分享下。 以下对架构的几点说明&#xff1a; 1&#xff0e; DB&#xff1a;数据库层。使用MongoDB, 可以作分布式&#xff0c;按webgame的需求&#xff0c;基本应该是不需…

Vue3之获取DOM元素

简介 我们一般用ref函数来获取DOM元素 使用步骤 使用ref函数创建容器在需要获取的dom元素上写refdom元素保存在容器的value属性上 代码 <script setup> import {ref,onMounted} from "vue"const inputRef ref() onMounted(() > {console.log(inputRef…

vue中动态获取dom元素进行操作

这几天我远程面试了一家公司,期间问题我都回答上来了 但有一个问题我很纳闷 就是你说下vue中获取dom元素的方法吧 我说大体上俩中吧 1.vue中 ref的方法 给元素起一个ref名称 通过 this.$refs.ref名称获取 2.第二个无非是 原生dom操作了 document.getElement // document…

Vue笔记四:Vue获取DOM元素和组件元素的方法

文章目录 Vue获取组件元素ref获取组件元素 Vue获取组件元素 如果想使用哪个DOM元素&#xff0c;就给它加上ref属性&#xff0c;然后用$refs属性获取它的元素对象&#xff0c;示例如下&#xff1a; 全部代码&#xff1a; <!DOCTYPE html> <html><head><m…

Vue.js中$refs{}获取DOM元素

如果我们想获取DOM元素&#xff0c;一般使用js中的document.querySelector来获取这个dom节点&#xff0c;然后在获取元素的值&#xff0c;现在Vue提供给我们一种更便捷的方式来获取DOM元素-----$refs{} $refs{}----获取标签元素 说明&#xff1a;一个对象&#xff0c;持有注册…

vue中怎么获取元素

vue中怎么获取元素 在元素上添加 v-el&#xff1a;food-wrapper &#xff08;不用驼峰的写法&#xff09; vue1版本 报错&#xff1a; vue2版本 &#xff08;vue2把vue1中的 v-el 改为了 ref vue1 v-el:foods-wrapper 调用的时候 this. el.foodsWrappervue2ref:foods−wrapp…

vue怎么点击获取当前元素

vue中有两种方法获取到当前元素 var el event.target; //当前元素&#xff0c;可修改&#xff08;能够用此方法获取到他的子元素&#xff0c;不能获取他本身的内容&#xff09; var el event.currentTarget;//当前元素&#xff0c;不可修改&#xff08;能够用此方法获取到他的…

vue3获取dom

在vue3中获取dom&#xff0c;有几点需要注意&#xff1a; 1&#xff0c;获取dom的ref元素名称&#xff0c;要对应暴露的名称&#xff0c;不然会出现无效的dom报错&#xff0c;也就是拿到的是null 2,在setup中&#xff0c;使用ref&#xff08;null&#xff09;获取dom 3,不能…

vue3中获取dom元素和操作

一&#xff0c;需求概述 直接举例子来说明吧&#xff0c;我想要做的是&#xff0c;遍历这几个菜单&#xff0c;获取他们的dom元素的宽度。当文字dom元素宽度太长的话&#xff0c;需要滚动显示文本。 二&#xff0c;实现思路 对应的html: <div class"icon-box"…

vue 3.0 使用ref获取dom元素

前言 附上vue3.0文档&#xff1a;Vue3中文文档 - vuejs 2022.10.22 更新 鉴于较多人询问几个高频问题&#xff0c;在此做统一回复 ref.value获取到的是null 答&#xff1a;检查是否将ref变量return出去了 答&#xff1a;检查是在哪里进行的console.log&#xff0c;setup函数…