I'm running two raspis connected to each other. They both run a program on startup (which starts fine).
However, I keep getting a error: [Errno 98] Address already in use error in the background, and the communication between both Pis doesn't even start.
I went for tracing down the python processes running via ps -fA ¦ grep python and tadaaa, I can see, that another process starts trying to use the same address.
The output of ps looks like:
root 923 917 0 12:25 pts/1 00:00:00 sudo python /home/pi/Documents/3_multithread.py
root 927 923 10 12:25 pts/1 00:00:00 python /home/pi/Documents/3_multithread.py
pi 932 881 0 12:25 pts/0 00:00:00 grep --color=auto python
From what I understand is, that it looks like the same process (3_multithread.py) is called twice (once as su, once not as su).
EDIT#2: I start the program via the .bashrc (sudo python /home/pi/Documents/3_multithread.py) and a lxsession. Might this be the reason for blocking the address?
The errorlog looks like that:
File "/home/pi/Documents/3_multithread.py", line 276, in set_server bind((HOST, PORT))
File "/usr/lib/python2.7/socket.py", line 228, in meth return getattr(self._sock, name)(*args)
error: [Errno 98] Address already in use
I just also checked the netstat -lptn. I get the following output:
tcp 0 0 0.0.0.0:22 0.0.0.0.* LISTEN -
EDIT#123: I traced the error further down. I imported and printed:
import os
os.getpid()
To get the process PID. Now what happens is: On bootup my script returned the PID 754, while the ps -fA ¦ grep python only stats two python processes with the PIDs 535 and 539. Does .bashrc and lxterminal start the process twice?
This is how i configure my socket inside the python script
def set_server():
global conn_global
global socket_global
global conn_established
HOST = ''
PORT = 22
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()
socket_global = s
conn_global = conn
conn_established = 1
I'm using global variables to send commands to send the commands to the other Pi, which is working absolutely perfect (once the connection is established).
Thank you guys very much in advance!
With best regards,
Tobi
So I was FINALLY able to solve that issue.
As Hannu suggested first, the problem was the way I booted the system. First of all, what did I want to do?
I need to boot both Raspis into the X environment (Graphical user interface), since both of my Pis are running a Tkinter GUI. That's why I went for the lxsession based autostart solution. Using the .bashrc file to start my python code failed, since it looked like the .bashrc is called twice on boot.
So what solved my issue was, to use a shell script to start the python code on bootup from a lxterminal.
In order to do this:
Create a shell script in your home directory (the tilde ~ directory)
pi#raspberrypi:~ $ nano start.sh
and add the hashbang as well as the command to start your python script
#!/bin/sh
sudo python ~/Your/file/here.py
Edit the user LX autostart file like:
sudo nano ~/.config/lxsession/LXDE-pi/autostart
and add the call for the lxterminal including your shell script like
#lxterminal -e ./start.sh
Finally, for my application I had to grant access rights to everyone
chmod 775 start.sh
and use global file paths for all images, like
/home/Documents/Your/files/here.png
Save everything and reboot your pi. Now Everything should boot up perfectly.
Thank you all for helping me, especially Hannu!
Related
So I am trying to learn the PyFirmata module of python that allows us to write codes in Python and upload it to an Arduino Board.
I am learning it from this website.
Code that causes the inbuilt LED to blink:
import pyfirmata
import time
board = pyfirmata.Arduino('/dev/ttyACM0') #This Line gives error
while True:
board.digital[13].write(1)
time.sleep(1)
board.digital[13].write(0)
time.sleep(1)
But, When I run it( in Sublime Text 3) , I get this error:
raise SerialException("could not open port {!r}: {!r}".format(self.portstr, ctypes.WinError()))
serial.serialutil.SerialException: could not open port '/dev/ttyACM0': FileNotFoundError(2, 'The
system cannot find the path specified.', None, 3)
[Finished in 7.0s]
Can Anyone help me to fix this error?
The port you are trying to access doesn't exist or your program doesn't have permission to access it.
First checkout whether the port exist or not. If you have Arduino software installed, you can check from it. In case it's missing, another port should appear, smth like /dev/ttyACM*, where * is any number. Choose it and try running.
In case it exists, but the program still doesn't work visit the official arduino site.
This problem is solved in two command. Open terminal and type:
ls -l /dev/ttyACM*
Then you'll get something like this:
crw-rw---- 1 root dialout 188, 0 5 apr 23.01 ttyACM0
Here what we need is dialout. After the above command, type the below command, and the restart your device.
sudo usermod -a -G your_username
This should work, but there are cases, when it doesn't. Then you need to add your port to root access:
=============================================================================
cd ~/etc/udev/rules.d
In this directory, create a new .rules file and add the following to it:
KERNEL=="ttyACM0", MODE="0666"
This should work.
I got this error message sublime issue(My OS: Ubuntu 16.04) "socket.error: [Errno 98] Address already in use" If I run flask in sublime text or PyCharm. But if I run flask on my Ubuntu terminal,it is running. I understood that port used another service. Then i was trying to solve this issue from google/stackoverflow.
# ps ax | grep 5000 // or # ps ax | grep name_of_service
# kill 3750 // or # killall name_of_service
But nothing changed. Only i found this problem when i was trying to run on sublime or pycharm IDE.
Simple way is to use fuser.
fuser <yourport>/tcp #this will fetch the process/service
Replace <yourport> with the port you want to use
#to kill the process using <yourport> add `-k` argument
fuser <yourport>/tcp -k
In your case
fuser 5000/tcp -k
Now you can run flask with that port.
Pycharm allows you to edit the run configuration, so enter the configuration and check the box (top-right corner) saying: "singleton instance". In this way, every time you restart the server, the previous connection on port 5000 is closed and opened again.
I'm trying to open Tcpdump to capture UDP packets from a Python script. Here is my code:
os.system("tcpdump -i wlp2s0 -n dst 8.8.8.8 -w decryptedpackets.pcap &")
testfile = urllib.URLopener()
s = socket(AF_INET, SOCK_DGRAM)
host = "8.8.8.8"
port = 5000
buf = 1024
addr = (host, port)
s.connect((host, port))
f = open("file.txt", "rb")
data = f.read(buf)
while (data):
if (s.sendto(data, addr)):
print "sending ..."
data = f.read(buf)
I am able to capture the packets (pcap file has content) if I manually execute this command in shell:
tcpdump -i wlp2s0 -n dst 8.8.8.8 -w decryptedpackets.pcap &
However, If I use os.system() I can't capture the packets. ( When I open the pcap file, I find it empty)
I have verified and found that there is a process that gets created when the Python script is executed:
root 10092 0.0 0.0 17856 1772 pts/19 S 10:25 0:00
tcpdump -i wlp2s0 -n dst 8.8.8.8 -w decryptedpackets.pcap
Also, I'm running this as a sudo user to avoid any permission problems.
Any suggestions what could be causing this problem ?
From python documentation.
os.system(command) Execute the command (a string) in a subshell. This
is implemented by calling the Standard C function system(), and has
the same limitations. Changes to sys.stdin, etc. are not reflected in
the environment of the executed command.
On Unix, the return value is the exit status of the process encoded in
the format specified for wait(). Note that POSIX does not specify the
meaning of the return value of the C system() function, so the return
value of the Python function is system-dependent.
On Windows, the return value is that returned by the system shell
after running command, given by the Windows environment variable
COMSPEC: on command.com systems (Windows 95, 98 and ME) this is always
0; on cmd.exe systems (Windows NT, 2000 and XP) this is the exit
status of the command run; on systems using a non-native shell,
consult your shell documentation.
The subprocess module provides more powerful facilities for spawning
new processes and retrieving their results; using that module is
preferable to using this function. See the Replacing Older Functions
with the subprocess Module section in the subprocess documentation for
some helpful recipes.
I think that os.system returns immediately and the script keeps going, there's no problem with the code but you probably need to create a separate thread and call os.system with the tcp-dump since I believe that it is returning immediately.
did you use the -w switch too when running from the command line instead of the script? If not your problem might be buffering and you should have a look at the -U option. Apart from that the -w switch should be used before the capture expression, i.e. the expression should be the last thing. In summary: tcpdump -i wlp2s0 -n -w out.pcap -U dst 8.8.8.8
– Steffen Ullrich
How can I doc a specific terminal window on my Mac ( OS X 10.9.2) that upon clicking executes my python program from within shell script?
In my job.sh file I have this:
#!/bin/bash
python python_script.py
This is what I have in my python_script.py file:
import SimpleHTTPServer
import SocketServer
PORT = 8000
Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)
print "serving at port", PORT
httpd.serve_forever()
Basically I don't want to have to open up my terminal window, type ./job.sh and run the command, I want my terminal window to run ./job.sh by default just by clicking it.
You can just put the command in your .profile or .bash_profile or .bashrc file:
echo 'python python_script.py' >> ~/.profile
# or
# echo '/path/to/job.sh' >> ~/.profile
When you open up a new terminal, the .profile file will be sourced and your job will be run.
Note: Command to be put into the file is python python_script.py or /path/to/job.sh
Figured it out! It was the .bash_profile file in my case(OS X) that needed the
'python python_script.py' >> ~/.bash_profile
command executed as my .profile is overlooked due to the order in which bash profile files are read. For anyone who has no idea about this(like me until today), definitely checkout http://hayne.net/MacDev/Notes/unixFAQ.html#shellStartup
The accepted answer for this question led me there, https://apple.stackexchange.com/questions/12993/why-doesnt-bashrc-run-automatically
After that, it was simply a matter of being in the right directory to execute the script.
Also be careful and make sure to properly exit out of your server(ctrl-c) when your done, as I closed out the workspace by accident before and it led to process being bound to the default port and kept giving me an error which was solved by this.
socket.error: [Errno 48] Address already in use
When trying to run python bottle on port 80 I get the following:
socket.error: [Errno 10013] An attempt was made to access a socket in a way forb
idden by its access permissions
My goal is to run the web server on port 80 so the url's will be nice and tidy without any need to specify the port
for example:
http://localhost/doSomething
instead of
http://localhost:8080/doSomething
Any ideas?
Thanks
Exactly as the error says. You need to have permissions to run something on the 80th port, normal user cannot do it. You can execute the bottle webapp as root (or maybe www-data) and it should be fine as long as the port is free.
But taking security (and stability) into consideration you should look at different ways of deployment, for example nginx together with gunicorn.
Gunicorn Docs
Nginx Docs
Check your system's firewall setting.
Check whether another application already use port 80 using following commands:
On unix: netstat -an | grep :80
On Windows: netstat -an | findstr :80
According to Windows Sockets Error Codes:
WSAEACCES 10013
Permission denied.
An attempt was made to access a socket in a way forbidden by its
access permissions. An example is using a broadcast address for sendto
without broadcast permission being set using setsockopt(SO_BROADCAST).
Another possible reason for the WSAEACCES error is that when the bind
function is called (on Windows NT 4.0 with SP4 and later), another
application, service, or kernel mode driver is bound to the same
address with exclusive access. Such exclusive access is a new feature
of Windows NT 4.0 with SP4 and later, and is implemented by using the
SO_EXCLUSIVEADDRUSE option.
Sometimes dont need to want install nginx, python with gunicorn is a viable alternative with supervisor but you need to make lot of tricks for working
i assume you know install supervisor, and later install again requirements
pip3 install virtualenv
mkdir /home/user/.envpython
virtualenv /home/user/.envpython/bin/activate
source /home/user/.envpython/bin/activate
cd /home/user/python-path/
pip3 install -r requirements
create a supervisor file like that
nano /etc/supervisord.d/python-file.conf
and edit with this example, edit the program that you need, remember the python3 run in other ports > 1024
;example with path python supervisor in background
[program:python]
environment=HOME="/home/user",USER="user"
user=user
directory = /home/user/python-path
command = python3 /home/user/python-path/main.py
priority = 900
autostart = true
autorestart = true
stopsignal = TERM
;redirect_stderr = true
stdout_logfile = /home/user/.main-python-stdout.log
stderr_logfile = /home/user/.main-python-stderr.log
;example with path python gunicorn supervisor and port 80
[program:gunicorn]
;environment=HOME="/home/user",USER="user"
;user=user
directory = /home/user/python-path
command = bash /home/user/.scripts/supervisor-initiate.sh
priority = 900
autostart = true
autorestart = true
stopsignal = TERM
;redirect_stderr = true
stdout_logfile = /home/user/.main-python-stdout.log
stderr_logfile = /home/user/.main-python-stderr.log
and create the file
nano /home/user/.scripts/supervisor-initiate.sh
with the following content
source /home/user/.envpython/bin/activate
cd /home/user/python-path
gunicorn -w 1 -t 120 -b 0.0.0.0:80 main:app
i assume you file in python is called main and you initiate the app with flask or django that called "app"
only restart supervisord process
systemctl restart supervisord
and you have the app with gunicorn in the port 80, i post because i find for a very long time for this solution
Waiting works for anyone