Skip to content

Instantly share code, notes, and snippets.

@betrcode
Created June 24, 2014 06:36
Show Gist options
  • Save betrcode/0248f0fda894013382d7 to your computer and use it in GitHub Desktop.
Save betrcode/0248f0fda894013382d7 to your computer and use it in GitHub Desktop.
Using Python to check if remote port is open and accessible.
import socket
def isOpen(ip,port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((ip, int(port)))
s.shutdown(2)
return True
except:
return False
@XerionXavier
Copy link

XerionXavier commented Sep 10, 2019

Yes an old thread but still usefull. Can anyone shed some light as to how you can have multiple hosts that it polls until the app is exited?
as in..
domain1.com host id UP
domain2.com host id UP
domain3.com host id DOWN
domain4.com host id UP

What Im using so far...

#!/usr/bin/python3
import sys
import socket
import time

ip = "domain.com"
port = 443
retry = 1
delay = 1
timeout = 2

def isOpen(ip, port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((ip, int(port)))
s.shutdown(2)
return True
except:
return False

def checkHost(ip, port):
ipup = False
for i in range(retry):
if isOpen(ip, port):
ipup = True
break
else:
time.sleep(delay)
return ipup

if checkHost(ip, port):
print ip + " port " + str(port) + u" is \u001b[32;1mUP!\u001b[0m"

else:
print ip + " port " + str(port) + u" is \u001b[31;1mDOWN!\u001b[0m"

@shaozi
Copy link

shaozi commented Jan 30, 2020

An async version:

async def wait_host_port(host, port, duration=10, delay=2):
    """Repeatedly try if a port on a host is open until duration seconds passed
    
    Parameters
    ----------
    host : str
        host ip address or hostname
    port : int
        port number
    duration : int, optional
        Total duration in seconds to wait, by default 10
    delay : int, optional
        delay in seconds between each try, by default 2
    
    Returns
    -------
    awaitable bool
    """
    tmax = time.time() + duration
    while time.time() < tmax:
        try:
            _reader, writer = await asyncio.wait_for(asyncio.open_connection(host, port), timeout=5)
            writer.close()
            await writer.wait_closed()
            return True
        except:
            if delay:
                await asyncio.sleep(delay)
    return False

@michaeloliverx
Copy link

An async version:

async def wait_host_port(host, port, duration=10, delay=2):
    """Repeatedly try if a port on a host is open until duration seconds passed
    
    Parameters
    ----------
    host : str
        host ip address or hostname
    port : int
        port number
    duration : int, optional
        Total duration in seconds to wait, by default 10
    delay : int, optional
        delay in seconds between each try, by default 2
    
    Returns
    -------
    awaitable bool
    """
    tmax = time.time() + duration
    while time.time() < tmax:
        try:
            _reader, writer = await asyncio.wait_for(asyncio.open_connection(host, port), timeout=5)
            writer.close()
            await writer.wait_closed()
            return True
        except:
            if delay:
                await asyncio.sleep(delay)
    return False

Thanks this is EXACTLY what I was looking for.

@UmutAlihan
Copy link

An async version:

async def wait_host_port(host, port, duration=10, delay=2):
    """Repeatedly try if a port on a host is open until duration seconds passed
    
    Parameters
    ----------
    host : str
        host ip address or hostname
    port : int
        port number
    duration : int, optional
        Total duration in seconds to wait, by default 10
    delay : int, optional
        delay in seconds between each try, by default 2
    
    Returns
    -------
    awaitable bool
    """
    tmax = time.time() + duration
    while time.time() < tmax:
        try:
            _reader, writer = await asyncio.wait_for(asyncio.open_connection(host, port), timeout=5)
            writer.close()
            await writer.wait_closed()
            return True
        except:
            if delay:
                await asyncio.sleep(delay)
    return False

While reading this, I had tears of joy. Many thanks!

@shaozi
Copy link

shaozi commented Jun 4, 2021

@leafonsword
Copy link

Very good, replace ping command,haha!

@michaelg68
Copy link

Thank you very much. Works out of the box :)

@AveragePythonEnjoyer29
Copy link

Small note, this can be sped up by using connect_ex instead of connect. The first call will not raise any exceptions (except for No host found, but that's standard) and is faster than the second one. Example:

def isOpen(ip, port):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(5)

    try:
        is_open = s.connect_ex((ip, int(port))) == 0 # True if open, False if not

        if is_open:
            s.shutdown(socket.SHUT_RDWR)

    except Exception:
        is_open = False

    s.close()

    return is_open

@caimaoy
Copy link

caimaoy commented Feb 2, 2023

An async version:

async def wait_host_port(host, port, duration=10, delay=2):
    """Repeatedly try if a port on a host is open until duration seconds passed
    
    Parameters
    ----------
    host : str
        host ip address or hostname
    port : int
        port number
    duration : int, optional
        Total duration in seconds to wait, by default 10
    delay : int, optional
        delay in seconds between each try, by default 2
    
    Returns
    -------
    awaitable bool
    """
    tmax = time.time() + duration
    while time.time() < tmax:
        try:
            _reader, writer = await asyncio.wait_for(asyncio.open_connection(host, port), timeout=5)
            writer.close()
            await writer.wait_closed()
            return True
        except:
            if delay:
                await asyncio.sleep(delay)
    return False

Thank you for the code. It works, but in python3.6, I get an exception like this 'StreamWriter' object has no attribute 'wait_closed'. Could you tell me how to fix it. Please

@alexdelprete
Copy link

Small note, this can be sped up by using connect_ex instead of connect. The first call will not raise any exceptions (except for No host found, but that's standard) and is faster than the second one. Example:

Thanks for sharing this Oscar.

@suspiciousRaccoon
Copy link

An async version:

async def wait_host_port(host, port, duration=10, delay=2):
    """Repeatedly try if a port on a host is open until duration seconds passed
    
    Parameters
    ----------
    host : str
        host ip address or hostname
    port : int
        port number
    duration : int, optional
        Total duration in seconds to wait, by default 10
    delay : int, optional
        delay in seconds between each try, by default 2
    
    Returns
    -------
    awaitable bool
    """
    tmax = time.time() + duration
    while time.time() < tmax:
        try:
            _reader, writer = await asyncio.wait_for(asyncio.open_connection(host, port), timeout=5)
            writer.close()
            await writer.wait_closed()
            return True
        except:
            if delay:
                await asyncio.sleep(delay)
    return False

Thank you for the code. It works, but in python3.6, I get an exception like this 'StreamWriter' object has no attribute 'wait_closed'. Could you tell me how to fix it. Please

the .wait_closed() method was added in python 3.7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment