如何从Python中的另一个线程中止socket.recv()
我有一个等待连接的主线程。它生成客户端线程,该线程将回显来自客户端的响应(在本例中为 telnet)。但是假设我想在一段时间后关闭所有套接字和所有线程,例如在 1 个连接之后。
我该怎么做呢?如果我从主线程执行 clientSocket.close()
,它不会停止执行 recv
。仅当我首先通过 telnet 发送某些内容时它才会停止,然后它将无法执行进一步的发送和接收。
我的代码如下所示:
# Echo server program
import socket
from threading import Thread
import time
class ClientThread(Thread):
def __init__(self, clientSocket):
Thread.__init__(self)
self.clientSocket = clientSocket
def run(self):
while 1:
try:
# It will hang here, even if I do close on the socket
data = self.clientSocket.recv(1024)
print "Got data: ", data
self.clientSocket.send(data)
except:
break
self.clientSocket.close()
HOST = ''
PORT = 6000
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serverSocket.bind((HOST, PORT))
serverSocket.listen(1)
clientSocket, addr = serverSocket.accept()
print 'Got a new connection from: ', addr
clientThread = ClientThread(clientSocket)
clientThread.start()
time.sleep(1)
# This won't make the recv in the clientThread to stop immediately,
# nor will it generate an exception
clientSocket.close()
I have a main thread that waits for connection. It spawns client threads that will echo the response from the client (telnet in this case). But say that I want to close down all sockets and all threads after some time, like after 1 connection.
How would I do it? If I do clientSocket.close()
from the main thread, it won't stop doing the recv
. It will only stop if I first send something through telnet, then it will fail doing further sends and recvs.
My code looks like this:
# Echo server program
import socket
from threading import Thread
import time
class ClientThread(Thread):
def __init__(self, clientSocket):
Thread.__init__(self)
self.clientSocket = clientSocket
def run(self):
while 1:
try:
# It will hang here, even if I do close on the socket
data = self.clientSocket.recv(1024)
print "Got data: ", data
self.clientSocket.send(data)
except:
break
self.clientSocket.close()
HOST = ''
PORT = 6000
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serverSocket.bind((HOST, PORT))
serverSocket.listen(1)
clientSocket, addr = serverSocket.accept()
print 'Got a new connection from: ', addr
clientThread = ClientThread(clientSocket)
clientThread.start()
time.sleep(1)
# This won't make the recv in the clientThread to stop immediately,
# nor will it generate an exception
clientSocket.close()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我知道这是一个旧线程,塞缪尔可能很久以前就解决了他的问题。然而,我遇到了同样的问题,并在谷歌搜索时发现了这篇文章。找到解决方案并认为值得添加。
您可以在套接字类上使用 shutdown 方法。它可以阻止进一步的发送、接收或两者。
例如,
上面的内容会阻止将来的发送。 有关更多信息,请参阅 Python 文档。
I know this is an old thread and that Samuel probably fixed his issue a long time ago. However, I had the same problem and came across this post while google'ing. Found a solution and think it is worthwhile to add.
You can use the shutdown method on the socket class. It can prevent further sends, receives or both.
The above prevents future sends, as an example.
See Python docs for more info.
我不知道是否可以按照您的要求进行操作,但应该没有必要。如果没有什么可读的,就不要从套接字读取;使用
select.select
检查套接字中的数据。更改:
更像这样:
编辑:如果您想防止套接字已关闭的可能性,请捕获
socket.error
。I don't know if it's possible to do what you're asking, but it shouldn't be necessary. Just don't read from the socket if there is nothing to read; use
select.select
to check the socket for data.change:
to something more like this:
EDIT: If you want to guard against the possibility that the socket has been closed, catch
socket.error
.我找到了使用超时的解决方案。这将中断接收(实际上在超时到期之前,这很好):
I found a solution using timeouts. That will interrupt the recv (actually before the timeout has expired which is nice):
我必须为下面的评论道歉。 @Matt Anderson 的早期评论有效。我在尝试时犯了一个错误,这导致了我在下面的帖子。
I must apologize for the comments below. The earlier comment by @Matt Anderson works. I had made a mistake when trying it out which led to my post below.