¿Cómo borro el búfer al iniciar / salir en el zócalo ZMQ? (para evitar que el servidor se conecte con clientes muertos)

Estoy usando un socket de tipo REQ / REP para la comunicación ZMQ en python. Hay varios clientes que intentan conectarse a un servidor. Se han agregado tiempos de espera en el script del cliente para evitar una espera indefinida.

El problema es que cuando el servidor no se está ejecutando, y un cliente intenta establecer la conexión, su mensaje se agrega al búfer de cola, que idealmente no debería existir en este momento. Cuando el script comienza a ejecutarse y se conecta un nuevo cliente, el servidor toma primero los datos del cliente anterior. Esto no debería suceder.

Cuando se inicia el servidor, asume que el cliente está conectado a él ya que había intentado conectarse anteriormente y no pudo salir de forma limpia (ya que el servidor estaba inactivo).

En el código que aparece a continuación, cuando el cliente lo intenta por primera vez, obtiene ERR 03: Server down que es correcto, seguido de un Error disconnecting . Cuando el servidor está activo, obtengo ERR 02: Server Busy para el primer cliente que se conecta. Esto no debería ocurrir. El cliente debe poder conectarse sin problemas con el servidor ahora que está en funcionamiento.

Código del servidor:

 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() 

Codigo del cliente:

 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() 

PD: Tengo la sensación de que la solución puede estar en el uso correcto de socket.bind y socket.connect.

Respondiendo a mi propia pregunta-

El problema es que el primer cliente envía un mensaje que el servidor acepta cuando comienza a ejecutarse, independientemente del estado del cliente.

Para evitar esto, hay que hacer 2 cosas. Lo más importante es usar socket.close () para cerrar la conexión del cliente. En segundo lugar, el parámetro LINGER se puede establecer en un valor bajo o cero. Esto borra el búfer después del valor de tiempo de espera desde el momento en que se cierra el socket.

 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()