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

Posted

技术标签:

【中文标题】Python:将数据从扭曲的套接字读取到 SWIG 结构中【英文标题】:Python: reading data from a twisted socket into a SWIG-ed structure 【发布时间】:2014-08-08 19:08:41 【问题描述】:

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

我是否需要编写(和 SWIG)一个传递“数据”并返回 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】:

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

见this Twisted FAQ。

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

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

最后,不要使用 SWIG,使用 CFFI。编写绑定更容易,更容易移植到其他运行时(例如,PyPy 实际上可以将您的调用 JIT 到 C 中),并且更安全(发生段错误的可能性要小得多)。

【讨论】:

以上是关于Python:将数据从扭曲的套接字读取到 SWIG 结构中的主要内容,如果未能解决你的问题,请参考以下文章

检测 TCP 何时拥塞 python 扭曲套接字服务器

SWIG:如何将复数向量从 C++ 传递到 python

Python 将 http post body 扭曲转发到 tcp 端口

通过 SWIG 将 Python 3 个字节输入到 C char*

检测到 Sqoop 套接字超时:从大型机读取数据并插入 Hive 时读取超时

从 Python 中的 WebSocket 读取(来自 Javascript WebSocket 的数据)