您的位置:首页 > 编程语言 > Python开发

用python写1个简单的聊天服务器4-协议设计与处理

2013-06-28 17:50 477 查看
因为tcp是数据流。所以1段数据可能会被分开发送或者接收,这样在服务器接受以后就存在1个问题。如何确认获取到的协议完整性?

这就需要服务器粘包处理。

C++游戏服务器协议部分一般都是采用 包长+协议号+数据

通过读取2或者4个字节包长,根据包长从数据流中提取固定长度的内容,然后判断协议号,对应到struct以后提取数据。

想一下最终决定采用json格式。

协议

提交部分

{
"lentgh":12,
"action":"register",

"username":"watsy",
"password":"123456"
}


其中length为整个json的长度

action为方法。

剩下的为提交的字段

返回

{
"status":1,
"errcode":0,
"action":"login",
"datas":{
"uid":1,
"name":"watsy",
"head":"xxxx.jpg",
"description":"hello world",
"token":"abcdefghikklmnopqrstuvwxyz"
}
}


服务器端发送与返回一致。

status - 状态 1成功,0异常

action - 方法

errcode - 错误号码

datas - 返回的内容,可以为空

server.py服务器接收到以后

投递到tcpstreampackage.py处理

搜索"length : " 得到长度,以后提取协议。然后对应action,以后反射得到协议对象。

部分代码

class TCPStreamPackage(object):

def __init__(self , callback):
super(TCPStreamPackage , self).__init__()

self.datas = ''
self._package_decode_callback = callback

def add(self, data):
#组包
if len(self.datas) == 0:
self.datas = data
else:
self.datas = "%s%s" % (self.datas , data)

#拆包
length = -1
length_index = self.datas.find('length\" :')
if length_index != -1:
length_end = self.datas.find(',' , length_index + 9 , length_index + 9 + 10)
if length_end == -1:
length_end = self.datas.find('}', length_index + 9 , length_index + 9 + 10)

if length_end != -1:
length = self.datas[length_index + 9 :length_end]

if length != -1:
length = int(length.strip())

if length != -1 and length <= len(self.datas):
package = self.datas[0:length]
package = FriendProtocol.checkPackage(package)

if self._package_decode_callback:
self._package_decode_callback(package)

if len(self.datas) == length:
self.datas = ''
else:
self.datas = self.datas[length]


解析协议

@staticmethod
def checkPackage(package):

json_msg = json.loads(package)

protocol = {
'login' :                       PackageLogin ,
'getfriendlistbytrainandtime' : PackageGetNotFriendsByCodeAndDate,
'addfriend' :                   PackageAddFriendRequest,
'addfriendstatus' :             PackageAddFriendStatus,
'getfriends'    :               PackageGetFriends,
'delfriend' :                   PackageDeleteFriend,
'getfrienddetail' :             PackageGetFriendDetail,
'sendchatmsg' :                 PackageSendChatMessage,
'register' :                    PackageRegister,
}

if json_msg.has_key("datas") :
datas = json_msg['datas']

if datas.has_key('type') :
stype = datas['type']

#存在协议内
if stype in protocol.keys():
#解析协议
pack = protocol[stype]()
pack.parser(datas)
return pack

return None
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: