是否可以通过共享公共套接字或使用独立套接字的多个线程与单个端口上的TCP套接字服务器进行通信,而无需使用锁定机制或其他跨线程通信技术?
我的具体问题:
我是python套接字编程的初学者,并尝试编写一个库来与网络家庭自动化设备(GlobalCache GC100)进行交互
我需要通过TCP不断收听来自此硬件的传感器状态变化事件,并且能够在用户启动的时间发送set_state命令(跳闸继电器),而不会有明显的延迟。
我有一个while True:
循环执行socket.recv()
来拾取状态更改事件。大多数情况下,这会超时(socket.settimeout(10)
)并继续下一个循环迭代,直到设备推送状态更改数据。
现在最重要的是我需要用户能够发送set_state命令,我不希望用户需要等到socket.recv()超时并在recv()循环之间注入通信迭代。所以我选择将tcp监听循环拆分为一个单独的线程,使用它自己的套接字(但指向相同的主机和端口)。
问题是set_state线程中的套接字似乎杀死了侦听线程中的套接字,反之亦然。似乎只有最近创建/连接的套接字才真正起作用。
我是否尝试使用套接字编程做一些不可能的事情,或者这可能只是我设备(GC-100)上套接字服务器实现的限制?
到目前为止我能看到的唯一解决方案是将所有套接字通信保持在一个线程中,使用公共套接字,实现通信队列,并将tcp-listening部分的超时持续时间保持在一个非常小的值,这样set_state命令必须在队列中等待最少的时间。但这似乎不太理想,有点脆弱。
修改
它是套接字对(由客户端IP组成的4元组 地址,客户端端口号,服务器IP地址和服务器端口 number)指定唯一标识每个端点的两个端点 互联网中的TCP连接。 (TCP-IP Illustrated Volume 1,W。 理查德史蒂文斯)
我想也许我需要在不同线程中的多个套接字使用的源端口强制区别。我尝试了socket.bind(hostname, source_port)
但是仍然遇到地址已经被使用的错误,因为主机名和源端口的所有组合似乎都是合理的。
答案 0 :(得分:0)
虽然他们的API文档中没有提到,但我认为这是GC-100服务器实现的限制。有很多关于如何实现tcp服务器的例子,它可以支持来自多个主机的多个同时连接。然而,我配置了两个不同的主机来连接到设备,设备一次只允许连接到一个主机。
因此,似乎对我来说唯一的解决方案是使用单个套接字,并多路复用所有读写。
http://wiki.linuxmce.org/index.php/GlobalCache_GC-100#Implementation_details
gc100软件架构使用两个线程进行通信 gc100关于继电器,红外发射器和传感器,一个用于 发送消息(SocketThread)和一个用于接收(EventThread)。 原因是gc100协议不完全是a 请求 - 回复协议,即使它最初看起来像那样。 gc100 当传感器跳闸时,可以启动传输,足以断开 请求 - 回复范例。该计划旨在治疗 通信是异步的。消息将被发送到设备 期待回复,回复被视为独立事件 和状态更改报告,而不将请求链接到 程序逻辑(初始化阶段除外)。