[笨木头FireFly 02]入门篇2_客户端发送请求,服务器处理请求
原地址: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函數,大家可以看看這篇文章:
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。這看起來有點多此一舉,據我目前的研究,還沒法知道原因,希望高手支招。
轉載于:https://www.cnblogs.com/123ing/p/3905096.html
總結
以上是生活随笔為你收集整理的[笨木头FireFly 02]入门篇2_客户端发送请求,服务器处理请求的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 返回一个首尾相接的二维整数数组中最大子数
- 下一篇: [注]什么是用户?估计90%人不知道