fix: 서버 시작 시 포트 충돌 자동 해결
- 포트 7001 사용 중이면 기존 프로세스 자동 종료 - Flask reloader 자식 프로세스 구분 처리 - check_port_available(), kill_process_on_port() 함수 추가
This commit is contained in:
@@ -3151,6 +3151,54 @@ def api_qr_preview():
|
||||
return jsonify({'success': False, 'error': str(e)}), 500
|
||||
|
||||
|
||||
def check_port_available(port: int) -> bool:
|
||||
"""포트가 사용 가능한지 확인"""
|
||||
import socket
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.settimeout(1)
|
||||
result = sock.connect_ex(('127.0.0.1', port))
|
||||
sock.close()
|
||||
return result != 0 # 0이면 이미 사용 중, 0이 아니면 사용 가능
|
||||
|
||||
|
||||
def kill_process_on_port(port: int) -> bool:
|
||||
"""특정 포트를 사용하는 프로세스 종료 (Windows)"""
|
||||
import subprocess
|
||||
try:
|
||||
# netstat으로 PID 찾기
|
||||
result = subprocess.run(
|
||||
f'netstat -ano | findstr ":{port}"',
|
||||
shell=True, capture_output=True, text=True
|
||||
)
|
||||
|
||||
for line in result.stdout.strip().split('\n'):
|
||||
if 'LISTENING' in line:
|
||||
parts = line.split()
|
||||
pid = parts[-1]
|
||||
if pid.isdigit():
|
||||
subprocess.run(f'taskkill /F /PID {pid}', shell=True)
|
||||
logging.info(f"포트 {port} 사용 중인 프로세스 종료: PID {pid}")
|
||||
return True
|
||||
return False
|
||||
except Exception as e:
|
||||
logging.error(f"프로세스 종료 실패: {e}")
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import os
|
||||
|
||||
PORT = 7001
|
||||
|
||||
# Flask reloader 자식 프로세스가 아닌 경우에만 체크
|
||||
if os.environ.get('WERKZEUG_RUN_MAIN') != 'true':
|
||||
if not check_port_available(PORT):
|
||||
logging.warning(f"포트 {PORT}이 이미 사용 중입니다. 기존 프로세스를 종료합니다...")
|
||||
if kill_process_on_port(PORT):
|
||||
import time
|
||||
time.sleep(2) # 프로세스 종료 대기
|
||||
else:
|
||||
logging.error(f"포트 {PORT} 해제 실패. 수동으로 확인하세요.")
|
||||
|
||||
# 개발 모드로 실행
|
||||
app.run(host='0.0.0.0', port=7001, debug=True)
|
||||
app.run(host='0.0.0.0', port=PORT, debug=True)
|
||||
|
||||
Reference in New Issue
Block a user