mirror of
https://github.com/CopterExpress/clever-show.git
synced 2026-05-26 07:07:58 +00:00
89 lines
3.1 KiB
Python
89 lines
3.1 KiB
Python
import socket
|
|
import logging
|
|
import platform
|
|
|
|
def str_peername(peername):
|
|
if peername is None:
|
|
return "None"
|
|
return f"{peername[0]}:{peername[1]}"
|
|
|
|
|
|
def get_ip_address(): # dodo async
|
|
"""
|
|
Returns the IP address of current computer or `localhost` if no network connection present.
|
|
|
|
Returns:
|
|
string: IP address of current computer or `localhost` if no network connection present
|
|
"""
|
|
ip_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # TODO IPv6
|
|
try:
|
|
ip_socket.connect(("8.8.8.8", 80))
|
|
ip = ip_socket.getsockname()[0]
|
|
except OSError as e:
|
|
logging.warning(f"No network connection detected, using localhost: {e}")
|
|
ip = "localhost"
|
|
finally:
|
|
ip_socket.close()
|
|
return ip
|
|
|
|
|
|
def get_ntp_time(ntp_host, ntp_port):
|
|
"""
|
|
Gets and returns time from specified host and port of NTP server.
|
|
|
|
Args:
|
|
ntp_host (string): hostname or address of the NTP server.
|
|
ntp_port (int): port of the NTP server.
|
|
|
|
Returns:
|
|
int: Current time recieved from the NTP server
|
|
"""
|
|
NTP_DELTA = 2208988800 # 1970-01-01 00:00:00
|
|
NTP_QUERY = b'\x1b' + bytes(47)
|
|
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as ntp_socket:
|
|
ntp_socket.sendto(NTP_QUERY, (ntp_host, ntp_port))
|
|
msg, _ = ntp_socket.recvfrom(1024)
|
|
return int.from_bytes(msg[-8:], 'big') / 2 ** 32 - NTP_DELTA
|
|
|
|
|
|
def set_keepalive(sock, after_idle_sec=1, interval_sec=3, max_fails=5):
|
|
"""
|
|
Sets `keepalive` parameters of given socket.
|
|
|
|
Args:
|
|
sock (socket): Socket which parameters will be changed.
|
|
after_idle_sec (int, optional): Start sending keepalive packets after this amount of seconds. Defaults to 1.
|
|
interval_sec (int, optional): Interval of keepalive packets in seconds. Defaults to 3.
|
|
max_fails (int, optional): Count of fails leading to socket disconnect. Defaults to 5.
|
|
|
|
Raises:
|
|
NotImplementedError: for unknown platform.
|
|
"""
|
|
current_platform = platform.system() # could be empty
|
|
|
|
if current_platform == "Linux":
|
|
return _set_keepalive_linux(sock, after_idle_sec, interval_sec, max_fails)
|
|
if current_platform == "Windows":
|
|
return _set_keepalive_windows(sock, after_idle_sec, interval_sec)
|
|
if current_platform == "Darwin":
|
|
return _set_keepalive_osx(sock, interval_sec)
|
|
|
|
raise NotImplementedError
|
|
|
|
|
|
def _set_keepalive_linux(sock, after_idle_sec, interval_sec, max_fails):
|
|
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
|
|
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, after_idle_sec)
|
|
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, interval_sec)
|
|
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, max_fails)
|
|
|
|
|
|
def _set_keepalive_windows(sock, after_idle_sec, interval_sec):
|
|
sock.ioctl(socket.SIO_KEEPALIVE_VALS, (1, after_idle_sec * 1000, interval_sec * 1000))
|
|
|
|
|
|
def _set_keepalive_osx(sock, interval_sec):
|
|
TCP_KEEPALIVE = 0x10
|
|
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
|
|
sock.setsockopt(socket.IPPROTO_TCP, TCP_KEEPALIVE, interval_sec)
|