原地址:http://www.9miao.com/question-15-53940.html

好,经过上一篇不权威的讲解,大家已经能轻易地让客户端和服务端连接起来了。

但是,仅仅是连接了,可它们俩不说话不交流,那游戏就玩不起来了,玩不起来那我就赚不到钱..啊不是,玩不起来那玩家就不能开心了,钱是…啊不!玩家是最重要的嘛~不能让玩家不开心(小若:好好好,看出来了,钱是最重要的是吧)

好~!这次木头就和大家一起见证客户端和服务端的第一次交谈吧~!

声明:
本教程基于FireFly1.2.2版本、Python2.7版本。
本教程面向Python和FireFly初学者中的初学者(比如我)
本教程由笨木头花心贡献,花心?不,是用心~!
转载请注明原文地址:http://www.benmutou.com/blog/archives/727

1. Pythone struct模块
Struct模块主要是用来对数据进行打包和解包的,和LiberateFactory不一样,LiberateFactory已经说了,是协议工厂,当然就主要是对协议进行封装和解析。而struct是对更底层的数据操作,是把数据打包成二进制的形式,然后在网络中传输。解包也一样,把二进制形式的数据解包成Pythone需要或者说比较好识别的格式。
反正,总之,struct模块是对数据进行打包和解包的,解释完毕~

2. 可以发送请求的客户端(client.py)
我们要修改客户端,以便它可以发送数据给服务端。

  1. #coding:utf8

  2. '''

  3. Created on 2013-10-8

  4. @author: 笨木头_钟迪龙 www.benmutou.com

  5. '''

  6. from socket import AF_INET, SOCK_STREAM, socket

  7. import struct

  8. def sendData(sendstr, commandId):

  9. HEAD_0 = chr(0) # 协议头0

  10. HEAD_1 = chr(0) # 协议头1

  11. HEAD_2 = chr(0) # 协议头2

  12. HEAD_3 = chr(0) # 协议头3

  13. ProtoVersion = chr(0) # 协议头版本号

  14. ServerVersion = 0 # 服务器版本号

  15. sendstr = sendstr

  16. data = struct.pack('!sssss3I', HEAD_0, HEAD_1, HEAD_2, HEAD_3,\

  17. ProtoVersion, ServerVersion, len(sendstr) + 4, commandId)

  18. senddata = data + sendstr

  19. return senddata

  20. if __name__ == '__main__':

  21. HOST = "localhost" # 服务端地址

  22. PORT = 1000 # 服务端端口

  23. ADDR = (HOST, PORT)

  24. client = socket(AF_INET, SOCK_STREAM) # 创建socket,TCP

  25. client.connect(ADDR) # 连接服务器

  26. client.sendall(sendData('hello server', 1))# 发送数据给服务器

  27. while True:

  28. pass

复制代码

觉得复杂吗?其实就多了一个sendData函数而已。(小若:但是它很复杂!)

2.1 协议头部信息
我们先来解释一下协议头、协议头版本号、服务器版本号。我也没有深入了解,但就这么看,我唯一能想到的就是:这些东西是用来检测客户端和服务端是否同步的。

经过我“深入”FireFly源码之后,发现了确实有这么一个用途,当服务端的协议工厂接收到数据时,会先判断这些协议头和版本号是否正确,不正确的话,是不会往下继续执行的。
由于这是入门教程,就不一层层地贴这些代码了,也不继续深入了,因为它不是本文的重点。

重点是struct的pack函数,大家可以看看这篇文章:
http://www.cnblogs.com/coser/archive/2011/12/17/2291160.html
只看第1、2点就暂时够用了。

于是,上面代码里的pack函数就是把4个协议头、协议头版本号、服务器版本号、发送的数据长度、命令码打包。
这样打包后的数据作为一个数据的头部信息,顾名思义,头部信息就是记录一次发送数据的主要信息,比如长度、版本、命令码。(小若:废话!上面都说了把这些东西打包了)

然后我们看看这句代码:senddata = data + sendstr。
为什么发送的数据字符串不需要参与打包呢?我也很白痴地试了一下把数据字符串也一起参与打包,结果是一样的。
于是,据我所知,字符串可以直接传输(字节流),不需要再进行什么打包了。

2.2 发送数据
客户端要发送数据给服务端很简单:client.sendall(sendData(‘hello server’, 1))
这句代码的意思是,发送字符串‘hello server’给服务端,命令码是1。
结合之前说的,命令码1会参与到数据头部信息一起打包,而字符串’hello server’是直接和打包后的数据连接的,不需要参与打包。

2.3 为什么数据长度要+4?
不知道大家会不会有个疑问,就是打包的时候这个参数:len(sendstr) + 4
为什么长度要+4,木头我是弄不明白了,我查看了源码,在解析头部信息的时候,获取数据长度值时,又减去了4。这看起来有点多此一举,据我目前的研究,还没法知道原因,希望高手支招。

[笨木头FireFly 02]入门篇2_客户端发送请求,服务器处理请求的更多相关文章

  1. 转一篇Unity客户端与Java服务器的通信

    转自:http://www.programering.com/a/MTNxYDMwATQ.html A few days ago a friend asked me about Unity3D ins ...

  2. asterisk-java ami 入门篇,连接与关闭服务器

    我选择的是通过AsteriskServer 来生成连接,因为后面要通过AsteriskServer来进行监听通话属性的改变. demo: AsteriskServer asteriskServer=n ...

  3. TCP 同步传输:客户端发送,服务器段接收

    1.服务器端程序 可以在TcpClient上调用GetStream()方法来获的链接到远程计算机的网络流NetworkStream.当在客户端调用时,他获的链接服务器端的流:当在服务器端调用时,他获得 ...

  4. swift开发网络篇—利用NSURLSession 发送GET和POST请求

    说明:本文示例代码发送的请求均为http请求,需要对info.plist文件进行配置.如何配置,请参考https://github.com/HanGangAndHanMeimei/iOS9Adapta ...

  5. (转载)从Java角度理解Angular之入门篇:npm, yarn, Angular CLI

    本系列从Java程序员的角度,带大家理解前端Angular框架. 本文是入门篇.笔者认为亲自动手写代码做实验,是最有效最扎实的学习途径,而搭建开发环境是学习一门新技术最需要先学会的技能,是入门的前提. ...

  6. soap入门篇

    摘自:http://blog.csdn.net/erica_1230/article/details/54982081 SOAP的全称是Simple Object Access Protocol,即简 ...

  7. 从Java角度理解Angular之入门篇:npm, yarn, Angular CLI

    本系列从Java程序员的角度,带大家理解前端Angular框架. 本文重点介绍Angular的开发.编译工具:npm, yarn, Angular CLI,它们就像Java在中的Maven,同时顺便介 ...

  8. Go语言入门篇-jwt(json web token)权限验证

    一.token.cookie.session的区别 1.cookie Cookie总是保存在客户端中,按在客户端中的存储位置,可分为内存Cookie和硬盘Cookie. 内存Cookie由浏览器维护, ...

  9. Netty学习记录-入门篇

    你如果,缓缓把手举起来,举到顶,再突然张开五指,那恭喜你,你刚刚给自己放了个烟花. 模块介绍 netty-bio: 阻塞型网络通信demo. netty-nio: 引入channel(通道).buff ...

随机推荐

  1. 怎么改svn的登陆账号

    svn 我想大家都很熟悉.用的也很多.可是上次遇到一个问题 ,就是用别人的svn下载的代码.选择了记住账号密码.结果提交的时候 还是用别人的不大好.结果就想改成自己的账号.第一次改 找了半天.今天给大 ...

  2. SVN Application

    一.SVN客户端:TortoiseSvn 下载地址: http://tortoisesvn.net/downloads.html 安装完后重启, 右击就可以使用SVN命令 首先, 从服务器版本库那边 ...

  3. C# GET 和 SET作用

    C#中get和SET,看来看去还是看不懂,通俗一点解释一下,用了有什么好处,不用会怎么样 如果你这样写是没有什么不一样的. private int __Old; public int Old{ get ...

  4. win7下64位系统memcache/memcached安装教程

    折腾了1个多小时,终于搞定.操作系统时64位的,php5.3.13 类似于上一篇的xdebug安装教程~~ memcache和memcached的区别  在自己的新程序中打算全面应用memcached ...

  5. JavaScript之数组对象

    Array类型是ECMAScript中最常用的类型了. 一.声明方式 1.使用Array构造函数 var arr1 = new Array(); 如果预先知道要保存数组的数量, 也可以给构造函数传递该 ...

  6. CodeBlocks对C++模板的支持

    坦率的说CodeBlocks是一款不错的跨平台编译器,一般编写C/C++都是使用它,但最近在编写C++模板文件时,发现它对模板的支持并不是很好.具体表现在模板的定义与声明分开的问题上. 一般编写C/C ...

  7. [转载]mysql慢日志文件分析处理

    原文地址:mysql慢日志文件分析处理作者:maxyicha mysql有一个功能就是可以log下来运行的比较慢的sql语句,默认是没有这个log的,为了开启这个功能,要修改my.cnf或者在mysq ...

  8. DB Cache Reloaded Fix缓存不能被激活解决方法

    1.创建wp-content/plugins/db-cache-reloaded-fix/cache目录. 2.将cache权限改为777. 3.拷贝wp-content/plugins/db-cac ...

  9. 弹性布局学习-详解 justify-content(三)

    弹性布局学习-详解 justify-content(三)

  10. cocos3.10 使用cocostudio 回调特性 c++版本说明

    cocos3.10 使用cocostudio 回调特性 c++版本说明 好久没捣鼓cocos2dx了,又拿起来玩玩,看着版本一次次的升级,真的好快,今天用cocos3.10版本测试下时间特性功能,跟着 ...