본문 바로가기

개발하자

Python을 사용하여 포트가 사용 중인지 여부를 테스트하는 빠른 방법

반응형

Python을 사용하여 포트가 사용 중인지 여부를 테스트하는 빠른 방법

나는 몇 개의 소켓에서 수신하는 파이썬 서버를 가지고 있다. 시작할 때 듣기 전에 이 소켓에 연결하려고 하므로 다른 포트가 이미 사용되고 있지 않은지 확인할 수 있습니다. 이것은 내 서버의 시작에 약 3초를 추가하며(테스트 없이 약 0.54초), 나는 그것을 줄이고 싶다. 로컬 호스트만 테스트하기 때문에 약 50밀리초의 시간 초과는 충분하다고 생각합니다. 불행하게도, 소켓.setdefaulttimeout(50) 메서드가 어떤 이유로 작동하지 않는 것 같습니다.

어떻게 해야 이걸 줄일 수 있을까요?




원하는 포트에 바인딩하고 포트가 사용 중인 경우 오류 사례를 처리하는 것은 어떨까요? (문제가 같은 서비스를 두 번 시작할 수 있는 경우 열려 있는 포트를 보지 마십시오.)

이것은 @eemz가 다른 답변에서 말했듯이 인종 문제를 일으키지 않기 위한 합리적인 방법이기도 하다.




Linux를 사용하고 있나요? 그렇다면 응용 프로그램을 실행하여(또는 UDP를 사용하는 경우) 사용 중인 포트를 확인할 수 있습니다. 이게 더 빠를 거야...




사이먼 B의 대답은 선택할 수 있는 방법이다. 아무것도 확인하지 말고, 이미 사용 중인 오류 사례를 바인딩하고 처리하도록 하라.

그렇지 않으면 다른 앱이 포트를 잡을 수 있는 레이스 상태에서 무료인지 확인하고 이후 포트에 바인딩을 시도할 수 있습니다. 즉, 바인딩 호출이 실패할 가능성을 처리해야 하므로 사전 확인을 통해 아무것도 얻을 수 없습니다.




다음은 포트가 확보되었는지 확인하는 방법의 예입니다.

import socket, errno

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:
    s.bind(("127.0.0.1", 5555))
except socket.error as e:
    if e.errno == errno.EADDRINUSE:
        print("Port is already in use")
    else:
        # something else raised the socket.error exception
        print(e)

s.close()



포트 사용을 확인하려면:

def is_port_in_use(port: int) -> bool:
    import socket
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        return s.connect_ex(('localhost', port)) == 0

출처:

connect_ex는 여전히 예외를 제기할 수 있습니다(잘못된 호스트 이름의 경우, [1]의 문서 참조).

[1]




포트를 확인하는 Python 2 코드가 사용 중인지 여부를 확인합니다

# python 2
import socket

def check_port(port):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    res = sock.connect_ex(('localhost', port))
    sock.close()
    return res == 0

확인.




사용 가능한/사용된 포트 확인

def check_port(port):
    import socket, errno
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:        
        s.bind(("127.0.0.1", port))
    except socket.error as e:
        if e.errno == errno.EADDRINUSE:
            print("Port is already in use", port)
        else:
            print(e)
            print(f"****Port: {port} cannot be acessed****")
            return False
    s.close()
    return True

# Check port open for range of ports
for i in range (10000):
    check_port(i)

반응형