I've checked few similar threads on stackoverflow.com and I think I might need to open non-blocking socket for my server script. Since, I'm not sure that this is the solution question title might be wrong. Let me explain what is my problem.
Server app waits for connection and once client connects it will ask for server ID, after that client will ask for server configuration and than client will send command to server to start measurement transmission. Here's simplified version of my code:
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")
And here is client script:
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()
And here is my problem:
When I run client and send command to get ID server will return ID message, then client will send command to get configuration and server will return configuration message but when I send start
command server will send only one measurement and than I guess connection.recv(2048)
will block execution until server gets another command. So, I added that line inside while True:
loop in client script which will keep sending (unnecessary, invalid) commands and server will keep sending measurements.
How to solve this without sending commands all the time from client. I want to be able to send only one command start
and server will keep sending measurements, and stop only when client sends stop
command. Also, if server receives id
or cfg
command while sending measurements it will first send id
or cfg
and than keep sending measurements.
In the server loop call select.select([connection], [connection], [connection])
( select module provides more facilities, so pick your favorite). If the socket is readable, read command and react on it. If the socket is writable (and there was a request for data), send measurements.
In case someone needs this:
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")
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.