簡體   English   中英

服務器的非阻塞套接字

[英]Non-blocking socket for server

我在stackoverflow.com上檢查了幾個類似的線程,我認為可能需要為我的服務器腳本打開非阻塞套接字。 既然如此,我不確定這是否是解決問題的標題可能是錯誤的。 讓我解釋一下我的問題是什么。

服務器應用程序等待連接,一旦客戶端連接,它將詢問服務器ID,此后客戶端將詢問服務器配置,然后客戶端將向服務器發送命令以開始測量傳輸。 這是我的代碼的簡化版本:

def conn_handler(self, connection, address):
    self.logger.info("[%d] - Connection from %s:%d", 10, address[0], address[1])

    sending_measurements_enabled = False
    try:
        while True:
            data = connection.recv(2048)

            if data:
                command = get_command_from_data(data)
            else:
                command = None

            if command == 'start':
                sending_measurements_enabled = True
            elif command == 'stop':
                break
            elif command == 'id':
                connection.sendall(self.id)
            elif command == 'cfg':
                connection.sendall(self.cfg)

            if sending_measurements_enabled:
                connection.sendall(measurement)

    except Exception as e:
       print(e)
    finally:
        connection.close()
        print("Connection closed")

這是客戶端腳本:

try:

    sock.sendall(get_id_command)    

    data = sock.recv(2048) # Do I need to wait for response?
    print(data)

    sock.sendall(get_conf_command)

    data = sock.recv(2048)
    print(data)

    sock.sendall(start_sending_measurements)
    data = sock.recv(2048)
    print(data)

    while True:
        sock.sendall(bytes('I do not want this', 'utf-8')) # I would like to keep receiving measurements without this
        data = sock.recv(2048)
        print(data)

finally:
    print('Closing socket...')
    sock.close()

這是我的問題:

當我運行客戶端並發送命令以獲取ID服務器時,服務器將返回ID消息,然后客戶端將發送命令以獲取配置,服務器將返回配置消息,但是當我發送start命令時,服務器將僅發送一個測量值,然后我猜為connection.recv(2048)將阻止執行,直到服務器收到另一個命令為止。 因此,我在客戶端腳本中的while True:循環中添加了該行,它將繼續發送(不必要的,無效的)命令,而服務器將繼續發送測量值。

如何解決此問題,而無需始終從客戶端發送命令。 我希望能夠只發送一個命令start和服務器將繼續發送測量,停止僅當客戶端發送stop命令。 另外,如果服務器在發送測量值時接收到idcfg命令,它將首先發送idcfg然后繼續發送測量值。

在服務器循環中調用select.select([connection], [connection], [connection])select模塊提供了更多功能,因此請選擇您喜歡的)。 如果套接字可讀,請讀取命令並對其作出反應。 如果套接字是可寫的(並且有數據請求),請發送測量值。

如果有人需要這個:

def conn_handler(self, connection, address):
    self.logger.info("[%d] - Connection from %s:%d", 10, address[0], address[1])

    sending_measurements_enabled = False
    try:
        while True:

            command = None
            readable, writable, exceptional = select([connection], [], [], 0)

            if readable:
               data = connection.recv(2048)

               if data:
                   command = get_command_from_data(data)
                   print("Received command %s", command)


            if command == 'start':
                sending_measurements_enabled = True
            elif command == 'stop':
                break
            elif command == 'id':
                connection.sendall(self.id)
            elif command == 'cfg':
                connection.sendall(self.cfg)

            if sending_measurements_enabled:
                connection.sendall(measurement)

    except Exception as e:
       print(e)
    finally:
        connection.close()
        print("Connection closed")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM