Python 소켓 오류 48란?
소켓 오류 48(Socket Error 48)은 파이썬에서 프로세스가 이미 사용 중인 포트에 바인딩을 시도할 때 발생하는 오류입니다. 실제 화면에는 보통 다음과 같은 메시지로 나타납니다.
socket.error: [Errno 48] Address already in use
"socket.error: [Errno 48] Address already in use" 오류의 원인
원인을 분석한 결과, 핵심은 다음과 같습니다.
- 프로세스의 포트 바인딩: 서버에서 프로세스가 생성될 때마다 인터넷과 통신하기 위해 포트가 사용됩니다. 포트는 한 번에 한 명의 손님만 맞이할 수 있는 호스트와 같아서, 두 개의 프로세스가 동시에 같은 포트를 사용할 수 없습니다. 포트를 별도로 지정하지 않으면 서버는 기본 포트(default port)를 사용하는데, 다음 프로세스를 생성할 때는 기본 포트가 이미 점유되어 있으므로 반드시 다른 포트를 지정해야 합니다.
해결 방법 1: 포트 번호 직접 지정하기
이 오류는 대부분 특정 프로세스를 기본 포트에 바인딩하려는데, 그 포트가 이미 다른 프로세스에 의해 사용 중일 때 발생합니다. 따라서 이번 단계에서는 프로세스를 바인딩할 포트를 직접 지정하는 방법을 알아보겠습니다.
- 아마도 다음 명령어로 프로세스를 생성하고 있을 가능성이 높습니다.
$ python -m SimpleHTTPServer
- 대신 아래처럼 포트 번호를 함께 입력하여 프로세스를 생성합니다.
$ python -m SimpleHTTPServer (포트 번호)
- 프로세스가 생성될 때까지 기다린 후, 문제가 계속 발생하는지 확인합니다.
참고: SimpleHTTPServer는 파이썬 2 전용 모듈입니다. 파이썬 3 환경이라면 다음과 같이 http.server 모듈을 사용하세요.
$ python -m http.server (포트 번호)
해결 방법 2: 포트 확보하기 (기존 프로세스 종료)
포트가 이미 다른 프로세스에 의해 사용 중이라면 새 프로세스는 해당 포트에서 작동할 수 없습니다. 따라서 이번에는 기존 프로세스를 종료해 포트를 비운 뒤, 새 프로세스를 실행하는 방법을 알아보겠습니다.
- 다음 명령어를 사용하면 특정 포트를 사용 중인 파이썬 프로세스 목록을 확인할 수 있습니다.
$ ps -fA | grep python
- 명령어 출력 결과는 대략 다음과 같은 형태로 표시됩니다.
601 88234 12788 0 9:53PM ttys000 0:00.16 python -m SimpleHTTPServer
- 여기서 종료할 프로세스 ID(PID)는 "88234"입니다.
- 다음 명령어로 해당 프로세스를 종료합니다.
kill 88234
강제 종료가 필요한 경우에는 다음 명령어를 사용할 수도 있습니다.
sudo kill -9 PID
- 이제 다음 명령어로 프로세스를 해당 포트에 바인딩합니다.
$ python -m SimpleHTTPServer (포트 번호)
- 프로세스가 정상적으로 생성되는 것을 확인할 수 있습니다.
해결 방법 3: 라즈베리파이 재시작 (라즈베리파이 전용)
라즈베리파이(Raspberry Pi)에서는 기기를 재시작하거나 터미널 셸을 종료하는 것만으로도 이 오류를 해결할 수 있는 경우가 많습니다. 라즈베리파이는 가끔 프로세스를 자동으로 종료하지 못하는데, 이때 포트에 이미 실행 중인 이전 프로세스들이 남아 있어 이 오류가 발생하게 됩니다.
추가 팁: SO_REUSEADDR 옵션 활용하기
직접 소켓 프로그래밍을 한다면 SO_REUSEADDR 옵션을 설정하는 것이 좋습니다. 이 옵션을 사용하면 이전 연결이 TIME_WAIT 상태로 남아 있어도 포트를 즉시 재사용할 수 있어, 오류 48을 사전에 예방하는 데 큰 도움이 됩니다.
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('0.0.0.0', 8080))
마무리
소켓 오류 48은 "포트 충돌"만 이해하면 매우 간단히 해결되는 문제입니다. 새 프로세스를 실행할 때는 항상 고유한 포트 번호를 지정하고, 불필요한 기존 프로세스는 미리 종료해 두는 습관을 들이면 이런 오류를 효과적으로 예방할 수 있습니다.