Python进程阻塞套接字[Errno 98]

时间:2018-01-03 12:00:14

标签: python sockets

我正在运行两个相互连接的raspis。他们都在启动时运行程序(启动正常)。 但是,我在后台不断收到error: [Errno 98] Address already in use错误,并且两个Pis之间的通信甚至都没有启动。

我去追踪通过ps -fA ¦ grep python和tadaaa运行的python进程,我可以看到,另一个进程开始尝试使用相同的地址。 ps的输出如下:

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

据我所知,看起来同样的进程(3_multithread.py)被调用两次(一次是su,一次不是su)。

编辑#2:我通过.bashrc(sudo python /home/pi/Documents/3_multithread.py)和lxsession启动程序。这可能是阻止地址的原因吗?

错误日志如下:

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

我还检查了netstat -lptn。我得到以下输出:

tcp        0     0 0.0.0.0:22           0.0.0.0.*          LISTEN     -
编辑#123:我进一步追踪错误。我导入并打印了:

import os
os.getpid()

获取进程PID。现在发生的事情是:在启动时,我的脚本返回PID 754,而ps -fA ¦ grep python仅统计两个带有PID 535539的python进程。 .bashrclxterminal是否会启动该流程两次?

这是我在python脚本中配置我的套接字的方法

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

我正在使用全局变量来发送命令以将命令发送到另一个Pi,这非常完美(一旦建立连接)。

非常感谢你们! 最诚挚的问候, 托比

1 个答案:

答案 0 :(得分:1)

所以我最终能够解决这个问题。

正如Hannu首先提出的那样,问题在于我启动系统的方式。首先,我想做什么?

我需要将Raspis启动到X环境(图形用户界面),因为我的两个Pis都在运行Tkinter GUI。这就是我选择基于lxsession的自动启动解决方案的原因。使用.bashrc文件启动我的python代码失败,因为看起来.bashrc在启动时被调用了两次。 所以解决了我的问题是,使用shell脚本从lxterminal启动启动python代码。

为了做到这一点:

  1. 在您的主目录(波浪号〜目录)中创建一个shell脚本

    pi@raspberrypi:~ $ nano start.sh

  2. 并添加hashbang以及启动python脚本的命令

    #!/bin/sh
    sudo python ~/Your/file/here.py
    
    1. 编辑用户LX自动启动文件,如:

      sudo nano ~/.config/lxsession/LXDE-pi/autostart

    2. 并添加对lxterminal的调用,包括你的shell脚本,如

      @lxterminal -e ./start.sh
      

      最后,对于我的应用程序,我必须向所有人授予访问权限

      chmod 775 start.sh
      

      并为所有图像使用全局文件路径,例如

      /home/Documents/Your/files/here.png
      

      保存所有内容并重启你的pi。现在一切都应该完美启动。 谢谢大家的帮助,尤其是Hannu!