Sam*_*erg 14 python sockets multithreading recv
我有一个等待连接的主线程.它产生的客户端线程将回应客户端的响应(在本例中为telnet).但是说我想在一段时间后关闭所有套接字和所有线程,比如在1次连接之后.
我该怎么办?如果我clientSocket.close()从主线程做,它将不会停止做recv.它只会在我第一次通过telnet发送内容时停止,然后它将无法进行进一步的发送和recvs.
我的代码看起来像这样:
# 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()
Run Code Online (Sandbox Code Playgroud)
ceb*_*bru 17
我知道这是一个老话题,塞缪尔可能很久以前就解决了他的问题.但是,我有同样的问题,并在google'ing时遇到了这篇文章.找到了解决方案并认为值得添加.
您可以在套接字类上使用shutdown方法.它可以防止进一步发送,接收或两者.
socket.shutdown(socket.SHUT_WR)
以上是为了防止将来的发送,作为一个例子.
我不知道是否可以做你所要求的,但它不应该是必要的.如果没有什么可读的,请不要从套接字读取; 用于select.select检查套接字的数据.
更改:
data = self.clientSocket.recv(1024)
print "Got data: ", data
self.clientSocket.send(data)
Run Code Online (Sandbox Code Playgroud)
更像这样的事情:
r, _, _ = select.select([self.clientSocket], [], [])
if r:
data = self.clientSocket.recv(1024)
print "Got data: ", data
self.clientSocket.send(data)
Run Code Online (Sandbox Code Playgroud)
编辑:如果你想防止插座已经关闭的可能性,赶上socket.error.
do_read = False
try:
r, _, _ = select.select([self.clientSocket], [], [])
do_read = bool(r)
except socket.error:
pass
if do_read:
data = self.clientSocket.recv(1024)
print "Got data: ", data
self.clientSocket.send(data)
Run Code Online (Sandbox Code Playgroud)