[英]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
命令。 另外,如果服務器在發送測量值時接收到id
或cfg
命令,它將首先發送id
或cfg
然后繼續發送測量值。
在服務器循環中調用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.