I have a list write command that need to infinite loop as thread by turn. Each call thread need to wait recv method to match OK or ERROR conditional. Then, call next command again with thread. The command in below. Current, the output buffer in unorder. It can't use join. Because, write command to fast than income buffer. The only ways is to pause after call write method and wait recv method a signal conditional match OK or ERROR. Then, iterate next command again and so on. How to achieve this?
AT+CGMI
AT+CGSN
class Device():
__command = 'none'
def __init__(self, port, baudrate):
self.__port = port
self.__baudrate = baudrate
def open(self):
try:
self.handle = serial.Serial(self.__port, self.__baudrate)
return True
except SerialException as e:
error = re.findall(r"'(.*?)'", str(e))
self.__error = {'port': error[0], 'description': error[1]}
return None
def __state(self):
if self.open() is None:
if self.__error['description'] == 'Access is denied.':
return True
elif self.__error['description'] == 'Port is already open.':
return True
else:
return False
else:
return True
def recv(self):
while True:
if self.__state():
buffer = self.handle.readline()
if buffer == b'AT+CGSN\r\r\n':
data = []
while True:
buffers = self.handle.readline()
data.append(buffers.decode('UTF-8').strip())
if buffers == b'OK\r\n':
print(data[0])
self.__command = 'done'
break
elif buffers == b'ERROR\r\n':
break
elif buffer == b'AT+CGMI\r\r\n':
data = []
while True:
buffers = self.handle.readline()
data.append(buffers.decode('UTF-8').strip())
if buffers == b'OK\r\n':
print(data[0])
self.__command = 'done'
break
elif buffers == b'ERROR\r\n':
break
else:
print(self.__error['port'] + ' ' + self.__error['description'])
time.sleep(1)
def write(self, command):
if self.__state():
self.__command = 'waiting'
self.handle.write(command.encode('UTF-8') + b'\r')
while self.__command == 'waiting':
if self.__command == 'done':
break
device = Device('COM12', 9600)
device.open()
recv = threading.Thread(target=device.recv)
recv.start()
commands = ['AT+CGSN', 'AT+CGMI']
while True:
for command in commands:
device.write(command)
Related
I want to stream real-time data of the order book of BTC/USD using a WebSocket connection to the FTX Exchange. After the first snapshot of the order book, the WebSocket returns updates that I apply to my local reconstructed order book. To ensure that my order book is synchronized, I have to check a crc32 integer after every update. If this number matches the checksum in the message, I can be confident that my order book is well synchronized. However, sometimes the checksum is not right, and I need to reset the connection, i.e. unsubscribe to the channel and subscribe right after.
At the end of the on_messagefunction, I check if the checksum is successful. If it is not, I close the connection but I would like to clear the memory (i.e. the global objects asks, bids, checksum) and reconnect right after. How can I do it?
Should I just add a while True loop at the end? Like this one?
while True:
ws.run_forever()
I don't like this while Truesolution because it's impossible for me to stop it, I have to quit the terminal.
My code is the following
import websocket,json
import zlib
from decimal import Decimal
import binascii
from itertools import chain, zip_longest
from typing import Iterable, Sequence
asks = {}
bids = {}
checksum = {'checksum':0}
def format_e(dec):
return ('{:.' + str(len(dec.as_tuple().digits) - 1) + 'e}').format(dec)
def check_sum(
asks: Iterable[Sequence[float]], bids: Iterable[Sequence[float]]
) -> int:
asks=[[level[0],level[1]]for level in asks.items()]
bids=[[level[0],level[1]]for level in bids.items()]
order_book_hash_iterator = zip_longest(bids, asks, fillvalue=tuple())
check_string = ":".join(
(
str(token)
for ask_level, bid_level in order_book_hash_iterator
for token in chain(ask_level, bid_level)
)
)
return binascii.crc32(check_string.encode("ascii"))
def on_open(ws):
print('Opened connection')
asks.clear()
bids.clear()
subscribe_message = {'op': 'subscribe', 'channel': 'orderbook','market':'BTC/USD'}
ws.send(json.dumps(subscribe_message))
def on_message(ws,message):
js=json.loads(message)
if js['type'] == 'partial':
print('Get Snapshot')
for level in js['data']['asks']:
asks[level[0]]=level[1]
for level in js['data']['bids']:
bids[level[0]]=level[1]
checksum['checksum']=js['data']['checksum']
if js['type'] == 'update':
for level in js['data']['asks']:
if level[1]==0:
asks.pop(level[0])
else:
asks[level[0]]=level[1]
for level in js['data']['bids']:
if level[1]==0:
bids.pop(level[0])
else:
bids[level[0]]=level[1]
if check_sum(asks,bids) != js['data']['checksum']:
print('Error')
ws.close()
socket = "wss://ftx.com/ws/"
ws = websocket.WebSocketApp(socket,on_open=on_open)
ws.on_message = lambda ws,msg: on_message(ws,msg)
ws.run_forever()
How about this:
# everything up to and including `on_open` the same
class ChecksumException(Exception):
pass
def on_message(ws, message):
print(message)
js = json.loads(message)
if js['type'] == 'partial':
print('Get Snapshot')
for level in js['data']['asks']:
asks[level[0]] = level[1]
for level in js['data']['bids']:
bids[level[0]] = level[1]
checksum['checksum'] = js['data']['checksum']
if js['type'] == 'update':
for level in js['data']['asks']:
if level[1] == 0:
asks.pop(level[0])
else:
asks[level[0]] = level[1]
for level in js['data']['bids']:
if level[1] == 0:
bids.pop(level[0])
else:
bids[level[0]] = level[1]
if js['type'] == 'subscribed':
return
# so, checking this for *any* type of message, except 'subscribed'
if check_sum(asks, bids) != js['data']['checksum']:
raise ChecksumException
def main():
socket = "wss://ftx.com/ws/"
while True:
ws = None
try:
ws = websocket.WebSocketApp(socket, on_open=on_open)
ws.on_message = lambda w=ws, msg=None: on_message(w, msg)
print('Connecting...')
ws.run_forever()
print('Keyboard interrupt, stopping')
break
except ChecksumException:
ws.close()
print('Checksum error, closed')
# no break here, so the loop continues and will reconnect
if __name__ == '__main__':
main()
I am trying to call a function inside an infinite loop. Once x happens in the function, I want it to return to the beginning of the while loop. How do you break out of the function?
I have tried to use break and return but, no luck.
def cmndln():
while True:
command = input("Input:> ")
if command == 'exit':
clientsocket.close()
break
elif command == 'decrypt':
clientsocket.send("decrypt".encode())
msg = clientsocket.recv(1024)
print(msg.decode())
key = input("Key: ")
clientsocket.send(key.encode())
msg = clientsocket.recv(1024)
print(msg.decode())
command = None
break
elif command == 'encrypt':
clientsocket.send("encrypt".encode())
msg = clientsocket.recv(1024)
print(msg.decode())
command = None
break
return
while True:
cmndln()
I want to start the function again
def cmndln():
command = input("Input:> ")
if command == 'exit':
clientsocket.close()
elif command == 'decrypt':
clientsocket.send("decrypt".encode())
msg = clientsocket.recv(1024)
print(msg.decode())
key = input("Key: ")
clientsocket.send(key.encode())
msg = clientsocket.recv(1024)
print(msg.decode())
command = None
elif command == 'encrypt':
clientsocket.send("encrypt".encode())
msg = clientsocket.recv(1024)
print(msg.decode())
command = None
def main():
while True:
#condition here
cmndln()
if __name__ = '__main__':
main()
Instead of the infinite loop twice you can call it once in the main function.
This way the command is still being called like before. You can now break on a condition in the main to exist the function.
I'm trying to design a control interface for my system which sends and receives some data through serial link. My searches related to GUI design took me to understand the "multi-threading" issue and code below shows the latest position I arrived.
This indicates similar parts (e.g try, run) with the ones I've seen on example GUIs. I planned to convert this to a GUI, once I understand how it exactly works.
So the problem is after I start, stop the code below I can't restart it again. Because, as I understand, multi-threading features only one cycle: start, stop and quit. I mean it doesn't accept start command after stop.
My question is how I can make this code to accept start after stopping?
Best wishes
import threading, random, time
class process(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
self.leave = 0
print("\n it's running ...\n\n")
while self.leave != 1:
print "Done!"
time.sleep(1)
operate = process()
while True:
inputt = input(" START : 1 \n STOP\t : 0 \n QUIT\t : 2 \n")
try:
if int(inputt) == 1:
operate.start()
elif int(inputt) == 0:
operate.leave = 1
elif int(inputt) == 2:
break
except:
print(" Wrong input, try egain...\n")
Create process inside while True loop
if int(inputt) == 1:
operate = process()
operate.start()
It should work.
... but your code may need other changes to make it safer - you will have to check if process exists before you try to stop it. You could use operate = None to control it.
import threading
import random
import time
class Process(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
self.leave = False
print("\n it's running ...\n\n")
while self.leave == False:
print("Done!")
time.sleep(1)
operate = None
while True:
inputt = input(" START : 1 \n STOP\t : 0 \n QUIT\t : 2 \n")
try:
if int(inputt) == 1:
if operate is None:
operate = Process()
operate.start()
elif int(inputt) == 0:
if operate is not None:
operate.leave = True
operate.join() # wait on process end
operate = None
elif int(inputt) == 2:
if operate is not None:
operate.leave = True
operate.join() # wait on process end
break
except:
print(" Wrong input, try egain...\n")
Other method is not to leave run() when you set leave = True but keep running thead. You would need two loops.
def run(self):
self.leave = False
self.stoped = False
print("\n it's running ...\n\n")
while self.leave == False:
while self.stoped == False:
print("Done!")
time.sleep(1)
I'm running windows 10, python 2.7 using pycharm
I'm doing as an exercise a socket chat room, and I've stumbled on a certain problem:
While running the client and server socket from multiple cmd windows,
When I exit one cmd window abruptly, the server is supposed to forward a message to the remaining client - informing them that a client left (including the client's nick)
For some reason it proves to be a problem, the server seems to retain that client in the client list, raising an error as if I sent him that message (which obviously is problematic, because he is no longer there).
When I tried to fix that - changing the loop to not send the message to that specific client (by saving his socket object) -it doesn't send any message.
As if it doesn't recognize the other clients.
My code:
Server:
import socket
import select
import datetime
server_socket=socket.socket()
server_socket.bind(('127.0.0.1',23))
server_socket.listen(5)
open_client_sockets = []
messages_to_send = []
chat_clients={}
def send_waiting_messages(wlist):
for message in messages_to_send:
(sender,msg)=message
if(msg=='\r'):
continue
elif(msg=='quit'):
pass
else:
nick_len=int(msg[:2])
nick=msg[2:2+nick_len]
chat=msg[2+nick_len:]
chat_clients[sender]=nick
for client in wlist:
if(msg=='quit'):
client.send(('{:02d}:{:02d} {} has left the chat!'.format(datetime.datetime.now().hour,datetime.datetime.now().minute,sender)))
else:
if(client is sender):
client.send('NL')
else:
client.send('{:02d}:{:02d} {}: {}'.format(datetime.datetime.now().hour,datetime.datetime.now().minute,nick,chat))
messages_to_send.remove(message)
while True:
rlist,wlist,xlist=select.select([server_socket] + open_client_sockets,open_client_sockets,[])
for current_socket in rlist:
print wlist
if(current_socket is server_socket):
(new_socket,address)=server_socket.accept()
open_client_sockets.append(new_socket)
chat_clients[new_socket]=''
else:
try:
msg=current_socket.recv(1024)
except socket.error as e:
if e.errno==10054:
msg=''
else:
raise
if(msg=='' or msg=='quit'):
if(msg=='quit'):
messages_to_send.append((chat_clients[current_socket], 'quit'))
current_socket.send('quit')
open_client_sockets.remove(current_socket)
del chat_clients[current_socket]
else:
print '{:02d}:{:02d} {} has left the chat!'.format(datetime.datetime.now().hour,
datetime.datetime.now().minute, chat_clients[current_socket])
messages_to_send.append((current_socket, 'quit'))
else:
print msg
messages_to_send.append((current_socket,msg))
send_waiting_messages(wlist)
Client:
import socket
import select
import datetime
server_socket=socket.socket()
server_socket.bind(('127.0.0.1',23))
server_socket.listen(5)
open_client_sockets = []
messages_to_send = []
chat_clients={}
def send_waiting_messages(wlist):
for message in messages_to_send:
(sender,msg)=message
if(msg=='\r'):
continue
elif(msg=='quit'):
pass
else:
nick_len=int(msg[:2])
nick=msg[2:2+nick_len]
chat=msg[2+nick_len:]
chat_clients[sender]=nick
for client in wlist:
if(msg=='quit'):
client.send(('{:02d}:{:02d} {} has left the chat!'.format(datetime.datetime.now().hour,datetime.datetime.now().minute,sender)))
else:
if(client is sender):
client.send('NL')
else:
client.send('{:02d}:{:02d} {}: {}'.format(datetime.datetime.now().hour,datetime.datetime.now().minute,nick,chat))
messages_to_send.remove(message)
while True:
rlist,wlist,xlist=select.select([server_socket] + open_client_sockets,open_client_sockets,[])
for current_socket in rlist:
print wlist
if(current_socket is server_socket):
(new_socket,address)=server_socket.accept()
open_client_sockets.append(new_socket)
chat_clients[new_socket]=''
else:
try:
msg=current_socket.recv(1024)
except socket.error as e:
if e.errno==10054:
msg=''
else:
raise
if(msg=='' or msg=='quit'):
if(msg=='quit'):
messages_to_send.append((chat_clients[current_socket], 'quit'))
current_socket.send('quit')
open_client_sockets.remove(current_socket)
del chat_clients[current_socket]
else:
print '{:02d}:{:02d} {} has left the chat!'.format(datetime.datetime.now().hour,
datetime.datetime.now().minute, chat_clients[current_socket])
messages_to_send.append((current_socket, 'quit'))
else:
print msg
messages_to_send.append((current_socket,msg))
send_waiting_messages(wlist)
Help would be much appreciated!
I have also been trying trying to make a chat room and I have been successful. You might want to look at my code to find the solution.
Server
import threading
from queue import Queue
import socket
host = ''
port = 5000
client_list = []
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(1000)
def conn():
while True:
(host, port) = s.accept()
f = len(client_list)
client_list.append(host)
print(client_list)
p1 = threading.Thread(target=clientam, args=str(f))
p2 = threading.Thread(target=threader)
p2.start()
p1.start()
p1.join()
p2.join()
def clientam(client):
size = 3000
client = int(client)
c = client_list[client]
print(c)
c.send("Welcome to the chatroom".encode())
while True:
try:
data = c.recv(size).decode()
if data == "exit":
for l in client_list:
if l == c:
pass
else:
l.send("The other person has left the chatroom".encode())
client_list[client] = ''
print(client_list)
c.close()
break
else:
for l in client_list:
if l == c:
pass
else:
l.send(data.encode())
except Exception:
for l in client_list:
if l == c:
continue
else:
try:
l.send("The other person has left the chatroom".encode())
except Exception:
pass
break
try:
c.close()
except Exception:
break
def threader():
t = threading.Thread(target=conn)
t.start()
t.join()
threader()
client
import socket
import threading
import time
import pickle
host = '127.0.0.1'
port = 5000
s = socket.socket()
d = 0
print_lock = threading.Lock()
def conn():
global d
global s
try:
if d == 1:
s = socket.socket()
s.connect((host, port))
d = 0
elif d == 0:
s.connect((host, port))
except Exception:
conn()
def reciever():
global d
global g
g = False
li = [128, 3, 88, 0, 113, 46]
size = 3000
while True:
try:
data = s.recv(size).decode()
data = str(data)
with open('Data.txt', 'a') as f:
f.write(data)
if str(data) == 'The other person has left the chatroom':
with print_lock:
print(data)
elif str(data) == "Welcome to the chatroom":
g = True
with print_lock:
print(str(data))
else:
try:
int(data)
continue
except Exception:
with print_lock:
print("Other Person:> " + str(data))
except Exception as e:
with print_lock:
print("You have been disconnected")
d = 1
s.close()
with print_lock:
print('Trying to connect to server')
conn()
def sender():
global d
global g
while True:
if g == True:
while True:
with print_lock:
i = input('You:> ')
if i == 'exit':
try:
s.send(i.encode())
with print_lock:
print("You have been disconnected")
d = 1
except Exception:
with print_lock:
print('You have been disconnected')
d = 1
elif i == "connect":
if d == 0:
with print_lock:
print("Server already connected")
elif d == 1:
with print_lock:
print('Server connecting')
conn()
else:
try:
if d == 0:
s.send(i.encode())
elif d == 1:
with print_lock:
print('Server is disconnected')
except Exception:
with print_lock:
print('Server is disconnected')
def threader():
p1 = threading.Thread(target = reciever)
p1.start()
p2 = threading.Thread(target = sender)
p2.start()
p1.join()
p2.join()
conn()
threader()
So, I've had a problem this morning that I couldn't find any posted answers yet. Basically, I wanted to have my Python client to reconnect everytime the server shuts down.
My previous code looks like this
def fire(self):
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.s.settimeout(5)
while (self.connected):
# create the transmission_struct class
msg = transmission_struct(self.stream, self.CHUNK, self.rate)
# create the Filestream packet
packet1 = msg.structure_msg_fls()
# create the decision packet
packet2 = msg.structure_msg_stm()
# send, first the decision packet
self.s.sendall(packet2)
# send the whole packet one by one
for i in range(len(packet1)):
self.s.sendall(packet1[i])
# timestamp for debugging purposes
ts = time.time()
timestamp = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
print(timestamp + " size of data sent is " + str(len(packet1)) +
" size of decision is " + str(len(packet2)))
I implemented the reconnection logic through try and exception blocks and a recursion in the attempt function.
def fire(self):
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.s.settimeout(5)
self.attempt_connect()
while (self.connected):
# create the transmission_struct class
msg = transmission_struct(self.stream, self.CHUNK, self.rate)
# create the Filestream packet
packet1 = msg.structure_msg_fls()
# create the decision packet
packet2 = msg.structure_msg_stm()
try:
# send, first the decision packet
self.s.sendall(packet2)
# send the whole packet one by one
for i in range(len(packet1)):
self.s.sendall(packet1[i])
# timestamp for debugging purposes
ts = time.time()
timestamp = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
print(timestamp + " size of data sent is " + str(len(packet1)) + " size of decision is " + str(len(packet2)))
except socket.error as e:
print(e.errno)
self.connected = False
print("Attempting to connect...")
self.close_open_new_socket()
time.sleep(1)
continue
except IOError as e:
print(e.errno)
self.close_open_new_socket()
continue
except KeyboardInterrupt:
self.s.close()
finally:
self.attempt_connect()
def attempt_connect(self):
while (self.connected is False):
try:
self.result = self.s.connect((self.host, self.port))
if (self.result == None):
self.connected = True
else:
self.connected = False
except socket.error as e:
errorcode = e[0]
print(errorcode)
if (errorcode == 56):
self.connected = True
time.sleep(1)
continue
elif(errorcode == 22):
self.connected = False
print("attempting to reconnect...")
# adding recursive call to attempt connect
# after socket is broken
self.close_open_new_socket()
time.sleep(1)
continue
elif (errorcode == 61):
self.connected = False
print("Server not up, waiting for server and reconnecting...")
time.sleep(1)
continue
elif (errorcode == 32):
self.connected = False
print("Server down, attempting to reconnect...")
time.sleep(1)
continue
else:
self.connected = False
time.sleep(1)
continue
def close_open_new_socket(self):
self.s.close()
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.s.settimeout(5)
self.attempt_connect()