Python OSError: [Errno 98] 地址已被使用但未使用任何端口

问题描述

我的代码同时使用烧瓶(http,作为主线程)、ngrok 和 tcp 服务器(ngrok 和 tcp 服务器都在两个线程上运行)有问题(错误消息见下文)

Traceback (most recent call last):
  File "/home/monki/anaconda3/lib/python3.8/threading.py",line 932,in _bootstrap_inner
    self.run()
  File "/home/monki/anaconda3/lib/python3.8/threading.py",line 870,in run
    self._target(*self._args,**self._kwargs)
  File "/home/monki/VSCode/Python/Webhook/app.py",line 49,in launchServer
    s.bind((hostname,TCP_PORT))
OSError: [Errno 98] Address already in use

我已经使用

检查了端口
ps -fA | grep python

发现没有端口被使用

root         910       1  0 15:02 ?        00:00:00 /usr/bin/python3 /usr/bin/networkd-dispatcher --run-startup-triggers
root        1036       1  0 15:02 ?        00:00:00 /usr/bin/python3 /usr/share/unattended-upgrades/unattended-upgrade-shutdown --wait-for-signal
x       6316    5499  0 15:55 pts/0    00:00:00 grep --color=auto python

这是我的代码

from flask import Flask,request,Response
import json
import socket
import threading  
from pyngrok import ngrok

from queue import Queue

#tcp server
TCP_IP = ''
TCP_PORT = 13370
BUFFER_SIZE  = 20

# http server
HOST_URL = 'http://xxx.ngrok.io'


def start_ngrok():
    ### sorry i have to blank out the account
    ngrok.set_auth_token("xxxxxx")
    url = ngrok.connect(5000,subdomain='xxx').public_url
    print(' * Tunnel URL:',url)


def launchServer(out_q):
    print("TCP thread started")
    hostname = socket.gethostname()
    local_ip = socket.gethostbyname(hostname)

    s = socket.socket(socket.AF_INET,socket.soCK_STREAM)
    s.setsockopt(socket.soL_SOCKET,socket.so_REUSEADDR,1)

    s.bind((hostname,TCP_PORT))
    s.listen(1)

    while True:
        print('waiting for a connection')
        conn,addr = s.accept()
        try:
            print(sys.stderr + 'client connected:' + addr)
            while True:
                out_q.put(data)
                data = conn.recv(1024)

                # print >>sys.stderr,'received "%s"' % data
                if data:
                    conn.sendall(data)
                else:
                    break
        finally:
            conn.close()

app = Flask(__name__)

# route deFinition
@app.route('/<webhookAddr>',methods=['POST'])
def response(in_q,webhookAddr):

    if webhookAddr == 'getGithub':
        # data = json.loads(request.data)
        print(request.json)

        in_q.put(request.json)
        return Response(status=200)
    
    elif webhookAddr == 'getGitHub2':
        print(request.json)
        return Response(status=200)
    else:
        return Response(status=200)


if __name__ == '__main__':
   q = Queue()

   t1 = threading.Thread(target=launchServer,args =(q,))
   t1.daemon = True
   t1.start()

   t2 = threading.Thread(target=start_ngrok)
   t2.daemon = False
   t2.start()

   app.run(debug=True)

但是,通过单独运行 launchServer 的代码部分,我不会收到这样的错误。我是否错误地使用了 ngrok。需要你的帮助指出我的错误

问候

解决方法

也许你的 5000 端口已经被其他进程占用了。 试试 netstat

netstat -anp  | grep 5000
,

这个问题也在我这边重现。从调试 Flask 代码来看,在调试模式下似乎没有使用 SO_REUSEADDR,因此下次尝试绑定相同的地址(您的 tcp 服务器)将失败。一种选择是关闭调试模式:

app.run(debug=False)

另一种选择是关闭重载器(如果您在服务器运行时修改应用程序,重载器很好):

app.run(debug=True,use_reloader=False)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...