如何在 ZMQ 套接字中启动/退出时清除缓冲区?(防止服务器与死客户端连接) [英] How do I clear the buffer upon start/exit in ZMQ socket? (to prevent server from connecting with dead clients)

查看:64
本文介绍了如何在 ZMQ 套接字中启动/退出时清除缓冲区?(防止服务器与死客户端连接)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 python 中使用 REQ/REP 类型的套接字进行 ZMQ 通信.有多个客户端尝试连接到一台服务器.已在客户端脚本中添加超时以防止无限期等待.

I am using a REQ/REP type socket for ZMQ communication in python. There are multiple clients that attempt to connect to one server. Timeouts have been added in the client script to prevent indefinite wait.

问题是,当服务器没有运行,并且客户端尝试建立连接时,它的消息被添加到队列缓冲区中,理想情况下此时甚至不应该存在.当脚本开始运行并且新客户端连接时,服务器首先接收前一个客户端的数据.这不应该发生.

The problem is that when the server is not running, and a client attempts to establish connection, it's message gets added to the queue buffer, which should not even exist at this moment ideally. When the script starts running and a new client connects, the previous client's data is taken in first by the server. This should not happen.

当服务器启动时,它假设有一个客户端连接到它,因为它之前尝试过连接,并且无法干净地退出(因为服务器关闭).

When the server starts, it assumes a client is connected to it since it had tried to connect previously, and could not exit cleanly (since the server was down).

在下面的代码中,当客户端第一次尝试时,它得到 ERR 03: Server down 这是正确的,然后是 Error disconnecting.当服务器启动时,我收到第一个连接的客户端的 ERR 02: Server Busy.这不应该发生.既然服务器已经启动并正在运行,客户端应该能够与服务器无缝连接.

In the code below, when the client tries the first time, it gets ERR 03: Server down which is correct, followed by Error disconnecting. When server is up, I get ERR 02: Server Busy for the first client which connects. This should not occur. The client should be able to seamlessly connect with the server now that it's up and running.

服务器代码:

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.

PS - I have a feeling the solution may lie in the correct usage of socket.bind and socket.connect.

推荐答案

回答我自己的问题-

问题是第一个客户端发送一条消息,服务器在开始运行时接受该消息,而不管客户端的状态如何.

The problem is that the first client sends a message which the server accepts when it starts running, regardless of the status of the client.

为了防止这种情况,必须做两件事.最重要的是使用 socket.close() 关闭客户端连接.其次,LINGER 参数可以设置为低值或零.这会在套接字关闭时的超时值之后清除缓冲区.

To prevent this, 2 things have to be done. The most important thing is to use socket.close() to close the client connection. Secondly, the LINGER parameter can be set to a low value or zero. This clears the buffer after the timeout value from the time the socket is closed.

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

这篇关于如何在 ZMQ 套接字中启动/退出时清除缓冲区?(防止服务器与死客户端连接)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆