twisted netclient
twisted netclient
学习twisted,尝试使用task和struct,接收类似下列消息
struct MSG_HEAD{
word msgLen;
word msgType;
byte source;
byte receive;
};
struct MSG_111:MSG_HEAD{
};
不知是否有更合适的方法,初次用python编写16进制数据收发,总觉的不确定。
from twisted.internet.protocol import ClientFactory
from twisted.protocols.basic import LineReceiver
from twisted.internet import reactor, task
import sys
import os
import struct
from netMsg import *
headLen = struct.calcsize(Inn_HEAD)
def genfunc( data, msgType ):
funcText = "self.body = struct.unpack(MSG_%i, data[:struct.calcsize(MSG_%i)])"
return funcText%( msgType, msgType )
class CM_Client(LineReceiver):
def __init__(self):
self.buf = ''
self.complete = True
def request(self):
self.transport.write(struct.pack(MSG_111, 6, 111, 1, 0))
def connectionMade(self):
self.setRawMode()
self.request_task = task.LoopingCall(self.request)
self.request_task.start(3.0) # call every 3 second
def rawDataReceived(self, data):
self.buf += data
self.netDataProc(self.buf)
def netDataProc(self, data):
print map(ord,self.buf)
if self.complete:
self.recvMsgHead(self.buf)
self.recvMsgBody(self.buf)
def recvMsgHead(self, data):
if len(self.buf) >= headLen:
self.head = struct.unpack(Inn_HEAD,self.buf[0:headLen])
else:
self.head = None
def recvMsgBody(self, data):
if self.head == None: return
self.complete = False
msgLen, msgType =self.head[0:2]
print 'msgLen =%d | headLen = %d'%(msgLen, headLen)
if len(self.buf) >= msgLen:
try:
exec( genfunc( self.buf, msgType ) )
self.buf = self.buf[msgLen:]
self.complete = True
self.dealMsg(self.body)
self.netDataProc(self.buf)
except NameError:
print "类型%d没有定义无法读出"% msgType
def dealMsg(self,msg):
print 'Msg:', msg
if(msg[1] == 112): self.request_task.stop()
if(msg[1] == 101): pass
if(msg[1] == 102): pass
if(msg[1] == 121): pass
class CM_ClientFactory(ClientFactory):
protocol = CM_Client
def clientConnectionFailed(self, connector, reason):
print 'connection failed:', reason.getErrorMessage()
reactor.stop()
def clientConnectionLost(self, connector, reason):
print 'connection lost:', reason.getErrorMessage()
reactor.stop()
def main():
reactor.connectTCP('localhost', 10050, CM_ClientFactory())
reactor.run()
if __name__ == '__main__':
main()
另外对于具有位域成员的消息结构,比如
struct XX_FLAG{
BYTE a:2;
BYTE b:6;
};
除了ctypes是否还有别的选择?
我尝试使用这种方式,不知能否使其赋值取值更加自动化
class CMD(Structure):
_fields_ = [('cmdType', c_ubyte, 3),
('reserve', c_ubyte, 5)]
class uCMD(Union):
_fields_ = [('uvalue', CMD),
('value', c_ubyte)]
def strPack(self):
return '1B'