Python 如何在ZMQ套接字中启动/退出时清除缓冲区?(防止服务器连接到死机客户端)
我在python中使用REQ/REP类型套接字进行ZMQ通信。有多个客户端试图连接到一台服务器。客户端脚本中添加了超时,以防止无限等待 问题在于,当服务器未运行时,客户机尝试建立连接时,它的消息会添加到队列缓冲区中,理想情况下,此时甚至不应该存在队列缓冲区。当脚本开始运行并连接新客户端时,服务器首先接收上一个客户端的数据。这不应该发生 当服务器启动时,它假定客户端已连接到它,因为它以前曾尝试连接,但无法完全退出(因为服务器已关闭) 在下面的代码中,当客户端第一次尝试时,它会得到正确的Python 如何在ZMQ套接字中启动/退出时清除缓冲区?(防止服务器连接到死机客户端),python,sockets,zeromq,pyzmq,Python,Sockets,Zeromq,Pyzmq,我在python中使用REQ/REP类型套接字进行ZMQ通信。有多个客户端试图连接到一台服务器。客户端脚本中添加了超时,以防止无限等待 问题在于,当服务器未运行时,客户机尝试建立连接时,它的消息会添加到队列缓冲区中,理想情况下,此时甚至不应该存在队列缓冲区。当脚本开始运行并连接新客户端时,服务器首先接收上一个客户端的数据。这不应该发生 当服务器启动时,它假定客户端已连接到它,因为它以前曾尝试连接,但无法完全退出(因为服务器已关闭) 在下面的代码中,当客户端第一次尝试时,它会得到正确的ERR 03
ERR 03:Server down
,然后是Error disconnecting
。当服务器启动时,对于第一个连接的客户端,我得到ERR 02:server Busy
。这不应该发生。客户机应该能够无缝连接服务器,现在它已经启动并运行
服务器代码:
import zmq
def server_fn():
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://192.168.1.14:5555")
one=1
while one == 1:
message = socket.recv()
#start process if valid new connection
if message == 'hello':
socket.send(message) #ACK
#keep session alive until application ends it.
while one == 1:
message = socket.recv()
print("Received request: ", message)
#exit connection
if message == 'bye':
socket.send(message)
break
#don't allow any client to connect if already busy
if message == 'hello':
socket.send ('ERR 00')
continue
#do all data communication here
else:
socket.send('ERR 01: Connection Error')
return
server_fn()
客户端代码:
import zmq
class client:
def clientInit(self):
hello='hello'
#zmq connection
self.context = zmq.Context()
print("Connecting to hello world server...")
self.socket = self.context.socket(zmq.REQ)
self.socket.connect("tcp://192.168.1.14:5555")
#RCVTIMEO to prevent forever block
self.socket.setsockopt(zmq.RCVTIMEO, 5000)
#SNDTIME0 is needed since script may not up up yet
self.socket.setsockopt(zmq.SNDTIMEO, 5000)
try:
self.socket.send(hello)
except:
print "Sending hello failed."
try:
echo = self.socket.recv()
if hello == echo:
#connection established.
commStatus = 'SUCCESS'
elif echo == 'ERR 00':
#connection busy
commStatus = "ERR 00. Server busy."
else:
#connection failed
commStatus="ERR 02"
except:
commStatus = "ERR 03. Server down."
return commStatus
def clientQuit(self):
try:
self.socket.send('bye')
self.socket.recv()
except:
print "Error disconnecting."
cObj = client()
commStatus=cObj.clientInit()
print commStatus
cObj.clientQuit()
PS-我觉得解决方法可能在于正确使用socket.bind和socket.connect。回答我自己的问题- 问题是第一个客户机发送一条消息,服务器在开始运行时接受该消息,而不管客户机的状态如何 为了防止这种情况,必须做两件事。最重要的是使用socket.close()关闭客户端连接。其次,可以将LINGER参数设置为低值或零。这将在套接字关闭时的超时值之后清除缓冲区
class client:
def clientInit(self):
...
self.socket.setsockopt(zmq.LINGER, 100)
...
def clientQuit(self):
try:
self.socket.send('bye')
self.socket.recv()
except:
print "Error disconnecting."
self.socket.close()