Getting a machine's external IP address with Python
If you are behind a router which obtains the external IP, I'm afraid you have no other option but to use external service like you do. If the router itself has some query interface, you can use it, but the solution will be very environment-specific and unreliable.
Finding network (external) IP addresses using Python
Use this script :
import urllib, json
data = json.loads(urllib.urlopen("http://ip.jsontest.com/").read())
print data["ip"]
Without json :
import urllib, re
data = re.search('"([0-9.]*)"', urllib.urlopen("http://ip.jsontest.com/").read()).group(1)
print data
Other way it was to parse ifconfig (= linux) or ipconfig (= windows) command but take care with translated Windows System
(ipconfig was translated).
Example of lib for linux :
ifparser.
Finding local IP addresses using Python's stdlib
import socket
socket.gethostbyname(socket.gethostname())
This won't work always (returns 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()
instead. Of course your machine needs a resolvable hostname.
Python, How to get all external ip addresses with multiple NICs
You should use netifaces. It is designed to be cross-platform on Mac OS X, Linux, and Windows.
>>> import netifaces as ni
>>> ni.interfaces()
['lo', 'eth0', 'eth1', 'vboxnet0', 'dummy1']
>>> ni.ifaddresses('eth0')
{17: [{'broadcast': 'ff:ff:ff:ff:ff:ff', 'addr': '00:02:55:7b:b2:f6'}], 2: [{'broadcast': '24.19.161.7', 'netmask': '255.255.255.248', 'addr': '24.19.161.6'}], 10: [{'netmask': 'ffff:ffff:ffff:ffff::', 'addr': 'fe80::202:55ff:fe7b:b2f6%eth0'}]}
>>>
>>> ni.ifaddresses.__doc__
'Obtain information about the specified network interface.\n\nReturns a dict whose keys are equal to the address family constants,\ne.g. netifaces.AF_INET, and whose values are a list of addresses in\nthat family that are attached to the network interface.'
>>> # for the IPv4 address of eth0
>>> ni.ifaddresses('eth0')[2][0]['addr']
'24.19.161.6'
The numbers used to index protocols are from /usr/include/linux/socket.h
(in Linux)...
#define AF_INET 2 /* Internet IP Protocol */
#define AF_INET6 10 /* IP version 6 */
#define AF_PACKET 17 /* Packet family */
Python Socket to connect over Global Public IP Address
In server you always use local IP
(it is IP of one of network cards in computer or 0.0.0.0
to use all network cards)
s.bind( (local_IP, port) )
# or
s.bind( ('0.0.0.0', port) )
In client you use external IP
s.connect( (external_IP, port) )
External client uses external IP
to connect with your Internet Provider route and this router knows that this external IP
is assigned to your computer and it redirects it your server.
At the same time local client can use local IP
to connect with the same server.
external_client --> router(externa_IP) --> server(local_IP) <-- local_client
What is the best way to get the external IP of a machine in python?
Off the top of my head you could use an external webpage that returns your ip. For example using the page myip.dnsdynamic.org:
import urllib2
myip = urllib2.urlopen("http://myip.dnsdynamic.org/").read()
Related Topics
How to Scrape a Website Which Requires Login Using Python and Beautifulsoup
How to Request a Url in Python and Not Follow Redirects
Python Numpy Arange Unexpected Results
How Many Concurrent Requests Does a Single Flask Process Receive
Merge Multiple Column Values into One Column in Python Pandas
Is It Feasible to Compile Python to MAChine Code
How to Check If a Value Is in the List in Selection from Pandas Data Frame
How to Determine the Length of Lists in a Pandas Dataframe Column
Does Python Support Multiprocessor/Multicore Programming
Nested for Loops Using List Comprehension
How to Calculate the Sum of All Columns of a 2D Numpy Array (Efficiently)
Python String 'Join' Is Faster () Than '+', But What's Wrong Here
Naming Conflict with Built-In Function
Differencebetween Using Loc and Using Just Square Brackets to Filter for Columns in Pandas/Python