Python의 stdlib를 사용하여 로컬 IP 주소 찾기
표준 라이브러리만 사용하여 Python 플랫폼에서 로컬 IP 주소(192.168.x.x 또는 10.0.x.x)를 독립적으로 찾으려면 어떻게 해야 합니까?
방금 찾았는데 좀 허술한 것 같은데 *nix에서 시도해 봤고 창문에서 해 봤더니 작동하더라고요.
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
print(s.getsockname()[0])
s.close()
이는 사용자가 인터넷에 접속할 수 있고 로컬 프록시가 없다고 가정합니다.
import socket
socket.gethostbyname(socket.gethostname())
이것은 항상 작동하지 않습니다. return 능 기 니 은 아반 this wons ( always환(이것')127.0.0.1
on machines having the hostname in 에 호스트명이 있는 머신의/etc/hosts
as ~하듯이127.0.0.1
), a paliative would be what gimel shows, use )는 기멜이 보여주는 것이 될 것입니다.socket.getfqdn()
대신.신 물론 시스템이 해결 가능한 호스트 중 하나가 필요합니다.물론 머신에는 해결 가능한 호스트명이 필요합니다.
이 메서드는 로컬박스(디폴트루트가 있는 IP)의 '프라이머리' IP를 반환합니다.
- 라우팅 가능한 네트워크액세스나 접속은 전혀 필요 없습니다.
- 모든 인터페이스가 네트워크에서 분리되어 있어도 동작합니다.
- 다른 곳으로 갈 필요도 없고 가려고도 하지도 않는다.
- NAT, 퍼블릭, 프라이빗, 외부 및 내부 IP와 연동됩니다.
- 외부 종속성이 없는 순수 Python 2(또는 3)입니다.
- Linux, Windows 및 OSX에서 작동합니다.
Python 3 또는 2:
import socket
def get_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.settimeout(0)
try:
# doesn't even have to be reachable
s.connect(('10.254.254.254', 1))
IP = s.getsockname()[0]
except Exception:
IP = '127.0.0.1'
finally:
s.close()
return IP
print(get_ip())
프라이머리 IP(디폴트루트가 있는 IP)가 1개 반환됩니다.대신에, 모든 IP 를 모든 인터페이스(localhost 등)에 접속할 필요가 있는 경우는, 다음과 같은 회답을 참조해 주세요.
자택의 wifi 라우터와 같은 NAT 방화벽의 배후에 있는 경우 퍼블릭 NAT IP가 표시되지 않고 로컬 WIFI 라우터에 대한 디폴트루트가 있는 로컬네트워크상의 프라이빗 IP가 표시됩니다.외부 IP가 필요한 경우:
THAT 외부 디바이스(Wifi 라우터)에서 이 기능을 실행하거나
외부에서 볼 때 IP를 반영할 수 있는 https://www.ipify.org/ 등의 외부 서비스에 연결
하지만 그 아이디어는 원래 질문과는 전혀 다릅니다.:)
As an alias called 라는 별칭으로myip
:
alias myip="python -c 'import socket; print([l for l in ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith(\"127.\")][:1], [[(s.connect((\"8.8.8.8\", 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) if l][0][0])'"
- 현재 IPv4 주소를 찾기 위해 Python 2.x, Python 3.x, 최신 및 구형 Linux Distros, OSX/macOS 및 Windows와 올바르게 작동합니다.
- 복수의 IP 주소, IPv6, 구성된 IP 주소가 없거나 인터넷 액세스가 없는 시스템에 대해 올바른 결과를 반환하지 않습니다.
- 이것은, 최신의 MacOS 릴리스에서는 동작하지 않는 것으로 알려져 있습니다.
메모: Python 프로그램 내에서 이와 같은 것을 사용하는 경우 IPv6를 지원하는 Python 모듈을 사용하는 것이 좋습니다.
위와 동일하지만 Python 코드만:
import socket
print([l for l in ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1], [[(s.connect(('8.8.8.8', 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) if l][0][0])
- IP 주소가 설정되어 있지 않은 경우는, 예외가 발생합니다.
인터넷 접속이 없는 LAN에서도 동작하는 버전:
import socket
print((([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")] or [[(s.connect(("8.8.8.8", 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) + ["no IP found"])[0])
(감사합니다 @cpizza)
배경:
「」를 사용합니다.socket.gethostbyname(socket.gethostname())
중 제가 사용하고 있던 컴퓨터 중 하나가/etc/hosts
중복된 엔트리와 참조가 있습니다. socket.gethostbyname()
할 뿐입니다./etc/hosts
.
의 첫 였습니다.처음 this this 、 가 、 this 、 this 、 starting 、 starting 、 starting 、 starting 、 starting 、 starting 。 모든 주소를 제거하려고 하면"127."
:
import socket
print([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1])
이것은 Linux 및 Windows의 Python 2 및 3에서 작동하지만 여러 네트워크 장치 또는 IPv6에서는 처리되지 않습니다.그러나 최근 Linux 디스트로스에서 동작하지 않게 되어, 대신 이 대체 기술을 사용해 보았습니다..8.8.8.8
'''로53
:
import socket
print([(s.connect(('8.8.8.8', 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1])
다음 의 두 할 수 있는 .myip
에일리어스 Python 에일리어스.
IPv6 가 보급되고 있어, 복수의 네트워크 인터페이스가 있는 서버의 경우, 서드 파티의 Python 모듈을 사용해 IP 주소를 검색하는 것이, 여기에 기재되어 있는 방법보다 견고하고 신뢰할 수 있을 것입니다.
Netifaces 모듈을 사용할 수 있습니다.입력만:
pip install netifaces
기본 Python 설치 시 자동으로 설치됩니다.
그 후 다음과 같이 사용할 수 있습니다.
from netifaces import interfaces, ifaddresses, AF_INET
for ifaceName in interfaces():
addresses = [i['addr'] for i in ifaddresses(ifaceName).setdefault(AF_INET, [{'addr':'No IP addr'}] )]
print '%s: %s' % (ifaceName, ', '.join(addresses))
내 컴퓨터에는 다음과 같이 인쇄되어 있습니다.
{45639BDC-1050-46E0-9BE9-075C30DE1FBC: 192.168.0.100{D43A468B-F3AE-4BF9-9391-4863A4500583}: 10.5.9.207
이 모듈의 작성자는 Windows, UNIX 및 Mac OS X에서 작동해야 한다고 주장합니다.
컴퓨터에 인터넷 루트가 있는 경우 /etc/hosts가 올바르게 설정되어 있지 않은 경우에도 항상 우선 로컬 IP 주소를 가져옵니다.
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('8.8.8.8', 1)) # connect() for UDP doesn't send packets
local_ip_address = s.getsockname()[0]
소켓 API 메서드
https://stackoverflow.com/a/28950776/711085 를 참조해 주세요.
단점:
- 크로스 플랫폼이 아닙니다.
- 인터넷상의 특정 주소의 존재와 관련된 폴백코드가 더 필요합니다.
- NAT의 지원을 받는 경우에도 이 방법은 작동하지 않습니다.
- 아마 (통상 ISP의) DNS 가용성과는 무관하지 않은 UDP 접속을 확립할 수 있다(8.8.8을 사용하는 등의 아이디어는 Google의 (공교롭게도 DNS 서버)
- 행선지 주소는, 미사용이 보증되고 있는 수치 IP 주소와 같이, 도달 불능으로 해 주세요.fakesubdomain.google.com 나 somefakewebsite.com 와 같은 도메인을 사용하지 말아 주세요.지금이나 장래에도, 그 상대에게 스팸 메일을 송신할 수 있습니다.또, 그 과정에서 자신의 네트워크 박스에도 스팸 메일이 송신할 수 있습니다.
리플렉터법
(이것은 로컬 IP 주소에 대한 OP의 질문(예: 192.168)에 대한 답변은 아닙니다.; 퍼블릭 IP 주소를 제공합니다.사용 사례에 따라서는, 보다 바람직한 경우가 있습니다).
다음과 같은 whatismyip.com과 같은 사이트를 쿼리할 수 있습니다(단, API를 사용).
from urllib.request import urlopen
import re
def getPublicIp():
data = str(urlopen('http://checkip.dyndns.com/').read())
# data = '<html><head><title>Current IP Check</title></head><body>Current IP Address: 65.96.168.198</body></html>\r\n'
return re.compile(r'Address: (\d+\.\d+\.\d+\.\d+)').search(data).group(1)
또는 python2를 사용하는 경우:
from urllib import urlopen
import re
def getPublicIp():
data = str(urlopen('http://checkip.dyndns.com/').read())
# data = '<html><head><title>Current IP Check</title></head><body>Current IP Address: 65.96.168.198</body></html>\r\n'
return re.compile(r'Address: (\d+\.\d+\.\d+\.\d+)').search(data).group(1)
장점:
- 이 방법의 장점 중 하나는 크로스 플랫폼입니다.
- 못생긴 NAT(예를 들어 홈라우터) 뒤에서 동작합니다.
단점(및 회피책):
- 이 웹 사이트가 가동되고 포맷이 변경되지 않으며(거의 변경되지 않음), DNS 서버가 작동해야 합니다.장애 발생 시 다른 서드파티 IP 주소 리플렉터를 조회하여 이 문제를 완화할 수 있습니다.
- 여러 리플렉터를 쿼리하지 않는 경우(손상된 리플렉터가 주소가 아니라고 알리는 것을 방지하기 위해) 또는 HTTPS를 사용하지 않는 경우(서버를 가장한 중간자 공격을 방지하기 위해) 공격 벡터 가능성이 있습니다.
편집: 처음에는 이 방법들이 매우 나쁘다고 생각했지만(많은 폴백을 사용하지 않는 한 코드는 앞으로 몇 년 동안 관련이 없을지도 모른다), "인터넷이란 무엇인가?"라는 질문을 던집니다.컴퓨터에는 다양한 네트워크를 가리키는 인터페이스가 여러 개 있을 수 있습니다.토픽에 대한 자세한 설명은 다음 웹 사이트를 참조하십시오.gateways and routes
컴퓨터는, 내부 게이트웨이를 개입시켜 내부 네트워크에 액세스 하거나, 라우터(통상은 케이스)의 게이트웨이를 개입시켜 월드 와이드 Web에 액세스 할 수 있습니다.OP가 요구하는 로컬 IP 주소는 단일 링크층에 대해서만 명확하게 정의되므로 ('네트워크 카드 또는 이더넷케이블' 중 어느 쪽입니까?)를 지정해야 합니다.이 질문에는 여러 개의 고유하지 않은 답변이 제시되어 있을 수 있습니다., 는 (플래그멘테이션이 ) 잘되어 있을 의 경우 할 수 를 경유한 , 「Web」, 「IP」(「」)입니다.
Linux의 경우:
>>> import socket, struct, fcntl
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> sockfd = sock.fileno()
>>> SIOCGIFADDR = 0x8915
>>>
>>> def get_ip(iface = 'eth0'):
... ifreq = struct.pack('16sH14s', iface, socket.AF_INET, '\x00'*14)
... try:
... res = fcntl.ioctl(sockfd, SIOCGIFADDR, ifreq)
... except:
... return None
... ip = struct.unpack('16sH2x4s8x', res)[2]
... return socket.inet_ntoa(ip)
...
>>> get_ip('eth0')
'10.80.40.234'
>>>
다음 모듈을 사용하고 있습니다.
#!/usr/bin/python
# module for getting the lan ip address of the computer
import os
import socket
if os.name != "nt":
import fcntl
import struct
def get_interface_ip(ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915, # SIOCGIFADDR
struct.pack('256s', bytes(ifname[:15], 'utf-8'))
# Python 2.7: remove the second argument for the bytes call
)[20:24])
def get_lan_ip():
ip = socket.gethostbyname(socket.gethostname())
if ip.startswith("127.") and os.name != "nt":
interfaces = ["eth0","eth1","eth2","wlan0","wlan1","wifi0","ath0","ath1","ppp0"]
for ifname in interfaces:
try:
ip = get_interface_ip(ifname)
break;
except IOError:
pass
return ip
단일 IPv4 기반 LAN 시스템에서 사용하기 위해 Windows 및 Linux에서 테스트 완료(추가 모듈은 필요 없음).
Alexander가 지적한 바와 같이 예측 가능한 인터페이스 이름에 관한 systemd v197 변경을 채택한 최신 Linux 버전에서는 인터페이스 이름의 고정 목록이 작동하지 않습니다.이 경우 수동으로 목록을 시스템의 인터페이스 이름으로 바꾸거나 Netifaces 등의 다른 솔루션을 사용해야 합니다.
[Windows만 해당] 외부 패키지를 사용하지 않고 외부 인터넷 서버에 의존하지 않으려면 이 방법이 도움이 될 수 있습니다.Google 코드 검색에서 찾은 코드 샘플로 필요한 정보를 반환하도록 수정했습니다.
def getIPAddresses():
from ctypes import Structure, windll, sizeof
from ctypes import POINTER, byref
from ctypes import c_ulong, c_uint, c_ubyte, c_char
MAX_ADAPTER_DESCRIPTION_LENGTH = 128
MAX_ADAPTER_NAME_LENGTH = 256
MAX_ADAPTER_ADDRESS_LENGTH = 8
class IP_ADDR_STRING(Structure):
pass
LP_IP_ADDR_STRING = POINTER(IP_ADDR_STRING)
IP_ADDR_STRING._fields_ = [
("next", LP_IP_ADDR_STRING),
("ipAddress", c_char * 16),
("ipMask", c_char * 16),
("context", c_ulong)]
class IP_ADAPTER_INFO (Structure):
pass
LP_IP_ADAPTER_INFO = POINTER(IP_ADAPTER_INFO)
IP_ADAPTER_INFO._fields_ = [
("next", LP_IP_ADAPTER_INFO),
("comboIndex", c_ulong),
("adapterName", c_char * (MAX_ADAPTER_NAME_LENGTH + 4)),
("description", c_char * (MAX_ADAPTER_DESCRIPTION_LENGTH + 4)),
("addressLength", c_uint),
("address", c_ubyte * MAX_ADAPTER_ADDRESS_LENGTH),
("index", c_ulong),
("type", c_uint),
("dhcpEnabled", c_uint),
("currentIpAddress", LP_IP_ADDR_STRING),
("ipAddressList", IP_ADDR_STRING),
("gatewayList", IP_ADDR_STRING),
("dhcpServer", IP_ADDR_STRING),
("haveWins", c_uint),
("primaryWinsServer", IP_ADDR_STRING),
("secondaryWinsServer", IP_ADDR_STRING),
("leaseObtained", c_ulong),
("leaseExpires", c_ulong)]
GetAdaptersInfo = windll.iphlpapi.GetAdaptersInfo
GetAdaptersInfo.restype = c_ulong
GetAdaptersInfo.argtypes = [LP_IP_ADAPTER_INFO, POINTER(c_ulong)]
adapterList = (IP_ADAPTER_INFO * 10)()
buflen = c_ulong(sizeof(adapterList))
rc = GetAdaptersInfo(byref(adapterList[0]), byref(buflen))
if rc == 0:
for a in adapterList:
adNode = a.ipAddressList
while True:
ipAddr = adNode.ipAddress
if ipAddr:
yield ipAddr
adNode = adNode.next
if not adNode:
break
사용방법:
>>> for addr in getIPAddresses():
>>> print addr
192.168.0.100
10.5.9.207
windll
Windows ★★★★★★★★★★★★★★★★★★★★★★」
Ubuntu 머신에서 사용하고 있습니다.
import commands
commands.getoutput("/sbin/ifconfig").split("\n")[1].split()[1][5:]
이거 안 되네.
닌자게코의 대답에 대한 변형입니다.이 기능은 UDP 브로드캐스트를 허용하고 LAN 또는 인터넷 상의 주소에 액세스할 필요가 없는 LAN에서 작동해야 합니다.
import socket
def getNetworkIp():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.connect(('<broadcast>', 0))
return s.getsockname()[0]
print (getNetworkIp())
Debian(테스트 완료)에서는 대부분의 Linux가..
import commands
RetMyIP = commands.getoutput("hostname -I")
MS Windows (테스트 완료)
import socket
socket.gethostbyname(socket.gethostname())
아직 게시되지 않은 버전입니다.Ubuntu 12.04에서 python 2.7로 테스트했습니다.
이 솔루션은 http://code.activestate.com/recipes/439094-get-the-ip-address-associated-with-a-network-inter/에서 찾을 수 있습니다.
import socket
import fcntl
import struct
def get_ip_address(ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915, # SIOCGIFADDR
struct.pack('256s', ifname[:15])
)[20:24])
결과 예:
>>> get_ip_address('eth0')
'38.113.228.130'
입니다.UnkwnTech는 UnkwnTech를 합니다.get_local_addr()
function : LAN IP 입니다. 처리,및하여 .ipv6 에이 .
# imports
import errno
import socket
import logging
# localhost prefixes
_local_networks = ("127.", "0:0:0:0:0:0:0:1")
# ignore these prefixes -- localhost, unspecified, and link-local
_ignored_networks = _local_networks + ("0.", "0:0:0:0:0:0:0:0", "169.254.", "fe80:")
def detect_family(addr):
if "." in addr:
assert ":" not in addr
return socket.AF_INET
elif ":" in addr:
return socket.AF_INET6
else:
raise ValueError("invalid ipv4/6 address: %r" % addr)
def expand_addr(addr):
"""convert address into canonical expanded form --
no leading zeroes in groups, and for ipv6: lowercase hex, no collapsed groups.
"""
family = detect_family(addr)
addr = socket.inet_ntop(family, socket.inet_pton(family, addr))
if "::" in addr:
count = 8-addr.count(":")
addr = addr.replace("::", (":0" * count) + ":")
if addr.startswith(":"):
addr = "0" + addr
return addr
def _get_local_addr(family, remote):
try:
s = socket.socket(family, socket.SOCK_DGRAM)
try:
s.connect((remote, 9))
return s.getsockname()[0]
finally:
s.close()
except socket.error:
# log.info("trapped error connecting to %r via %r", remote, family, exc_info=True)
return None
def get_local_addr(remote=None, ipv6=True):
"""get LAN address of host
:param remote:
return LAN address that host would use to access that specific remote address.
by default, returns address it would use to access the public internet.
:param ipv6:
by default, attempts to find an ipv6 address first.
if set to False, only checks ipv4.
:returns:
primary LAN address for host, or ``None`` if couldn't be determined.
"""
if remote:
family = detect_family(remote)
local = _get_local_addr(family, remote)
if not local:
return None
if family == socket.AF_INET6:
# expand zero groups so the startswith() test works.
local = expand_addr(local)
if local.startswith(_local_networks):
# border case where remote addr belongs to host
return local
else:
# NOTE: the two addresses used here are TESTNET addresses,
# which should never exist in the real world.
if ipv6:
local = _get_local_addr(socket.AF_INET6, "2001:db8::1234")
# expand zero groups so the startswith() test works.
if local:
local = expand_addr(local)
else:
local = None
if not local:
local = _get_local_addr(socket.AF_INET, "192.0.2.123")
if not local:
return None
if local.startswith(_ignored_networks):
return None
return local
의 는, Linux 의 「」만을 할 수 .check_output
hostname -I
다음과 같이 합니다.
from subprocess import check_output
check_output(['hostname', '-I'])
다른 컴퓨터에 연결하여 IP 주소를 전송하는 것 외에는 플랫폼에 의존하지 않는 좋은 방법이 없습니다.예를 들어 findmyipaddress 입니다.연결하려는 컴퓨터가 NAT의 배후에 있지 않는 한 NAT의 배후에 있는 IP 주소가 필요한 경우에는 이 방법이 작동하지 않습니다.
Linux 로 동작하는 솔루션은, 네트워크 인터페이스와 관련된 IP 주소를 취득하는 것입니다.
참고로 이 방법은 다음 사항을 확인할 수 있습니다.
import socket
addr = socket.gethostbyname(socket.gethostname())
OS X(10.6, 10.5), Windows XP 및 적절하게 관리되는 RHEL 부문 서버에서 작동합니다.그것은 아주 적은 돈으로는 효과가 없었다.커널 해킹을 하는 OS VM입니다.따라서 이 인스턴스에서는 127.0.0.1 주소를 확인하고 이 경우 다음 절차를 수행합니다.
if addr == "127.0.0.1":
import commands
output = commands.getoutput("/sbin/ifconfig")
addr = parseaddress(output)
다음으로 출력에서IP 주소를 해석합니다.ifconfig는 기본적으로는 일반 사용자의 PATH에 포함되지 않으므로 명령어로 풀 경로를 지정합니다.이게 도움이 됐으면 좋겠어요.
명령줄 유틸리티를 통해 "깨끗한" 출력을 생성하는 간단한 방법 중 하나는 다음과 같습니다.
import commands
ips = commands.getoutput("/sbin/ifconfig | grep -i \"inet\" | grep -iv \"inet6\" | " +
"awk {'print $2'} | sed -ne 's/addr\:/ /p'")
print ips
시스템의 모든 IPv4 주소가 표시됩니다.
이것은 대부분의 Linux 박스에서 동작합니다.
import socket, subprocess, re
def get_ipv4_address():
"""
Returns IP address(es) of current machine.
:return:
"""
p = subprocess.Popen(["ifconfig"], stdout=subprocess.PIPE)
ifc_resp = p.communicate()
patt = re.compile(r'inet\s*\w*\S*:\s*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})')
resp = patt.findall(ifc_resp[0])
print resp
get_ipv4_address()
은 LAN IP를 하기 위한 는 LAN IP를 취득하기 위한 것입니다.socket.gethostbyname(socket.gethostname())
.1.1194.0.0.이 반환되었습니다.이 방법에서는 LAN 접속만으로 인터넷이 필요 없습니다.Python 3.x는 2.x로 되어 있습니다.UDP:
import select
import socket
import threading
from queue import Queue, Empty
def get_local_ip():
def udp_listening_server():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('<broadcast>', 8888))
s.setblocking(0)
while True:
result = select.select([s],[],[])
msg, address = result[0][0].recvfrom(1024)
msg = str(msg, 'UTF-8')
if msg == 'What is my LAN IP address?':
break
queue.put(address)
queue = Queue()
thread = threading.Thread(target=udp_listening_server)
thread.queue = queue
thread.start()
s2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s2.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
waiting = True
while waiting:
s2.sendto(bytes('What is my LAN IP address?', 'UTF-8'), ('<broadcast>', 8888))
try:
address = queue.get(False)
except Empty:
pass
else:
waiting = False
return address[0]
if __name__ == '__main__':
print(get_local_ip())
import socket
[i[4][0] for i in socket.getaddrinfo(socket.gethostname(), None)]
IP 는 「IPv4」입니다.127.0.0.1
가 있습니다: 비단뱀의 코드입니다
import subprocess
address = subprocess.check_output(['hostname', '-s', '-I'])
address = address.decode('utf-8')
address=address[:-1]
한 줄에 쓸 수도 있습니다.
address = subprocess.check_output(['hostname', '-s', '-I']).decode('utf-8')[:-1]
를 localhost
/etc/hostname
IP를 사용합니다.
127.0.1.1
는, 실제의 IP 주소입니다.보다 일반적으로 말하면, 컴퓨터는 임의의 수의 IP 주소를 가질 수 있습니다.프라이빗 네트워크(127.0.0/8, 10.0.0/8, 172.16.0.0/12 및 192.168.0.0/16)에 대해서 필터링 할 수 있습니다.
단, 모든 IP 주소를 취득하는 크로스 플랫폼 방법은 없습니다.Linux 에서는 ioctl 을 사용할 수 있습니다.
IP 명령을 사용하여 IPv4 및 IPv6 주소를 반환하는 명령어버전을 약간 개량한 것입니다.
import commands,re,socket
#A generator that returns stripped lines of output from "ip address show"
iplines=(line.strip() for line in commands.getoutput("ip address show").split('\n'))
#Turn that into a list of IPv4 and IPv6 address/mask strings
addresses1=reduce(lambda a,v:a+v,(re.findall(r"inet ([\d.]+/\d+)",line)+re.findall(r"inet6 ([\:\da-f]+/\d+)",line) for line in iplines))
#addresses1 now looks like ['127.0.0.1/8', '::1/128', '10.160.114.60/23', 'fe80::1031:3fff:fe00:6dce/64']
#Get a list of IPv4 addresses as (IPstring,subnetsize) tuples
ipv4s=[(ip,int(subnet)) for ip,subnet in (addr.split('/') for addr in addresses1 if '.' in addr)]
#ipv4s now looks like [('127.0.0.1', 8), ('10.160.114.60', 23)]
#Get IPv6 addresses
ipv6s=[(ip,int(subnet)) for ip,subnet in (addr.split('/') for addr in addresses1 if ':' in addr)]
GNU/Linux에서 "ip route" 명령을 사용하여 현재 IP 주소를 알 수 있습니다.
라우터/모뎀 상에서 동작하는 DHCP 서버에 의해 인터페이스에 주어지는IP 가 표시됩니다.통상, 「192.168.1.1/24」는 로컬 네트워크의 IP입니다.여기서 「24」는 마스크 범위내의 DHCP 서버에 의해서 주어지는 정의 가능한 IP 주소의 범위를 의미합니다.
다음은 예를 제시하겠습니다.Py Notify는 제 요점을 명확히 하기 위한 추가 사항일 뿐이며, 전혀 필요하지 않습니다.
#! /usr/bin/env python
import sys , pynotify
if sys.version_info[1] != 7:
raise RuntimeError('Python 2.7 And Above Only')
from subprocess import check_output # Available on Python 2.7+ | N/A
IP = check_output(['ip', 'route'])
Split_Result = IP.split()
# print Split_Result[2] # Remove "#" to enable
pynotify.init("image")
notify = pynotify.Notification("Ip", "Server Running At:" + Split_Result[2] , "/home/User/wireless.png")
notify.show()
이 방법의 장점은 네트워크인터페이스를 지정할 필요가 없다는 것입니다.이는 소켓 서버를 실행할 때 매우 유용합니다.
PyNotify는 easy_install 또는 Pip을 사용하여 설치할 수 있습니다.
easy_install py-notify
또는
pip install py-notify
또는 python 스크립트/프로세서 내
from pip import main
main(['install', 'py-notify'])
netifaces는 pip 및 easy_install을 통해 이용할 수 있습니다(기본값이 아닌 것은 알지만 설치할 가치가 있을 수 있습니다.
netifaces에는 플랫폼 간에 몇 가지 이상한 점이 있습니다.
- localhost/loop-back 인터페이스가 항상 포함되는 것은 아닙니다(Cygwin).
- 주소는 프로토콜(예: IPv4, IPv6)별로 나열되며 프로토콜은 인터페이스별로 나열됩니다.일부 시스템(Linux)에서는 각 프로토콜-인터페이스 쌍이 고유한 관련 인터페이스를 가지고 있으며(interface_name:n 표기법 사용), 다른 시스템(Windows)에서는 단일 인터페이스에 각 프로토콜에 대한 주소 목록이 있습니다.두 경우 모두 프로토콜 목록이 있지만 단일 요소만 포함할 수 있습니다.
다음은 사용할 수 있는 Netifaces 코드입니다.
import netifaces
PROTO = netifaces.AF_INET # We want only IPv4, for now at least
# Get list of network interfaces
# Note: Can't filter for 'lo' here because Windows lacks it.
ifaces = netifaces.interfaces()
# Get all addresses (of all kinds) for each interface
if_addrs = [netifaces.ifaddresses(iface) for iface in ifaces]
# Filter for the desired address type
if_inet_addrs = [addr[PROTO] for addr in if_addrs if PROTO in addr]
iface_addrs = [s['addr'] for a in if_inet_addrs for s in a if 'addr' in s]
# Can filter for '127.0.0.1' here.
위의 코드는 주소를 인터페이스 이름에 다시 매핑하지 않습니다(즉석에서 ebtables/iptables 규칙을 생성할 때 유용합니다).여기에서는, 인터페이스명을 태플에 붙여 상기의 정보를 보관합니다.
import netifaces
PROTO = netifaces.AF_INET # We want only IPv4, for now at least
# Get list of network interfaces
ifaces = netifaces.interfaces()
# Get addresses for each interface
if_addrs = [(netifaces.ifaddresses(iface), iface) for iface in ifaces]
# Filter for only IPv4 addresses
if_inet_addrs = [(tup[0][PROTO], tup[1]) for tup in if_addrs if PROTO in tup[0]]
iface_addrs = [(s['addr'], tup[1]) for tup in if_inet_addrs for s in tup[0] if 'addr' in s]
아니, 난 목록 수집을 좋아하지 않아요즘 내 뇌가 작동하는 방식이야.
다음의 스니펫에 의해서, 모든 것이 인쇄됩니다.
from __future__ import print_function # For 2.x folks
from pprint import pprint as pp
print('\nifaces = ', end='')
pp(ifaces)
print('\nif_addrs = ', end='')
pp(if_addrs)
print('\nif_inet_addrs = ', end='')
pp(if_inet_addrs)
print('\niface_addrs = ', end='')
pp(iface_addrs)
맛있게 드세요!
import netifaces as ni
ni.ifaddresses('eth0')
ip = ni.ifaddresses('eth0')[ni.AF_INET][0]['addr']
print(ip)
그러면 Ubuntu 시스템과 MacOS의 IP 주소가 반환됩니다.출력은 192.168.1.10과 같은 시스템 IP 주소가 됩니다.
IP 주소를 얻으려면 python에서 셸 명령을 직접 사용합니다.
import socket, subprocess
def get_ip_and_hostname():
hostname = socket.gethostname()
shell_cmd = "ifconfig | awk '/inet addr/{print substr($2,6)}'"
proc = subprocess.Popen([shell_cmd], stdout=subprocess.PIPE, shell=True)
(out, err) = proc.communicate()
ip_list = out.split('\n')
ip = ip_list[0]
for _ip in ip_list:
try:
if _ip != "127.0.0.1" and _ip.split(".")[3] != "1":
ip = _ip
except:
pass
return ip, hostname
ip_addr, hostname = get_ip_and_hostname()
새롭게 도입된 asyncio 패키지를 사용하는 Python 3.4 버전.
async def get_local_ip():
loop = asyncio.get_event_loop()
transport, protocol = await loop.create_datagram_endpoint(
asyncio.DatagramProtocol,
remote_addr=('8.8.8.8', 80))
result = transport.get_extra_info('sockname')[0]
transport.close()
return result
이것은 UnkwnTech의 훌륭한 답변에 근거하고 있습니다.
언급URL : https://stackoverflow.com/questions/166506/finding-local-ip-addresses-using-pythons-stdlib
'programing' 카테고리의 다른 글
Java FileReader 인코딩 문제 (0) | 2023.02.04 |
---|---|
mariadb 서버:mysql.server stop'을 사용하여 서버를 중지할 수 없습니다. (0) | 2023.02.04 |
봄의 @Valid 주석은 무엇을 의미합니까? (0) | 2023.02.04 |
null 값에 대해 jdk8 스트림을 관리하는 방법 (0) | 2023.02.04 |
Linux에서 문자열 리터럴의 메모리 주소가 다른 것과 다른 이유는 무엇입니까? (0) | 2023.01.25 |