Non-blocking 服务器套接字
Non-blocking socket for server
我在 whosebug.com 上检查了几个类似的线程,我认为我可能需要为我的服务器脚本打开 non-blocking 套接字。因为,我不确定这是解决问题的标题可能是错误的。让我解释一下我的问题是什么。
服务器应用程序等待连接,一旦客户端连接,它将请求服务器 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 服务器将 return ID 消息,然后客户端将发送命令获取配置,服务器将 return 配置消息但是当我send 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")
我在 whosebug.com 上检查了几个类似的线程,我认为我可能需要为我的服务器脚本打开 non-blocking 套接字。因为,我不确定这是解决问题的标题可能是错误的。让我解释一下我的问题是什么。
服务器应用程序等待连接,一旦客户端连接,它将请求服务器 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 服务器将 return ID 消息,然后客户端将发送命令获取配置,服务器将 return 配置消息但是当我send 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")