Chinaunix首页 | 论坛 | 博客
  • 博客访问: 43885
  • 博文数量: 2
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 285
  • 用 户 组: 普通用户
  • 注册时间: 2006-02-09 21:38
文章分类
文章存档

2008年(2)

我的朋友
最近访客

分类: Python/Ruby

2008-04-17 00:32:43

              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'

阅读(745) | 评论(0) | 转发(0) |
0

上一篇:Boost python在VC下的使用

下一篇:没有了

给主人留下些什么吧!~~