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'