2017-10-15 68 views
0

是否可以通过多个线程与单个端口上的TCP套接字服务器进行通信,共享一个公用套接字或使用独立套接字,而无需锁定机制或其他跨线程通信技术?多线程套接字客户端冲突

我的具体问题:

我在python socket编程初学者,试图写一个联网的家庭自动化设备(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 地址,客户端端口号,服务器IP地址的四元组,和服务器端口 号码),指定所述两个唯一标识互联网中每个 TCP连接的端点。 (TCP-IP详解卷1,W 理查德·史蒂文斯)

我想也许我需要强制通过在不同的线程的多个插座使用的源端口的差异。我尝试了socket.bind(hostname, source_port),但不断收到地址已被使用的错误,对于主机名为&的所有组合似乎都是合理的。

+0

单个TCP套接字完全能够同时发送/接收数据。 – bnaecker

+0

@bnaecker我意识到我的描述并不是特别擅长说明具体问题,所以我编辑了它。我的问题与通过一个或多个套接字同时在不同线程上与一个主机和端口进行通信有关。 – davegravy

+0

用户如何将命令发送到设备?如果它通过文本/命令行界面之类的东西,则可以使用IO多路复用来处理单个套接字上的所有内容。查看'select'或'selectors'模块,您可以无限期地等待,直到用户输入命令或设备发送状态更新。 – bnaecker

回答

0

虽然没有在他们的API文档中提到,但我相信这是GC-100服务器实现的限制。有很多关于如何实现可以支持来自多个主机的同时连接的tcp服务器的例子。然而,我配置了两台不同的主机连接到设备,而设备一次只允许连接一台主机。

因此,对我来说似乎唯一的解决方案是使用一个单一的套接字,并复用所有的阅读和写作。

http://wiki.linuxmce.org/index.php/GlobalCache_GC-100#Implementation_details

的GC100软件体系结构使用两个线程,用于接收(EventThread)与 关于继电器,IR发射器和传感器的GC100,一个用于 发送消息(SocketThread)和一个进行通信。 原因是gc100协议并不完全是 请求 - 回复协议,即使它看起来像这样。 gc100 可以在传感器跳闸时启动传输,足以中断请求 - 回复范例。该程序旨在将 通信视为异步。消息被发送到设备而没有 期待回复,并且回复将被视为独立事件 和状态更改报告,而不会将请求链接到 程序逻辑中的回复(初始化阶段除外)。