梗概: 我的程序偶尔遇到想要通过套接字发送数据的情况,但该套接字被阻塞,等待对前一个从未发出的命令的响应。当发生这种情况时,有没有办法解锁套接字并重新启用它?如果不是这样,我怎么能测试插座是否被阻塞所以我可以关闭它并打开一个新的? (我首先需要阻塞套接字)
详细说明: 我通过两个插座连接到服务器。套接字1用于一般命令通信。套接字2用于中止运行命令。可以随时和频繁地进行中止。通过套接字1发送的每个命令都会收到响应,例如:
socket1 send: set command data
socket1 read: set command ack
发送和读取之间总有一段时间,因为在命令执行完毕之前服务器不会发回任何内容。
要中断正在进行的命令,我通过另一个套接字连接并发出中止命令。然后我使用套接字1发出一个新命令。
我发现在中止挂起程序后偶尔会在套接字1上发出命令。似乎套接字1被阻塞,等待对先前发出的从未返回的命令的响应(并且被中断)。虽然通常有时它不起作用(我没有写服务器)。
在这些情况下,有没有办法让我检查套接字1是否被阻塞等待读取,如果是,放弃读取并继续?或者甚至任何方式检查,以便我可以关闭该套接字并重新开始?
THX!
更新1:谢谢你的回答。至于为什么我使用阻塞套接字,这是因为我用这个代码控制一台CNC型机器,我需要知道我要求它执行的命令何时执行完毕。服务器在完成后返回ACK,因此这似乎是处理它的好方法。我喜欢重构非阻塞的想法,但无法设想在命令何时完成时获取信息的方法。我会看看选择和其他选项。
答案 0 :(得分:4)
并不意味着看起来不愉快,但是你说你需要阻塞套接字然后继续描述一些非常好的理由需要非阻塞套接字。我建议重构使用非阻塞。
除此之外,我知道如果套接字被阻止的唯一方法是您的程序调用{{1}}或其中一个变体并且尚未返回。其他人可能知道我没有的API,但在recv
调用之前设置“阻止”布尔值并在之后清除它可能是获取该信息的最佳黑客。但你不想这样做。相信我,从长远来看,重构将是值得的。
答案 1 :(得分:2)
此问题的传统解决方案是使用select。在编写之前,测试套接字是否支持写入,如果不支持,则执行其他操作(例如先等待响应)。在select一级以上,Python提供asyncore模块来启用此类处理。上面两级,Twisted是处理消息异步处理的整个框架。
答案 2 :(得分:0)
套接字应为全双工。如果Python阻止线程写入套接字,而另一个线程从同一个套接字读取,我会认为它是Python中的一个主要错误。在我使用的任何其他编程语言中都不会出现这种情况。
答案 3 :(得分:0)
你真正想要阻止select()或poll()。解除阻塞套接字的唯一方法是接收可能无法接受的数据或信号。 select()或poll()调用可以阻止等待一个或多个套接字,无论是读取还是写入(等待缓冲区空间)。如果您想要定期等待检查其他事情,他们也可以暂停。看看我对Block Socket with Unix and C/C++ Help
的回答