I am trying to run two while loops in this program. The first while loop needs to run up to 50 seconds but this loop does not exit after 50 seconds (Not terminating after 50 Seconds), it just continues. I verified the timer in a separate program, where timer works well,but in my program timer is not working.
import array
import time
import socket
import os,sys
import concurrent.futures
import struct
Nmax_Per_hop=100
hello_Broadcast_Period=40
NeighborDiscovery_Time_Interval=50
MyNeighborSet_ip=[]
all_ip=[]
a=10
b=0
start_time=time.time()
My_ip='192.168.1.1'
#############################################################################
def broadcast_hello(): # (send 'Hello message')
ip1 = "192.168.1.254"
print ("[tx]------>hello to:"+ ip1)
PORT = 12345
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1)
s.sendto (b'Hello',('192.168.1.254',PORT))
##########################################################################
def received_hello():
PORT = 12345
ip=[]
recv_message_hello=[]
global a
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.bind(('',PORT))
message=s.recvfrom(4096)
print ("before the ip")
ip=message[1][0]
if (ip not in all_ip):
all_ip.append(ip)
print (all_ip)
recv_message=message[0]
if not recv_message in recv_message_hello:
recv_message_hello=recv_message
if (ip==My_ip):
pass
elif ip not in MyNeighborSet_ip :
MyNeighborSet_ip.append(ip)
else:
print ("Already in List")
print ("[N-Set]------------:",MyNeighborSet_ip)
##########################################################################
temp = concurrent.futures.ThreadPoolExecutor (max_workers=2)
Here this loop is not working well
while(((time.time()-start_time)<NeighborDiscovery_Time_Interval) and (len(MyNeighborSet_ip) <= Nmax_Per_hop)):
if (time.time()-start_time<hello_Broadcast_Period):
temp.submit(broadcast_hello)
try:
temp.submit(received_hello)
except:
print("###################")
print ("IP of this node is: ",My_ip)
print ("[N-Set]------------:",MyNeighborSet_ip)
while (b<10):
print ("dfdfdfdfdfdfdfdf")
b+=1
Can anybody help me how to fix this problem?
Related
Working on learning socket programming and I am having a strange issue crop up between my two codes depending on what IP I try to run them through.
Server:
import socket
import time
import datetime
import filecmp
HOST = 'localhost'
PORT = 9100
n = 1
x = 0
average_list = []
print('I am ready for any client side request \n')
file_comparison = "send.txt"
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST,PORT))
s.listen(1)
conn, addr = s.accept()
while n <= 100:
data = conn.recv(1024)
file = 'receive1.txt';
print('I am starting receiving file', file,'for the',n,'th time')
a = datetime.datetime.now()
f = open(file, 'wb')
f.write(data)
print('I am finishing receiving file', file,'for the',n,'th time')
b = datetime.datetime.now()
rawtime = b - a
millidelta = rawtime * 1000
average_list.append(millidelta)
real_average = ((sum(average_list, datetime.timedelta(0,0))) / n)
print('The time used in milliseconds to receive',file,'for the',n,'th time','is:',millidelta,'milliseconds')
print('The average time to receive',file,'in milliseconds is:',real_average)
if filecmp.cmp(file,file_comparison,shallow=False):
x = x+1
n=n + 1
f.close()
conn.close()
s.close()
print('I am done \n')
print('Total errors: ',x,'out of',n-1 )
Client:
import socket
import datetime
import time
import filecmp
#initializing host, port, filename, total time and number of times to send the file
host = 'localhost'
port = 9100
fileName = "send.txt"
n = 1
average_list = []
file_to_send = open(fileName,'rb')
while n <= 100:
data = file_to_send.read(1024)
s=socket.socket()
s.connect((host,port))
s.sendall(data)
#reading the next 1024 bits
print('I am connecting to server side:',host,'\n')
print('I am sending file',fileName,'for the',n,'th time')
a = datetime.datetime.now()
print('I am finishing sending file',fileName,'for the',n,'th time')
b = datetime.datetime.now()
rawtime = b - a
millidelta = rawtime * 1000
average_list.append(millidelta)
real_average = ((sum(average_list, datetime.timedelta(0,0))) / n)
print('The time used in milliseconds to send',fileName,'for the',n,'th time','is:',millidelta,'milliseconds')
print('The average time to send',fileName,'in milliseconds is:',real_average)
n = n + 1
file_to_send.close()
s.close()
print('I am done')
In this current iteration my client side code simply runs through the loop trying to send the data of a .txt file to a server that isnt receiving anything. If i change 'localhost' to my actual IP address, I instead get the server side code cycling through its while loop while the client side gives up after 2 iterations with:
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it
with the error citing line 15, "s.connect((host,port)) as the cause of the issue. Ultimately Im stuck since changing my host between what I assumed were two correct implementations of the host are giving me drastically different results with neither working as intended.
What I think the error is trying to tell us from other times I have seen that is that the port the socket is trying to connect is still connected to another socket.
So my diagnosis of why that might be happening is that the s.close() is not in the while loop so it keeps making a new socket and then tries to connect on the same port.
Edit: I got a chance to run it on my side and it works for me if I pull the whole making and binding of a socket out of the loop like this:
import socket
import datetime
import time
import filecmp
#initializing host, port, filename, total time and number of times to send the file
host = 'localhost'
port = 9100
fileName = "send.txt"
n = 1
average_list = []
file_to_send = open(fileName,'rb')
s=socket.socket()
s.connect((host,port))
while n <= 100:
data = file_to_send.read(1024)
s.sendall(data)
#reading the next 1024 bits
print('I am connecting to server side:',host,'\n')
print('I am sending file',fileName,'for the',n,'th time')
a = datetime.datetime.now()
print('I am finishing sending file',fileName,'for the',n,'th time')
b = datetime.datetime.now()
rawtime = b - a
millidelta = rawtime * 1000
average_list.append(millidelta)
real_average = ((sum(average_list, datetime.timedelta(0,0))) / n)
print('The time used in milliseconds to send',fileName,'for the',n,'th time','is:',millidelta,'milliseconds')
print('The average time to send',fileName,'in milliseconds is:',real_average)
n = n + 1
s.close()
file_to_send.close()
This definitely works for me and sends the file 100 times and it gets received 100 times but I don't know if in your use case you need it to be a hundred new sockets instead of one socket sending 100 files that get successfully received.
I am working in a project where I interfaces two rotary encoder with Raspberry pi and at same time read two sensor values and shown them on tkinter window and now as per project I need to send these values to PC whenever a query command receive from PC .I read from google that if we want two continuous loop then we cab achieve via thread method. But I don't have enough knowledge about threading.
Below I am providing tkinter code as well as TCP/IP code.
import pigpio
import tkinter as tk
from PIL import ImageTk,Image
import time
from RPi import GPIO
import serial
i="*00T%"
j="*01T%"
s=serial.Serial(port='/dev/ttyS0',
baudrate=9600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=1)
class decoder: # class for decoding rotary encoder
def __init__(self, pi, gpioA, gpioB, callback):
----------
---------------
----------------
if __name__ == "__main__":
rpm=0
tor=0
pow=0
pi = pigpio.pi()
st=1
pos=0
def callback(way): # interrupt event sense on pin no 17,18
global pos
global st
if st ==1:
pos += way
if pos >= 9999:
pos=9999
if pos <= 0:
pos=0
var.set(pos)
print("pos={}".format(pos))
def rpm_update():
--------------
rpm read code
---------------
def tor_update():
-------------------
torque read code
---------------------
def pow_update():
------------------------
power Calculation
--------------------------
def update():
--------------------
root.after(200,update)
path="/home/pi/logo.png"
root=tk.Tk()
img=ImageTk.PhotoImage(Image.open(path))
panel=tk.Label(root,image=img)
panel.pack()
panel.place(x=195,y=10,height=50,width=80)
root.title("Dynalec")
root.geometry("500x600")
{
body of tkinter screen
}
decoder=decoder(pi, 17, 18, callback)
root.after(200,update)
root.mainloop()
and my server code which is working perfectly in while loop.
I want to merge this two code two achieve desire result perfectly.
import socket
import encodings
rpm = 2000
tor = 35
pow = 7.33
HOST = '169.254.29.78'
PORT = 65432
def data():
global rpm, tor, pow
my_sensor = "{},{},{}".format(rpm,tor,pow)
return my_sensor # return data seperated by comma
def my_server():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
print("Server Started waiting for client to connect ")
s.bind((HOST, PORT))
s.listen(5)
conn, addr = s.accept()
with conn:
print('Connected by', addr)
while True:
data = conn.recv(1024).decode('utf-8')
if str(data) == "Data":
print("Ok Sending data ")
my_data = data()
x_encoded_data = my_data.encode('utf-8')
conn.sendall(x_encoded_data)
elif str(data) == "Quit":
print("shutting down server ")
break
if not data:
break
else:
pass
if __name__ == '__main__':
while 1:
my_server()
I Have infinite loop that read bytes from serial port, I want to save the read data to firebase database every X seconds.
I used this code snippet but it's not helping:
import threading
def printit():
threading.Timer(5.0, printit).start()
print "Hello, World!"
printit()
This is my code
import serial
ser = serial.Serial()
ser.baudrate = 115200
ser.port = "/dev/ttyUSB0"
ser.timeout = 30
try:
try:
while 1:
line = ser.readline().rstrip().decode('utf-8')
# print("save data here every X seconds)
except KeyboardInterrupt:
ser.close() # Close port
pass
except serial.serialutil.SerialException as e:
print(str(e))
I can't use sleep because it blocking the main thread,So how to let the code read continuously and print "data saved" every X seconds (I'll save to database in my case)
Thanks to Lutz Horn for the suggestion in the comment, I resolve the problem like that :
import schedule
import time
import serial
ser = serial.Serial()
ser.baudrate = 115200
ser.port = "/dev/ttyUSB0"
ser.timeout = 30
schedule.every(10).seconds.do(save_db)
try:
try:
while 1:
schedule.run_pending()
line = ser.readline().rstrip().decode('utf-8')
# here every 10 seconds the function save_db will be called
except KeyboardInterrupt:
ser.close() # Close port
pass
except serial.serialutil.SerialException as e:
print(str(e))
I hope i have understood you correctly. Use time.time() to set timer.
import time
def doEvery_X_Seconds():
print("I do it every X seconds")
time.sleep(1)
TIMER_LIMIT = 5
setTimer = time.time()
while(1):
print("hello world")
if(time.time() - setTimer >= TIMER_LIMIT):
doEvery_X_Seconds()
setTimer = time.time()
There is time.sleep(1) only to demonstrate, that it works.
First of all I am a complete noobie when it comes to python. Actually I started reading about it this morning when I needed to use it, so sorry if the code is a disaster.
I'd like to get this done:
A communication via serial between two devices. The device where the python program is running has to be listening for some data being sent by the other device and storing it in a file. But every 30 seconds of received data it has to send a command to the other device to tell it to stop sending and begin a scan that takes 10 seconds.
This is the code I've written. It's printing continuously Opening connection..
from serial import Serial
from threading import Timer
import time
MOVE_TIME = 30.0
SCAN_TIME = 10.0
DEVICE_ADDRESS = '/dev/ttyACM0'
BAUD_RATE = 9600
while True:
try:
print("Opening connection...")
ser = Serial(DEVICE_ADDRESS, BAUD_RATE
break
except SerialException:
print("No device attached")
def scan():
print("Scanning...")
timeout = time.time() + SCAN_TIME
while True:
#Some code I haven't thought of yet
if time.time() > timeout:
ser.write(b'r') #command to start
break
def send_stop_command():
print("Sending stop command")
ser.write(b's') #command to stop
scan()
t = Timer(MOVE_TIME + SCAN_TIME, send_stop_command)
t.start()
filename = time.strftime("%d-%m-%Y_%H:%M:%S") + ".txt"
while True:
data = ser.readline()
try:
with open(filename, "ab") as outfile:
outfile.write(data)
outfile.close()
except IOError:
print("Data could not be written")
I am trying to write a program that works as an intermedium. (M)
I can only use telnet to connect :
A needs to connect to M, B connects to M.
A sends data to M on a socket, M needs to pass it to B
B sends data to M on another socket
I tried this by starting four threads with a shared list
The problem is it seems it is not writing to the other socket, or even accepting writing.
Does anyone know a better way to implement this and pass it through to another socket
My code :
import sys
import arduinoReadThread
import arduinoWriteThread
import socket
class ControllerClass(object):
'''
classdocs
'''
bolt = 0
socketArray=list()
def __init__(self):
self.readAndParseArgv()
self.createThreads()
def readAndParseArgv(self):
array = sys.argv
print sys.argv
if len(array) != 3:
print "Too few arguments : ./script host:port host:port"
else:
for line in array:
if ":" in line:
splitted = line.split(':')
HOST = splitted[0]
print HOST
PORT = int(splitted[1])
print PORT
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM ) #create an INET, STREAMing socket
s.bind((HOST,PORT)) #bind to that port
print "test"
s.listen(1) #listen for user input and accept 1 connection at a time.
self.socketArray.append(s)
def createThreads(self):
print "Creating Threads"
sharedArray1 = list()
sharedArray2 = list()
s1 = self.socketArray.pop()
s2 = self.socketArray.pop()
sT1 = arduinoWriteThread.writeThread().run(self.bolt,sharedArray1,s2)
sT2 = arduinoReadThread.readThread().run(self.bolt,sharedArray1,s1)
sT3 = arduinoReadThread.readThread().run(self.bolt,sharedArray2,s2)
sT4 = arduinoWriteThread.writeThread().run(self.bolt,sharedArray2,s1)
sT1.start()
sT2.start()
sT3.start()
sT4.start()
x = ControllerClass()
x
Two Threads :
Write Thread :
import threading
class writeThread ( threading.Thread ):
def run ( self,bolt,writeList,sockeToWriteTo ):
s = sockeToWriteTo
while(bolt == 0):
conn, addr = s.accept()
if len(writeList) > 0:
socket.send(writeList.pop(0))
Read Thread
import threading
class readThread ( threading.Thread ):
def run ( self,bolt,writeList,socketToReadFrom ):
s = socketToReadFrom
while(bolt == 0):
conn, addr = s.accept()
f = conn.rcv()
print f
writeList.append(f)
You don't really need threads for this...
When a new connection is accepted, add it to a list. When receiving anything from one of the connection in the list, send to all connections except the one you got the message from.
Use select to see which connections have send data to you.
Edit
Example using select:
# serversocket: One server socket listening on some port, has to be non-blocking
# all_sockets : List containing all connected client sockets
while True:
readset = [serversocket]
readset += all_sockets
# Wait for sockets to be ready, with a 0.1 second timeout
read_ready = select.select(readset, None, None, 0.1)
# If the listening socket can be read, it means it has a new connection
if serversocket in read_ready:
new_connection = serversocket.accept()
new_connection.setblocking(0); # Make socket non-blocking
all_sockets += [new_connection]
read_ready.remove(serversocket) # To not loop over it below
for socket in read_ready:
# Read data from socket
data = socket.recv(2048)
for s in all_sockets:
# Do not send to self
if s != socket:
s.send(data)
Disclaimer I have never really used the Python socket functions, the code above was made from reading the manual pages just now. The code is probably not optimal or very Pythonic either.