如何解除阻塞的套接字?

发布于 2024-10-07 05:58:59 字数 796 浏览 0 评论 0原文

概要: 我的程序偶尔会遇到这样的情况:它想通过套接字发送数据,但该套接字被阻塞,等待对从未到来的先前命令的响应。发生这种情况时,有什么方法可以解锁套接字并恢复它吗?如果不是这样,我如何测试套接字是否被阻止,以便我可以关闭它并打开一个新的? (我首先需要阻塞套接字)

详细信息: 我正在通过两个套接字连接到服务器。套接字1用于一般命令通信。套接字 2 用于中止正在运行的命令。中止可能随时发生且频繁发生。通过套接字 1 发送的每个命令都会得到响应,例如:

socket1 send: set command data
socket1 read: set command ack

发送和读取之间总是有一段时间,因为服务器在命令执行完成之前不会发回任何内容。

为了中断正在进行的命令,我通过另一个套接字连接并发出中止命令。然后我使用套接字 1 发出新命令。

我发现中止后偶尔通过套接字 1 发出的命令会挂起程序。看来套接字 1 被阻塞,等待对先前发出的命令的响应,该命令从未返回(并且被中断)。虽然通常它可以工作,但有时却不能(我没有编写服务器)。

在这些情况下,有什么方法可以让我检查套接字 1 是否被阻塞等待读取,如果是,则放弃读取并继续?或者甚至有什么方法可以检查,以便我可以关闭该套接字并重新开始?

谢谢!

更新1:感谢您的回答。至于为什么我使用阻塞套接字,这是因为我正在用这段代码控制 CNC 型机器,并且我需要知道我要求它执行的命令何时执行完毕。服务器在完成后返回 ACK,因此这似乎是处理它的好方法。我喜欢重构非阻塞的想法,但无法想象一种方法来获取有关命令执行时的信息。我将查看 select 和其他选项。

Synopsis:
My program occasionally runs into a condition where it wants to send data over a socket, but that socket is blocked waiting for a response to a previous command that never came. Is there any way to unblock the socket and pick back up with it when this happens? If not that, how could I test whether the socket is blocked so I could close it and open a new one? (I need blocking sockets in the first place)

Details:
I'm connecting to a server over two sockets. Socket 1 is for general command communication. Socket 2 is for aborting running commands. Aborts can come at any time and frequently. Every command sent over socket 1 gets a response, such as:

socket1 send: set command data
socket1 read: set command ack

There is always some time between the send and the read, as the server doesn't send anything back until the command is finished executing.

To interrupt commands in progress, I connect over a another socket and issue an abort command. I then use socket 1 to issue a new command.

I am finding that occasionally commands issued over socket 1 after an abort are hanging the program. It appears that socket 1 is blocked waiting for a response to a previously issued command that never returned (and that got interrupted). While usually it works sometimes it doesn't (I didn't write the server).

In these cases, is there any way for me to check to see if socket 1 is blocked waiting for a read, and if so, abandon that read and move on? Or even any way to check at all so I can close that socket and start again?

thx!

UPDATE 1: thanks for the answers. As for why I'm using blocking sockets, it's because I'm controlling a CNC-type machine with this code, and I need to know when the command I've asked it to execute is done executing. The server returns the ACK when it's done, so that seems like a good way to handle it. I like the idea of refactoring for non-blocking but can't envision a way to get info on when the command is done otherwise. I'll look at select and the other options.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

何时共饮酒 2024-10-14 05:58:59

并不是要显得不愉快,而是您说您需要阻塞套接字,然后继续描述需要非阻塞套接字的一些很好的理由。我建议重构以使用非阻塞。

除此之外,我知道了解套接字是否被阻止的唯一方法是您的程序调用了 recv 或其变体之一并且尚未返回。其他人可能知道我不知道的 API,但在 recv 调用之前设置“阻止”布尔值并在之后清除它可能是获取该信息的最佳技巧。但你不想这样做。相信我,从长远来看,重构是值得的。

Not meaning to seem disagreeable, but you say you need blocking sockets and then go on to describe some very good reasons for needing non-blocking sockets. I would recommend refactoring to use non-blocking.

Aside from that, the only method I'm aware of to know if a socket is blocked is the fact that your program called recv or one of its variants and has not yet returned. Someone else may know an API that I don't, but setting a "blocked" boolean before the recv call and clearing it afterward is probably the best hack to get you that info. But you don't want to do that. Trust me, the refactor will be worth it in the long run.

冰火雁神 2024-10-14 05:58:59

这个问题的传统解决方案是使用 select。在写入之前,测试套接字是否支持写入,如果不支持,则执行其他操作(例如先等待响应)。在 select 之上一级,Python 提供了 asyncore 模块来启用此类处理。在上面两层,Twisted 是一个处理消息异步处理的完整框架。

The traditional solution to this problem is to use select. Before writing, test whether the socket will support writing, and if not, do something else (such as waiting for a response first). One level above select, Python provides the asyncore module to enable such processing. Two level above, Twisted is an entire framework dealing with asynchronous processing of messages.

怪异←思 2024-10-14 05:58:59

套接字应该是全双工的。如果Python阻止一个线程写入套接字,而另一个线程正在从同一个套接字读取数据,我会认为这是Python中的一个主要错误。在我使用过的任何其他编程语言中都不会发生这种情况。

Sockets should be full duplex. If Python blocks a thread from writing to a socket while another thread is reading from the same socket I would regard it as a major bug in Python. This doesn't occur in any other programming language I've used.

等风来 2024-10-14 05:58:59

你真正要做的是阻止 select() 或 poll() 。解除阻塞套接字的唯一方法是接收可能不可接受的数据或信号。 select() 或 poll() 调用可以在读取或写入(等待缓冲区空间)时阻塞等待一个或多个套接字。如果您想定期等待检查其他事情,它们也可以超时。看看我对 Block Socket with Unix and C/ 的回答C++ 帮助

What you really what is to block on a select() or poll(). The only way to unblock a blocked socket is to receive data or a signal which is probably not acceptable. A select() or poll() call can block waiting for one or more sockets, either on reading or writing (waiting for buffer space). They can also take a timeout if you want to wait periodically to check on other things. Take a look at my answer to Block Socket with Unix and C/C++ Help

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文