[笨木头FireFly 02]入门篇2_客户端发送请求,服务器处理请求
2014-08-11 16:45
204 查看
原地址: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)
我们要修改客户端,以便它可以发送数据给服务端。
#coding:utf8
'''
Created on 2013-10-8
@author: 笨木头_钟迪龙 www.benmutou.com
'''
from socket import AF_INET, SOCK_STREAM, socket
import struct
def sendData(sendstr, commandId):
HEAD_0 = chr(0) # 协议头0
HEAD_1 = chr(0) # 协议头1
HEAD_2 = chr(0) # 协议头2
HEAD_3 = chr(0) # 协议头3
ProtoVersion = chr(0) # 协议头版本号
ServerVersion = 0 # 服务器版本号
sendstr = sendstr
data = struct.pack('!sssss3I', HEAD_0, HEAD_1, HEAD_2, HEAD_3,\
ProtoVersion, ServerVersion, len(sendstr) + 4, commandId)
senddata = data + sendstr
return senddata
if __name__ == '__main__':
HOST = "localhost" # 服务端地址
PORT = 1000 # 服务端端口
ADDR = (HOST, PORT)
client = socket(AF_INET, SOCK_STREAM) # 创建socket,TCP
client.connect(ADDR) # 连接服务器
client.sendall(sendData('hello server', 1))# 发送数据给服务器
while True:
pass
复制代码
觉得复杂吗?其实就多了一个sendData函数而已。(小若:但是它很复杂!)
2.1 协议头部信息
我们先来解释一下协议头、协议头版本号、服务器版本号。我也没有深入了解,但就这么看,我唯一能想到的就是:这些东西是用来检测客户端和服务端是否同步的。
经过我“深入”FireFly源码之后,发现了确实有这么一个用途,当服务端的协议工厂接收到数据时,会先判断这些协议头和版本号是否正确,不正确的话,是不会往下继续执行的。
由于这是入门教程,就不一层层地贴这些代码了,也不继续深入了,因为它不是本文的重点。
重点是struct的pack函数,大家可以看看这篇文章:
/article/5038508.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。这看起来有点多此一举,据我目前的研究,还没法知道原因,希望高手支招。
好,经过上一篇不权威的讲解,大家已经能轻易地让客户端和服务端连接起来了。
但是,仅仅是连接了,可它们俩不说话不交流,那游戏就玩不起来了,玩不起来那我就赚不到钱..啊不是,玩不起来那玩家就不能开心了,钱是…啊不!玩家是最重要的嘛~不能让玩家不开心(小若:好好好,看出来了,钱是最重要的是吧)
好~!这次木头就和大家一起见证客户端和服务端的第一次交谈吧~!
声明:
本教程基于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)
我们要修改客户端,以便它可以发送数据给服务端。
#coding:utf8
'''
Created on 2013-10-8
@author: 笨木头_钟迪龙 www.benmutou.com
'''
from socket import AF_INET, SOCK_STREAM, socket
import struct
def sendData(sendstr, commandId):
HEAD_0 = chr(0) # 协议头0
HEAD_1 = chr(0) # 协议头1
HEAD_2 = chr(0) # 协议头2
HEAD_3 = chr(0) # 协议头3
ProtoVersion = chr(0) # 协议头版本号
ServerVersion = 0 # 服务器版本号
sendstr = sendstr
data = struct.pack('!sssss3I', HEAD_0, HEAD_1, HEAD_2, HEAD_3,\
ProtoVersion, ServerVersion, len(sendstr) + 4, commandId)
senddata = data + sendstr
return senddata
if __name__ == '__main__':
HOST = "localhost" # 服务端地址
PORT = 1000 # 服务端端口
ADDR = (HOST, PORT)
client = socket(AF_INET, SOCK_STREAM) # 创建socket,TCP
client.connect(ADDR) # 连接服务器
client.sendall(sendData('hello server', 1))# 发送数据给服务器
while True:
pass
复制代码
觉得复杂吗?其实就多了一个sendData函数而已。(小若:但是它很复杂!)
2.1 协议头部信息
我们先来解释一下协议头、协议头版本号、服务器版本号。我也没有深入了解,但就这么看,我唯一能想到的就是:这些东西是用来检测客户端和服务端是否同步的。
经过我“深入”FireFly源码之后,发现了确实有这么一个用途,当服务端的协议工厂接收到数据时,会先判断这些协议头和版本号是否正确,不正确的话,是不会往下继续执行的。
由于这是入门教程,就不一层层地贴这些代码了,也不继续深入了,因为它不是本文的重点。
重点是struct的pack函数,大家可以看看这篇文章:
/article/5038508.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]入门篇_客户端发送请求,服务器处理请求
- 由于内部错误,服务器无法处理该请求。有关该错误的详细信息,请打开服务器上的 IncludeExceptionDetailInFaults (从 ServiceBehaviorAttribute 或从 <serviceDebug> 配置行为)以便将异常信息发送回客户端,或打开对每个 Microsoft .NET Framework SDK 文档的跟踪并检查服务器跟踪日志。
- SuperSocket入门--Telnet服务器和客户端请求处理
- 由于内部错误,服务器无法处理该请求。有关该错误的详细信息,请打开服务器上的 IncludeExceptionDetailInFaults (从 ServiceBehaviorAttribute 或从 <serviceDebug> 配置行为)以便将异常信息发送回客户端,
- android下socket编程问题:服务器关闭时,客户端发送请求的异常处理
- SuperSocket入门(一)-Telnet服务器和客户端请求处理
- Lunix网络编程之socket(客户端发送请求,服务器处理例如:排序,两人联机五子棋)
- java客户端数据发送到服务器(POST请求)总结
- Java客户端通过Http发送POST请求上传文件到web服务器
- C语言 Socket入门示例1—— 单工通信(客户端向服务器发送消息)
- Windows Server 2003 使用vSphere5.5连接ESXI5.5 “客户端无法向服务器发送完整的请求” 的解决办法
- Enter-PSSession : 连接到远程服务器失败,错误消息如下: WinRM 客户端无法处理该请求
- 解决连接vcenter (客户端无法向服务器发送完整的请求。(基础连接已经关闭:发送时发生错误。)) 问题
- Web 服务器处理客户端请求过程
- Windows Server 2003 使用vSphere5.5连接ESXI5.5 “客户端无法向服务器发送完整的请求” 的解决办法
- Ajax---通过JSON与服务器通信(发送请求和处理响应)
- VMware vSphere client 5.1登录出现这个错误:客户端无法向服务器发送完整请求
- 【安卓笔记】android客户端向tomcat服务器发送请求中文乱码问题解决
- 准多线程TCP服务器,处理客户端连接请求。
- socket + pcntl_fork 实现客户端请求,服务器实时监听返回处理 消息推送