Python Forum
testing for a network connection
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
testing for a network connection
#1
my function gets an open file with a write method. what's the simplest way to test if it is a network connection that is connected?
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#2
I don't know if this is possible in general, but it looks like bad design. Friendly python functions that receive a file with a write() method will usually accept any file-like object and will never try to guess what's beyond the write method. I think if you need the information, give the responsibility to the caller and change the signature to
def flood_with_spam(file, is_network):
    pass
Reply
#3
Quote:what's the simplest way to test if it is a network connection that is connected?

I had done this kind of task.
Situation: There is a device, which connects to wifi, then it should check if the device can reach the default gateway (router IP) or if it's in "online-mode", it should check a known IP in internet.

This was my preparation to obtain local IPs and the gateway IP with two different solutions.
One solution is using iproute2 (ip command, which can return json) or netifaces which works also on Windows.

Code: https://pastebin.com/yqcAQGyh


Example code which works only on my machine ^^
import json
from socket import gethostbyname, gaierror
from subprocess import check_output, call, DEVNULL


OK = "✓"
FAIL = "✗"


def get_default_gateways():
    cmd = ["ip", "-j", "-4", "r", "s", "default"]
    result = json.loads(check_output(cmd, encoding="utf8"))
    return [res.get("gateway", "") for res in result]


def ping_ip(ip):
    return call(["ping", "-c1", "-W1", ip], stdout=DEVNULL, stderr=DEVNULL) == 0


def check_dns():
    try:
        gethostbyname("google.com")
    except OSError:
        return False
    else:
        return True


if __name__ == "__main__":
    result = False
    gateways = get_default_gateways()
    if gateways:
        result = ping_ip(gateways[0])
    if result:
        print(f"[{OK}] Gateway")
    else:
        print(f"[{FAIL}] Gateway")

    if ping_ip("1.1.1.1"):
        print(f"[{OK}] Internet")
    else:
        print(f"[{FAIL}] Internet")

    if check_dns():
        print(f"[{OK}] DNS")
    else:
        print(f"[{FAIL}] DNS")
Obviously I'm online:
Output:
[✓] Gateway [✓] Internet [✓] DNS
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#4
as for the design issues, i do try to make commands and APIs give more detailed and intelligent response codes and error messages than just letting things fail where they may. i do not agree with the idea of requiring the user to be sure things are correct (user in the case of an API being the programmer of the calling program).
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#5
I understand that you want intelligent APIs but what I mean is that you are doing something unnatural when you're extracting information from a file object other than the information that can be obtained from the file object's documented attributes and methods. If the function wants to act differently depending on whether the file object is connected to the internet or not, it means that the file object is only an item of a more general context and the function should receive contextual elements in its arguments besides the pointer to file, or perhaps be a method of some class that provides these contextual elements. Alternately, the file object could be an instance of a specialized class containing thîs extra context.

May be it's just me.
Reply
#6
Don't try to solve it with checking everything before.
Work with timeouts. Set the timeout to your socket, then it will throw a socket.timeout exception if you try to read a file and the read took longer than the timeout.

import socket


def read(fd):
    try:
        fd.read(1)
    except socket.timeout:
        print("Read timed out")


s = socket.socket()
s.settimeout(10) # 10 seconds
s.connect(("google.com", 80))
f = s.makefile()

# will fail
read(f)
Regular files won't throw a socket.timeout.
I hope this is a better answer.

By the way, how do you check if a socket is still connected?
I think there is no safe method.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020