Python:将数据从扭曲的套接字读取到SWIG-ed结构中

时间:2014-08-08 19:08:42

标签: python c sockets twisted swig

我正在编写一个Python客户端来连接用C编写的服务器,该服务器以二进制结构发送状态。我用SWIG封装了C结构,但是我需要处理从套接字返回的数据作为C结构。特别是,我想将传递给dataReceived()的数据转换为iwrf_ui_task_operations结构。

我是否需要编写(和SWIG)传递'data'的辅助函数,并返回iwrf_ui_task_operations结构?

这是一个简单的测试程序:

from twisted.internet import reactor, protocol
import syscon_interface


class SysconClient(protocol.Protocol):
    """Once connected, receive messages from syscon."""

    def connectionMade(self):
        print "connectionMade"

    def dataReceived(self, data):
        "As soon as any data is received, write it out."
        # this constructor does not accept 'data' as an argument  :-(
        to = syscon_interface.iwrf_ui_task_operations_t()  
        print "Server said:", data

    def connectionLost(self, reason):
        print "connection lost"

class SysconClientFactory(protocol.ClientFactory):
    protocol = SysconClient

    def clientConnectionFailed(self, connector, reason):
        print "Connection failed - goodbye!"
        reactor.stop()

    def clientConnectionLost(self, connector, reason):
        print "Connection lost - goodbye!"
        reactor.stop()


# this connects the protocol to a server running on port 2515
def main():
    f = SysconClientFactory()
    reactor.connectTCP("localhost", 2515, f)
    reactor.run()

# this only runs if the module was *not* imported
if __name__ == '__main__':
    main()       

1 个答案:

答案 0 :(得分:4)

你不想这样做。传递给dataReceived的数据是TCP段,而不是协议消息。因此,您可能会收到一些结构,或全部结构,或多个结构,或从中间开始的数据。

请参阅this Twisted FAQ

你根本不想这样做。不同的C编译器可以完全有效地为这个结构生成不同的布局,并且您的平台的字节序将会涉及,而且通常只是一个糟糕的场景。

如果您打算这样做(并且基于您的问题的框架,我认为您必须这样做),首先您需要确保您的确切工具链版本(C编译器版本,SWIG版本,Python版本) ,Python构建选项等等都是完全同步的。然后你需要编写一个框架协议,like those in twisted.protocols.basic,它处理基于sizeof(iwrf_ui_task_operations_t)的固定宽度记录,然后一旦你拆分它,一个包装函数需要{{1}和char* data并构造你的结构将是合乎逻辑的下一步。

最后,不要使用SWIG,请使用CFFI。编写绑定更加容易,对其他运行时更容易移植(例如,PyPy实际上可以将您的调用JIT调到C中),并且实质上更安全(更少的段错误机会)。