Python - Network Programming
Python provides two levels of access to network services. At a low level, you can
access the basic socket support in the underlying operating system, which allows
you to implement clients and servers for both connection-oriented and
connectionless protocols.
Python also has libraries that provide higher-level access to specific application-
level network protocols, such as FTP, HTTP, and so on.
This chapter gives you understanding on most famous concept in Networking -
Socket Programming.
[Link] Term & Description
.
1 Domain
The family of protocols that is used as the transport mechanism. These
values are constants such as AF_INET, PF_INET, PF_UNIX, PF_X25,
and so on.
2 Type
The type of communications between the two endpoints, typically
SOCK_STREAM for connection-oriented protocols and SOCK_DGRAM
for connectionless protocols.
3 Protocol
Typically zero, this may be used to identify a variant of a protocol within
a domain and type.
4 Hostname
The identifier of a network interface −
A string, which can be a host name, a dotted-quad address, or an
IPV6 address in colon (and possibly dot) notation
A string "<broadcast>", which specifies an
INADDR_BROADCAST address.
A zero-length string, which specifies INADDR_ANY, or
An Integer, interpreted as a binary address in host byte order.
5 Port
Each server listens for clients calling on one or more ports. A port may be
a Fixnum port number, a string containing a port number, or the name of a
service.
What is Sockets?
Sockets are the endp
oints of a bidirectional communications channel. Sockets may communicate
within a process, between processes on the same machine, or between processes
on different continents.
Sockets may be implemented over a number of different channel types: Unix
domain sockets, TCP, UDP, and so on. The socket library provides specific
classes for handling the common transports as well as a generic interface for
handling the rest.
Sockets have their own vocabulary −
The socket Module
To create a socket, you must use the [Link]() function available
in socket module, which has the general syntax −
s = [Link] (socket_family, socket_type, protocol=0)
Here is the description of the parameters −
socket_family − This is either AF_UNIX or AF_INET, as explained earlier.
socket_type − This is either SOCK_STREAM or SOCK_DGRAM.
protocol − This is usually left out, defaulting to 0.
Once you have socket object, then you can use required functions to create your
client or server program. Following is the list of functions required −
Server Socket Methods
[Link]. Method & Description
1 [Link]()
This method binds address (hostname, port number pair) to socket.
2 [Link]()
This method sets up and start TCP listener.
3 [Link]()
This passively accept TCP client connection, waiting until connection arrives (blocki
Client Socket Methods
[Link]. Method & Description
1 [Link]()
This method actively initiates TCP server connection.
General Socket Methods
[Link] Method & Description
.
1 [Link]()
This method receives TCP message
2 [Link]()
This method transmits TCP message
3 [Link]()
This method receives UDP message
4 [Link]()
This method transmits UDP message
5 [Link]()
This method closes socket
6 [Link]()
Returns the hostname.
A Simple Server
To write Internet servers, we use the socket function available in socket module to
create a socket object. A socket object is then used to call other functions to setup
a socket server.
Now call bind(hostname, port) function to specify a port for your service on the
given host.
Next, call the accept method of the returned object. This method waits until a
client connects to the port you specified, and then returns a connection object that
represents the connection to that client.
#!/usr/bin/python # This is [Link] file
import socket # Import socket module
s = [Link]() # Create a socket object
host = [Link]() # Get local machine name
port = 12345 # Reserve a port for your service.
[Link]((host, port)) # Bind to the port
[Link](5) # Now wait for client connection.
while True:
c, addr = [Link]() # Establish connection with client.
print 'Got connection from', addr
[Link]('Thank you for connecting')
[Link]() # Close the connection
A Simple Client
Let us write a very simple client program which opens a connection to a given
port 12345 and given host. This is very simple to create a socket client using
Python's socket module function.
The [Link](hosname, port ) opens a TCP connection to hostname on
the port. Once you have a socket open, you can read from it like any IO object.
When done, remember to close it, as you would close a file.
The following code is a very simple client that connects to a given host and port,
reads any available data from the socket, and then exits −
#!/usr/bin/python # This is [Link] file
import socket # Import socket module
s = [Link]() # Create a socket object
host = [Link]() # Get local machine name
port = 12345 # Reserve a port for your service.
[Link]((host, port))
print [Link](1024)
[Link]() # Close the socket when done
Now run this [Link] in background and then run above [Link] to see the
result.
# Following would start a server in background.
$ python [Link] &
# Once server is started run client as follows:
$ python [Link]
This would produce following result −
Got connection from ('[Link]', 48437)
Thank you for connecting
Python Internet modules
A list of some important modules in Python Network/Internet programming.
Protoco Common function Port No Python module
l
HTTP Web pages 80 httplib, urllib, xmlrpclib
NNTP Usenet news 119 nntplib
FTP File transfers 20 ftplib, urllib
SMTP Sending email 25 smtplib
POP3 Fetching email 110 poplib
IMAP4 Fetching email 143 imaplib
Telnet Command lines 23 telnetlib
Gopher Document transfers 70 gopherlib, urllib
Please check all the libraries mentioned above to work with FTP, SMTP, POP,
and IMAP protocols.
Protocol Python Module Name Description
HTTP [Link] Opening the HTTP URL
HTTP [Link] Create a reponse object for a url
request
HTTP [Link] To break Uniform Resource Locator
(URL) strings up in components like
(addressing scheme, network
location, path etc.),
HTTP [Link] It finds out whether or not a
particular user agent can fetch a
URL on the Web site that published
the [Link] file.
FTP ftplib implements the client side of the
FTP protocol. You can use this to
write Python programs that perform
a variety of automated FTP jobs,
such as mirroring other FTP servers.
POP poplib This module defines a class, POP3,
which encapsulates a connection to a
POP3 server to read messages from
a email server
IMAP imaplib This module defines three classes,
IMAP4, IMAP4_SSL and
IMAP4_stream, which encapsulate a
connection to an IMAP4 server to
read emails.
SMTP smtplib The smtplib module defines an
SMTP client session object that can
be used to send mail to any Internet
machine with an SMTP listner
deamon.
Telnet telnet This module provides a Telnet class
that implements the Telnet protocol
to access a server thorugh teleent.
TCP Sockets
As you’ll see shortly, we’ll create a socket object
using [Link]() and specify the socket type
as socket.SOCK_STREAM. When you do that, the default protocol
that’s used is the Transmission Control Protocol (TCP). This is a
good default and probably what you want.
Why should you use TCP? The Transmission Control Protocol
(TCP):
Is reliable: packets dropped in the network are detected and
retransmitted by the sender.
Has in-order data delivery: data is read by your application
in the order it was written by the sender.
In contrast, User Datagram Protocol (UDP) sockets created
with socket.SOCK_DGRAM aren’t reliable, and data read by the
receiver can be out-of-order from the sender’s writes.
Why is this important? Networks are a best-effort delivery system.
There’s no guarantee that your data will reach its destination or that
you’ll receive what’s been sent to you.
Network devices (for example, routers and switches), have finite
bandwidth available and their own inherent system limitations. They
have CPUs, memory, buses, and interface packet buffers, just like
our clients and servers. TCP relieves you from having to worry
about packet loss, data arriving out-of-order, and many other things
that invariably happen when you’re communicating across a
network.
In the diagram below, let’s look at the sequence of socket API calls
and data flow for TCP:
TCP Socket Flow (Image source)
The left-hand column represents the server. On the right-hand side is
the client.
Starting in the top left-hand column, note the API calls the server
makes to setup a “listening” socket:
socket()
bind()
listen()
accept()
A listening socket does just what it sounds like. It listens for
connections from clients. When a client connects, the server
calls accept() to accept, or complete, the connection.
The client calls connect() to establish a connection to the server and
initiate the three-way handshake. The handshake step is important
since it ensures that each side of the connection is reachable in the
network, in other words that the client can reach the server and vice-
versa. It may be that only one host, client or server, can reach the
other.
In the middle is the round-trip section, where data is exchanged
between the client and server using calls to send() and recv().
Python - Sending Email using SMTP
Simple Mail Transfer Protocol (SMTP) is a protocol, which handles sending e-
mail and routing e-mail between mail servers.
Python provides smtplib module, which defines an SMTP client session object
that can be used to send mail to any Internet machine with an SMTP or ESMTP
listener daemon.
Here is a simple syntax to create one SMTP object, which can later be used to
send an e-mail −
import smtplib
smtpObj = [Link]( [host [, port [, local_hostname]]] )
Here is the detail of the parameters −
host − This is the host running your SMTP server. You can specify IP
address of the host or a domain name like [Link]. This is
optional argument.
port − If you are providing host argument, then you need to specify a port,
where SMTP server is listening. Usually this port would be 25.
local_hostname − If your SMTP server is running on your local machine,
then you can specify just localhost as of this option.
An SMTP object has an instance method called sendmail, which is typically used
to do the work of mailing a message. It takes three parameters −
The sender − A string with the address of the sender.
The receivers − A list of strings, one for each recipient.
The message − A message as a string formatted as specified in the various
RFCs.
Example
Here is a simple way to send one e-mail using Python script. Try it once −
#!/usr/bin/python
import smtplib
sender = 'from@[Link]'
receivers = ['to@[Link]']
message = """From: From Person <from@[Link]>
To: To Person <to@[Link]>
Subject: SMTP e-mail test
This is a test e-mail message.
"""
try:
smtpObj = [Link]('localhost')
[Link](sender, receivers, message)
print "Successfully sent email"
except SMTPException:
print "Error: unable to send email"
Here, you have placed a basic e-mail in message, using a triple quote, taking care
to format the headers correctly. An e-mail requires a From, To,
and Subject header, separated from the body of the e-mail with a blank line.
To send the mail you use smtpObj to connect to the SMTP server on the local
machine and then use the sendmail method along with the message, the from
address, and the destination address as parameters (even though the from and to
addresses are within the e-mail itself, these aren't always used to route mail).
If you are not running an SMTP server on your local machine, you can
use smtplib client to communicate with a remote SMTP server. Unless you are
using a webmail service (such as Hotmail or Yahoo! Mail), your e-mail provider
must have provided you with outgoing mail server details that you can supply
them, as follows −
[Link]('[Link]', 25)
Sending an HTML e-mail using Python
When you send a text message using Python, then all the content are treated as
simple text. Even if you include HTML tags in a text message, it is displayed as
simple text and HTML tags will not be formatted according to HTML syntax. But
Python provides option to send an HTML message as actual HTML message.
While sending an e-mail message, you can specify a Mime version, content type
and character set to send an HTML e-mail.
Example
Following is the example to send HTML content as an e-mail. Try it once −
#!/usr/bin/python
import smtplib
message = """From: From Person <from@[Link]>
To: To Person <to@[Link]>
MIME-Version: 1.0
Content-type: text/html
Subject: SMTP HTML e-mail test
This is an e-mail message to be sent in HTML format
<b>This is HTML message.</b>
<h1>This is headline.</h1>
"""
try:
smtpObj = [Link]('localhost')
[Link](sender, receivers, message)
print "Successfully sent email"
except SMTPException:
print "Error: unable to send email"
Sending Attachments as an E-mail
To send an e-mail with mixed content requires to set Content-type header
to multipart/mixed. Then, text and attachment sections can be specified
within boundaries.
A boundary is started with two hyphens followed by a unique number, which
cannot appear in the message part of the e-mail. A final boundary denoting the e-
mail's final section must also end with two hyphens.
Attached files should be encoded with the pack("m") function to have base64
encoding before transmission.
Example
Following is the example, which sends a file /tmp/[Link] as an attachment. Try it
once −
#!/usr/bin/python
import smtplib
import base64
filename = "/tmp/[Link]"
# Read a file and encode it into base64 format
fo = open(filename, "rb")
filecontent = [Link]()
encodedcontent = base64.b64encode(filecontent) # base64
sender = 'webmaster@[Link]'
reciever = '[Link]@[Link]'
marker = "AUNIQUEMARKER"
body ="""
This is a test email to send an attachement.
"""
# Define the main headers.
part1 = """From: From Person <me@[Link]>
To: To Person <[Link]@[Link]>
Subject: Sending Attachement
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=%s
--%s
""" % (marker, marker)
# Define the message action
part2 = """Content-Type: text/plain
Content-Transfer-Encoding:8bit
%s
--%s
""" % (body,marker)
# Define the attachment section
part3 = """Content-Type: multipart/mixed; name=\"%s\"
Content-Transfer-Encoding:base64
Content-Disposition: attachment; filename=%s
%s
--%s--
""" %(filename, filename, encodedcontent, marker)
message = part1 + part2 + part3
try:
smtpObj = [Link]('localhost')
[Link](sender, reciever, message)
print "Successfully sent email"
except Exception:
print "Error: unable to send email"
Python - IP Address
IP Address (Internet Protocol) is a fundamental networking concept that
provides address assignation capability in a network. The python
module ipaddress is used extensively to validate and categorize IP address
to IPV4 and IPV6 type. It can also be used to do comparison of the IP
address values as well as IP address arithmetic for manipulating the ip
addresses.
Validate the IPV4 Address
The ip_address function validates the IPV4 address. If the range of values is
beyond 0 to 255, then it throws an error.
print (ipaddress.ip_address(u'[Link]'))
print (ipaddress.ip_address(u'[Link]'))
When we run the above program, we get the following output −
[Link]
ValueError: u'[Link]' does not appear to be an IPv4 or IPv6 address
Validate the IPV6 Address
The ip_address function validates the IPV6 address. If the range of values is
beyond 0 to ffff, then it throws an error.
print (ipaddress.ip_address(u'[Link]'))
#invalid IPV6 address
print (ipaddress.ip_address(u'FFFF:1[Link]'))
When we run the above program, we get the following output −
[Link]
ValueError: u'FFFF:1[Link]' does not appear to be an
IPv4 or IPv6 address
Check the type of IP Address
We can supply the IP address of various formats and the module will be able
to recognize the valid formats. It will also indicate which category of IP
address it is.
print type(ipaddress.ip_address(u'[Link]'))
print type(ipaddress.ip_address(u'[Link]'))
print ipaddress.ip_address(u'[Link]').reverse_pointer
print ipaddress.ip_network(u'[Link]/28')
When we run the above program, we get the following output −
[Link].[Link]
[Link]/28
Comparison of IP Addresses
We can make a logical comparison of the IP addresses finding out if they are
equal or not. We can also compare if one IP address is greater than the other
in its value.
print (ipaddress.IPv4Address(u'[Link]') >
ipaddress.IPv4Address(u'[Link]'))
print (ipaddress.IPv4Address(u'[Link]') ==
ipaddress.IPv4Address(u'[Link]'))
print (ipaddress.IPv4Address(u'[Link]') !=
ipaddress.IPv4Address(u'[Link]'))
When we run the above program, we get the following output −
True
False
True
IP Addresses Arithmetic
We can also apply arithmetic operations to manipulate IP addresses. We can
add or subtract integers to an IP address. If after addition the value of the last
octet goes beyond 255 then the previous octet gets incremented to
accommodate the value. If the extra value can not be absorbed by any of the
previous octet then a value error is raised.
print (ipaddress.IPv4Address(u'[Link]')+1)
print (ipaddress.IPv4Address(u'[Link]')-3)
# Increases the previous octet by value 1.
print (ipaddress.IPv4Address(u'[Link]')+3)
# Throws Value error
print (ipaddress.IPv4Address(u'[Link]')+1)
When we run the above program, we get the following output −
[Link]
[Link]
[Link]
AddressValueError: 4294967296 (>= 2**32) is not permitted as an IPv4 address
Python - DNS Look-up
The IP addresses when translated to human readable formats or words
become known as domain names. The translation of domain names to IP
address is managed by the python module [Link] module also
provides methods to find out CNAME and MX records.
Finding 'A' Record
In the below program we find the ip address for the domain using the
[Link] method. Usually this mapping between IP address and domain
name is also known as 'A' record.
import dnspython as dns
import [Link]
result = [Link]('[Link]', 'A')
for ipval in result:
print('IP', ipval.to_text())
When we run the above program, we get the following output −
('IP', u'[Link]')
Finding CNAME Value
A CNAME record also known as Canonical Name Record is a type of record
in the Domain Name System (DNS) used to map a domain name as an alias
for another domain. CNAME records always point to another domain name
and never directly to an IP address. In the query method below we specify
the CNAME parameter to get the CNAME value.
import dnspython as dns
import [Link]
result = [Link]('[Link]', 'CNAME')
for cnameval in result:
print ' cname target address:', [Link]
When we run the above program, we get the following output −
cname target address: [Link].
Finding MX Record
A MX record also called mail exchanger record is a resource record in the
Domain Name System that specifies a mail server responsible for accepting
email messages on behalf of a recipient's domain. It also sets the preference
value used to prioritizing mail delivery if multiple mail servers are available.
Similar to above programs we can find the value for MX record using the
'MX' parameter in the query method.
result = [Link]('[Link]', 'MX')
for exdata in result:
print ' MX Record:', [Link]()
When we run the above program, we get the following output −
MX Record: [Link].
MX Record: [Link].
MX Record: [Link].