Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Python Network Programming Cookbook
Python Network Programming Cookbook

Python Network Programming Cookbook: Practical solutions to overcome real-world networking challenges , Second Edition

Arrow left icon
Profile Icon Pradeeban Kathiravelu Profile Icon Gary Berger Profile Icon Dr. M. O. Faruque Sarker
Arrow right icon
$29.99 $43.99
Full star icon Full star icon Full star icon Half star icon Empty star icon 3.5 (4 Ratings)
eBook Aug 2017 450 pages 2nd Edition
eBook
$29.99 $43.99
Paperback
$54.99
Subscription
Free Trial
Renews at $19.99p/m
Arrow left icon
Profile Icon Pradeeban Kathiravelu Profile Icon Gary Berger Profile Icon Dr. M. O. Faruque Sarker
Arrow right icon
$29.99 $43.99
Full star icon Full star icon Full star icon Half star icon Empty star icon 3.5 (4 Ratings)
eBook Aug 2017 450 pages 2nd Edition
eBook
$29.99 $43.99
Paperback
$54.99
Subscription
Free Trial
Renews at $19.99p/m
eBook
$29.99 $43.99
Paperback
$54.99
Subscription
Free Trial
Renews at $19.99p/m

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Table of content icon View table of contents Preview book icon Preview Book

Python Network Programming Cookbook

Sockets, IPv4, and Simple Client/Server Programming

In this chapter, we will cover the following recipes:

  • Printing your machine's name and IPv4 address
  • Retrieving a remote machine's IP address
  • Converting an IPv4 address to different formats
  • Finding a service name, given the port and protocol
  • Converting integers to and from host to network byte order
  • Setting and getting the default socket timeout
  • Handling socket errors gracefully
  • Modifying a socket's send/receive buffer size
  • Changing a socket to the blocking/non-blocking mode
  • Reusing socket addresses
  • Printing the current time from the internet time server
  • Writing an SNTP client
  • Writing a simple TCP echo client/server application
  • Writing a simple UDP echo client/server application

Introduction

This chapter introduces Python's core networking library through some simple recipes. Python's socket module has both class-based and instances-based utilities. The difference between a class-based and instance-based method is that the former doesn't need an instance of a socket object. This is a very intuitive approach. For example, in order to print your machine's IP address, you don't need a socket object. Instead, you can just call the socket's class-based methods. On the other hand, if you need to send some data to a server application, it is more intuitive that you create a socket object to perform that explicit operation. The recipes presented in this chapter can be categorized into three groups as follows:

  • In the first few recipes, the class-based utilities have been used in order to extract some useful information about host, network, and any target service.
  • After that, some more recipes have been presented using the instance-based utilities. Some common socket tasks, including manipulating the socket timeout, buffer size, and blocking mode has been demonstrated.
  • Finally, both class-based and instance-based utilities have been used to construct some clients, which perform some practical tasks, for example, synchronizing the machine time with an internet server or writing a generic client/server script.

You can use these demonstrated approaches to write your own client/server application.

Printing your machine's name and IPv4 address

Sometimes, you need to quickly discover some information about your machine, for example, the hostname, IP address, number of network interfaces, and so on. This is very easy to achieve using Python scripts.

Getting ready

You need to install Python on your machine before you start coding. Python comes preinstalled in most of the Linux distributions. For Microsoft Windows operating systems, you can download binaries from the Python website: http://www.python.org/download/.

Currently, Python 3.x is released in addition to Python 2.x. Many of the current Linux distributions and macOS versions are still shipping Python 2 by default. However, some ship both of them.

Download the relevant installer for your operating system and the relevant version based on whether your operating system is 32 bit or 64 bit.

You may consult the documentation of your operating system to check and review your Python setup. After installing Python on your machine, you can try opening the Python interpreter from the command line by typing python. This will show the interpreter prompt, >>>, which should be similar to the following output:

~$ python
Python 2.7.12 (default, Nov 19 2016, 06:48:10) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 
  

How to do it...

In the latter versions of Ubuntu since Ubuntu 14.04, Python 3 can be executed by typing python3:

~$ python3
Python 3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or 
"license" for more information.
>>>

Similarly, to be specific about which version you prefer to use, you may type python2 to execute Python 2 as well:

~$ python2
Python 2.7.12 (default, Nov 19 2016, 06:48:10) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>

There are a few changes in Python 3 that made some code written for Python 2 incompatible with Python 3. When you write network applications, try to follow the Python 3 best practices as these changes and improvements are back ported to the latter versions of Python 2. Thus, you may be fine by running the latest versions of Python 2 such as Python 2.7. However, some code developed focusing on Python 2 may not run on Python 3.

The following recipes in this chapter are written in Python 3. However, please keep in mind that a few network projects and modules may have been developed for Python 2. In that case, you will either have to port the application to Python 3 or use Python 2 depending on your requirements.

As this recipe is very short, you can try this in the Python interpreter interactively.

First, we need to import the Python socket library with the following command:

>>> import socket  

Then, we call the gethostname() method from the socket library and store the result in a variable as follows:

>>> host_name = socket.gethostname()
>>> print "Host name: %s" %host_name
Host name: llovizna
>>> print "IP address: %s" 
%socket.gethostbyname(host_name)
IP address: 127.0.1.1

The entire activity can be wrapped in a free-standing function, print_machine_info(), which uses the built-in socket class methods.

We call our function from the usual Python __main__ block. During runtime, Python assigns values to some internal variables such as __name__. In this case, __name__ refers to the name of the calling process. When running this script from the command line, as shown in the following command, the name will be __main__. But it will be different if the module is imported from another script. This means that, when the module is called from the command line, it will automatically run our print_machine_info function; however, when imported separately, the user will need to explicitly call the function.

Listing 1.1 shows how to get our machine info, as follows:

#!/usr/bin/env python
# Python Network Programming Cookbook,
Second Edition -- Chapter - 1 # This program is optimized for Python 2.7.12
and Python 3.5.2. # It may run on any other version with/without
modifications. import socket def print_machine_info(): host_name = socket.gethostname() ip_address = socket.gethostbyname(host_name) print ("Host name: %s" %host_name) print ("IP address: %s" %ip_address) if __name__ == '__main__': print_machine_info()

In order to run this recipe, you can use the provided source file from the command line as follows:

$ python 1_1_local_machine_info.py  

On my machine, the following output is shown:

Host name: llovizna
IP address: 127.0.1.1
  

The hostname is what you assigned to your computer when you configured your operating system. This output will be different on your machine depending on the system's host configuration. Here hostname indicates where the Python interpreter is currently executing.

Please note that the programs in this book are run with both versions 2 and 3. We avoid mentioning python3 and python2 in commands, as they are too specific to some distributions and assumes that a specific version is installed. You may run any of the programs in either version by using python2 or python3 accordingly.

How it works...

The import socket statement imports one of Python's core networking libraries. Then, we use the two utility functions, gethostname() and gethostbyname(host_name). You can type help(socket.gethostname) to see the online help information from within the command line. Alternatively, you can type the following address in your web browser at http://docs.python.org/3/library/socket.html. You can refer to the following code:

    gethostname(...)
        gethostname() -> string 
        Return the current host name. 
    
    gethostbyname(...) 
        gethostbyname(host) -> address 
        Return the IP address (a string of the form 
'255.255.255.255') for a host.

The first function takes no parameter and returns the current or localhost name. The second function takes a single hostname parameter and returns its IP address.

Retrieving a remote machine's IP address

Sometimes, you need to translate a machine's hostname into its corresponding IP address, for example, a quick domain name lookup. This recipe introduces a simple function to do that.

How to do it...

If you need to know the IP address of a remote machine, you can use a built-in library function, gethostbyname(). In this case, you need to pass the remote hostname as its parameter.

In this case, we need to call the gethostbyname() class function. Let's have a look at this short code snippet.

Listing 1.2 shows how to get a remote machine's IP address as follows:

    #!/usr/bin/env python
    # Python Network Programming Cookbook, Second Edition
-- Chapter - 1 # This program is optimized for Python 2.7.12 and
Python 3.5.2. # It may run on any other version with/without
modifications. import socket def get_remote_machine_info(): remote_host = 'www.python.org' try: print ("IP address of %s: %s" %(remote_host,
socket.gethostbyname(remote_host))) except socket.error as err_msg: print ("%s: %s" %(remote_host, err_msg)) if __name__ == '__main__': get_remote_machine_info()

If you run the preceding code it gives the following output:

$ python 1_2_remote_machine_info.py 
IP address of www.python.org: 151.101.36.223
  

How it works...

This recipe wraps the gethostbyname() method inside a user-defined function called get_remote_machine_info(). In this recipe, we introduced the notion of exception handling. As you can see, we wrapped the main function call inside a try-except block. This means that, if some error occurs during the execution of this function, this error will be dealt with by this try-except block.

For example, let's change the remote_host value and replace https://www.python.org/ with something non-existent, for example, www.pytgo.org:

#!/usr/bin/env python
# Python Network Programming Cookbook,
Second Edition -- Chapter - 1 # This program is optimized for Python 2.7.12 and
Python 3.5.2. # It may run on any other version with/without
modifications. import socket def get_remote_machine_info(): remote_host = 'www.pytgo.org' try: print ("IP address of %s: %s" %
(remote_host,
socket.gethostbyname(remote_host))) except socket.error as err_msg: print ("%s: %s" %(remote_host, err_msg)) if __name__ == '__main__': get_remote_machine_info()

Now run the following command:

$ python 1_2_remote_machine_info.py 
www.pytgo.org: [Errno -2] Name or service not known
  

The try-except block catches the error and shows the user an error message that there is no IP address associated with the hostname, www.pytgo.org.

Converting an IPv4 address to different formats

When you would like to deal with low-level network functions, sometimes, the usual string notation of IP addresses are not very useful. They need to be converted to the packed 32-bit binary formats.

How to do it...

The Python socket library has utilities to deal with the various IP address formats. Here, we will use two of them: inet_aton() and inet_ntoa().

Let us create the convert_ip4_address() function, where inet_aton() and inet_ntoa() will be used for the IP address conversion. We will use two sample IP addresses, 127.0.0.1 and 192.168.0.1.

Listing 1.3 shows ip4_address_conversion as follows:

#!/usr/bin/env python
# Python Network Programming Cookbook,
Second Edition -- Chapter - 1 # This program is optimized for Python 2.7.12 and
Python 3.5.2. # It may run on any other version with/without
modifications. import socket from binascii import hexlify def convert_ip4_address(): for ip_addr in ['127.0.0.1', '192.168.0.1']: packed_ip_addr = socket.
inet_aton(ip_addr) unpacked_ip_addr = socket.inet_ntoa
(packed_ip_addr) print ("IP Address: %s => Packed: %s,
Unpacked: %s" %(ip_addr,
hexlify(packed_ip_addr),
unpacked_ip_addr)) if __name__ == '__main__': convert_ip4_address()

Now, if you run this recipe, you will see the following output:

$ python 1_3_ip4_address_conversion.py 
IP Address: 127.0.0.1 => Packed: 7f000001, Unpacked: 
127.0.0.1
IP Address: 192.168.0.1 => Packed: c0a80001, Unpacked: 192.168.0.1

How it works...

In this recipe, the two IP addresses have been converted from a string to a 32-bit packed format using a for-in statement. Additionally, the Python hexlify function is called from the binascii module. This helps to represent the binary data in a hexadecimal format.

Finding a service name, given the port and protocol

If you would like to discover network services, it may be helpful to determine what network services run on which ports using either the TCP or UDP protocol.

Getting ready

If you know the port number of a network service, you can find the service name using the getservbyport() socket class function from the socket library. You can optionally give the protocol name when calling this function.

How to do it...

Let us define a find_service_name() function, where the getservbyport() socket class function will be called with a few ports, for example, 80, 25. We can use Python's for-in loop construct.

Listing 1.4 shows finding_service_name as follows:

#!/usr/bin/env python 
# Python Network Programming Cookbook, Second Edition -- Chapter - 1 
# This program is optimized for Python 2.7.12 and Python 3.5.2. 
# It may run on any other version with/without modifications. 
 
import socket 
 
def find_service_name(): 
    protocolname = 'tcp' 
    for port in [80, 25]: 
        print ("Port: %s => service name: %s" %(port, socket.getservbyport(port, protocolname))) 
     
    print ("Port: %s => service name: %s" %(53, socket.getservbyport(53, 'udp'))) 
     
if __name__ == '__main__': 
    find_service_name() 
 

If you run this script, you will see the following output:

$ python 1_4_finding_service_name.py 
    
Port: 80 => service name: http
Port: 25 => service name: smtp
Port: 53 => service name: domain
    

This indicates that http, smtp, and domain services are running on the ports 80, 25, and 53 respectively.

How it works...

In this recipe, the for-in statement is used to iterate over a sequence of variables. So for each iteration, we use one IP address to convert them in their packed and unpacked format.

Converting integers to and from host to network byte order

If you ever need to write a low-level network application, it may be necessary to handle the low-level data transmission over the wire between two machines. This operation requires some sort of conversion of data from the native host operating system to the network format and vice versa. This is because each one has its own specific representation of data.

How to do it...

Python's socket library has utilities for converting from a network byte order to host byte order and vice versa. You may want to become familiar with them, for example, ntohl()/htonl().

Let us define the convert_integer() function, where the ntohl()/htonl() socket class functions are used to convert IP address formats.

Listing 1.5 shows integer_conversion as follows:

#!/usr/bin/env python 
# Python Network Programming Cookbook, Second Edition -- Chapter - 1 
# This program is optimized for Python 2.7.12 and Python 3.5.2. 
# It may run on any other version with/without modifications. 
 
import socket 
 
def convert_integer(): 
    data = 1234 
    # 32-bit 
    print ("Original: %s => Long  host byte order: %s, Network byte order: %s" %(data, socket.ntohl(data), socket.htonl(data))) 
    # 16-bit 
    print ("Original: %s => Short  host byte order: %s, Network byte order: %s" %(data, socket.ntohs(data), socket.htons(data))) 
 
     
if __name__ == '__main__': 
    convert_integer() 
 

If you run this recipe, you will see the following output:

$ python 1_5_integer_conversion.py 
Original: 1234 => Long  host byte order: 3523477504, 
Network byte order: 3523477504
Original: 1234 => Short host byte order: 53764,
Network byte order: 53764

How it works...

Here, we take an integer and show how to convert it between network and host byte orders. The ntohl() socket class function converts from the network byte order to host byte order in a long format. Here, n represents network and h represents host; l represents long and s represents short, that is, 16-bit.

Setting and getting the default socket timeout

Sometimes, you need to manipulate the default values of certain properties of a socket library, for example, the socket timeout.

How to do it...

You can make an instance of a socket object and call a gettimeout() method to get the default timeout value and the settimeout() method to set a specific timeout value. This is very useful in developing custom server applications.

We first create a socket object inside a test_socket_timeout() function. Then, we can use the getter/setter instance methods to manipulate timeout values.

Listing 1.6 shows socket_timeout as follows:

#!/usr/bin/env python 
# Python Network Programming Cookbook, Second Edition -- Chapter - 1 
# This program is optimized for Python 2.7.12 and Python 3.5.2. 
# It may run on any other version with/without modifications. 
 
 
import socket 
 
def test_socket_timeout(): 
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    print ("Default socket timeout: %s" %s.gettimeout()) 
    s.settimeout(100) 
    print ("Current socket timeout: %s" %s.gettimeout())     
     
if __name__ == '__main__': 
    test_socket_timeout() 
 
 

After running the preceding script, you can see how this modifies the default socket timeout as follows:

$ python 1_6_socket_timeout.py 
Default socket timeout: None
Current socket timeout: 100.0
  

How it works...

In this code snippet, we have first created a socket object by passing the socket family and socket type as the first and second arguments of the socket constructor. Then, you can get the socket timeout value by calling gettimeout() and alter the value by calling the settimeout() method. The timeout value passed to the settimeout() method can be in seconds (non-negative float) or None. This method is used for manipulating the blocking-socket operations. Setting a timeout of None disables timeouts on socket operations.

Handling socket errors gracefully

In any networking application, it is very common that one end is trying to connect, but the other party is not responding due to networking media failure or any other reason. The Python socket library has an elegant method of handing these errors via the socket.error exceptions. In this recipe, a few examples are presented.

How to do it...

Let us create a few try-except code blocks and put one potential error type in each block. In order to get a user input, the argparse module can be used. This module is more powerful than simply parsing command-line arguments using sys.argv. In the try-except blocks, put typical socket operations, for example, create a socket object, connect to a server, send data, and wait for a reply.

The following recipe illustrates the concepts in a few lines of code.

Listing 1.7 shows socket_errors as follows:

#!/usr/bin/env python 
# Python Network Programming Cookbook, Second Edition -- Chapter - 1 
# This program is optimized for Python 2.7.12 and Python 3.5.2. 
# It may run on any other version with/without modifications. 
 
import sys 
import socket 
import argparse  
 
 
def main(): 
    # setup argument parsing 
    parser = argparse.ArgumentParser(description='Socket Error Examples') 
    parser.add_argument('--host', action="store", dest="host",
required=False) parser.add_argument('--port', action="store", dest="port", type=int,
required=False) parser.add_argument('--file', action="store", dest="file",
required=False) given_args = parser.parse_args() host = given_args.host port = given_args.port filename = given_args.file # First try-except block -- create socket try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) except socket.error as e: print ("Error creating socket: %s" % e) sys.exit(1) # Second try-except block -- connect to given host/port try: s.connect((host, port)) except socket.gaierror as e: print ("Address-related error connecting to
server: %s" % e) sys.exit(1) except socket.error as e: print ("Connection error: %s" % e) sys.exit(1) # Third try-except block -- sending data try: msg = "GET %s HTTP/1.0\r\n\r\n" % filename s.sendall(msg.encode('utf-8')) except socket.error as e: print ("Error sending data: %s" % e) sys.exit(1) while 1: # Fourth tr-except block -- waiting
to receive
data from remote host try: buf = s.recv(2048) except socket.error as e: print ("Error receiving data: %s" % e) sys.exit(1) if not len(buf): break # write the received data sys.stdout.write(buf.decode('utf-8')) if __name__ == '__main__': main()

How it works...

In Python, passing command-line arguments to a script and parsing them in the script can be done using the argparse module. This is available in Python 2.7. For earlier versions of Python, this module is available separately in Python Package Index (PyPI). You can install this via easy_install or pip.

In this recipe, three arguments are set up—a hostname, port number, and filename. The usage of this script is as follows:

$ python 1_7_socket_errors.py --host=<HOST> 
--port=<PORT> --file=<FILE>
In the preceding recipe, msg.encode('utf-8')
encodes the message into UTF-8, and
buf.decode('utf-8') decodes the received UTF-8
format.

If you try the preceding recipe with a non-existent host, this script will print an address error as follows:

$ python 1_7_socket_errors.py 
--host=www.pytgo.org --port=8080
--file=1_7_socket_errors.py
Address-related error connecting to
server: [Errno -2] Name or service not known

If there is no service on a specific port and if you try to connect to that port, then this will throw a connection timeout error as follows:

$ python 1_7_socket_errors.py 
--host=www.python.org --port=8080
--file=1_7_socket_errors.py

This will return the following error since the host, www.python.org, is not listening on port 8080:

Connection error: [Errno 110] Connection timed out
  

However, if you send an arbitrary request as a correct request to a correct port, the error may not be caught at the application level. For example, running the following script returns no error, but the HTML output tells us what's wrong with this script:

$ python 1_7_socket_errors.py 
--host=www.python.org --port=80
--file=1_7_socket_errors.py
HTTP/1.1 500 Domain Not Found Server: Varnish Retry-After: 0 content-type: text/html Cache-Control: private, no-cache connection: keep-alive Content-Length: 179 Accept-Ranges: bytes Date: Thu, 01 Jun 2017 22:02:24 GMT Via: 1.1 varnish Connection: close <html> <head> <title>Fastly error: unknown domain </title> </head> <body> Fastly error: unknown domain: . Please check that this domain has been added to a service.</body></html>

In the preceding example, four try-except blocks have been used. All blocks use socket.error except for the second block, which uses socket.gaierror. This is used for address-related errors. There are two other types of exceptions—socket.herror is used for legacy C API, and if you use the settimeout() method in a socket, socket.timeout will be raised when a timeout occurs on that socket.

Modifying a socket's send/receive buffer sizes

The default socket buffer size may not be suitable in many circumstances. In such circumstances, you can change the default socket buffer size to a more suitable value.

How to do it...

Let us manipulate the default socket buffer size using a socket object's setsockopt() method.

First, define two constants: SEND_BUF_SIZE/RECV_BUF_SIZE and then wrap a socket instance's call to the setsockopt() method in a function. It is also a good idea to check the value of the buffer size before modifying it. Note that we need to set up the send and receive buffer size separately.

Listing 1.8 shows how to modify socket send/receive buffer sizes as follows:

#!/usr/bin/env python 
# Python Network Programming Cookbook, Second Edition -- Chapter - 1 
# This program is optimized for Python 2.7.12 and Python 3.5.2. 
# It may run on any other version with/without modifications. 
 
import socket 
 
SEND_BUF_SIZE = 4096 
RECV_BUF_SIZE = 4096 
 
def modify_buff_size(): 
    sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) 
     
    # Get the size of the socket's send buffer 
    bufsize = sock.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF) 
    print ("Buffer size [Before]:%d" %bufsize) 
     
    sock.setsockopt(socket.SOL_TCP, 
socket.TCP_NODELAY, 1) sock.setsockopt( socket.SOL_SOCKET, socket.SO_SNDBUF, SEND_BUF_SIZE) sock.setsockopt( socket.SOL_SOCKET, socket.SO_RCVBUF, RECV_BUF_SIZE) bufsize = sock.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF) print ("Buffer size [After]:%d" %bufsize) if __name__ == '__main__': modify_buff_size()

If you run the preceding script, it will show the changes in the socket's buffer size. The following output may be different on your machine depending on your operating system's local settings:

$ python 1_8_modify_buff_size.py 
Buffer size [Before]:16384
Buffer size [After]:8192  

How it works...

You can call the getsockopt() and setsockopt() methods on a socket object to retrieve and modify the socket object's properties respectively. The setsockopt() method takes three arguments: level, optname, and value. Here, optname takes the option name and value is the corresponding value of that option. For the first argument, the needed symbolic constants can be found in the socket module (SO_*etc.).

Changing a socket to the blocking/non-blocking mode

By default, TCP sockets are placed in a blocking mode. This means the control is not returned to your program until some specific operation is complete. If you call the connect() API, the connection blocks your program until the operation is complete. On many occasions, you don't want to keep your program waiting forever, either for a response from the server or for any error to stop the operation. For example, when you write a web browser client that connects to a web server, you should consider a stop functionality that can cancel the connection process in the middle of this operation. This can be achieved by placing the socket in the non-blocking mode.

How to do it...

Let us see what options are available under Python. In Python, a socket can be placed in the blocking or non-blocking mode. In the non-blocking mode, if any call to API, for example, send() or recv(), encounters any problem, an error will be raised. However, in the blocking mode, this will not stop the operation. We can create a normal TCP socket and experiment with both the blocking and non-blocking operations.

To manipulate the socket's blocking nature, we should create a socket object first.

We can then call setblocking(1) to set up blocking or setblocking(0) to unset blocking. Finally, we bind the socket to a specific port and listen for incoming connections.

Listing 1.9 shows how the socket changes to blocking or non-blocking mode as follows:

#!/usr/bin/env python 
# Python Network Programming Cookbook, Second Edition -- Chapter - 1 
# This program is optimized for Python 2.7.12 and Python 3.5.2. 
# It may run on any other version with/without modifications. 
 
import socket 
 
def test_socket_modes(): 
    s = socket.socket(socket.AF_INET, 
socket.SOCK_STREAM) s.setblocking(1) s.settimeout(0.5) s.bind(("127.0.0.1", 0)) socket_address = s.getsockname() print ("Trivial Server launched on
socket: %s" %str(socket_address)) while(1): s.listen(1) if __name__ == '__main__': test_socket_modes()

If you run this recipe, it will launch a trivial server that has the blocking mode enabled as shown in the following command:

$ python 1_9_socket_modes.py 
Trivial Server launched on 
socket: ('127.0.0.1', 51410)

How it works...

In this recipe, we enable blocking on a socket by setting the value 1 in the setblocking() method. Similarly, you can unset the value 0 in this method to make it non-blocking.

This feature will be reused in some later recipes, where its real purpose will be elaborated.

Reusing socket addresses

You want to run a socket server always on a specific port even after it is closed intentionally or unexpectedly. This is useful in some cases where your client program always connects to that specific server port. So, you don't need to change the server port.

How to do it...

If you run a Python socket server on a specific port and try to rerun it after closing it once, you won't be able to use the same port. It will usually throw an error like the following command:

Traceback (most recent call last):
   File "1_10_reuse_socket_address.py", 
line 40, in <module>
reuse_socket_addr() File "1_10_reuse_socket_address.py",
line 25, in reuse_socket_addr
srv.bind( ('', local_port) ) File "<string>", line 1, in bind socket.error: [Errno 98] Address
already in use

The remedy to this problem is to enable the socket reuse option, SO_REUSEADDR.

After creating a socket object, we can query the state of address reuse, say an old state. Then, we call the setsockopt() method to alter the value of its address reuse state. Then, we follow the usual steps of binding to an address and listening for incoming client connections.

In the preceding example, when you close the Python script with Ctrl + C, you notice an exception:

^CTraceback (most recent call last):File "1_9_socket_modes.py", line 20, in <module>
test_socket_modes()
File "1_9_socket_modes.py", line 17, in test_socket_modes
s.listen(1)
KeyboardInterrupt

This indicates that there was a keyboard interrupt in the execution.

In this example, we catch the KeyboardInterrupt exception so that if you issue Ctrl + C, then the Python script gets terminated without showing any exception message.

Listing 1.10 shows how to reuse socket addresses as follows:

#!/usr/bin/env python 
# Python Network Programming Cookbook, Second Edition -- Chapter - 1 
# This program is optimized for Python 2.7.12 and Python 3.5.2. 
# It may run on any other version with/without modifications. 
 
import socket 
import sys 
 
 
def reuse_socket_addr(): 
    sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) 
 
    # Get the old state of the SO_REUSEADDR option 
    old_state = sock.getsockopt(socket.SOL_SOCKET, 
socket.SO_REUSEADDR ) print ("Old sock state: %s" %old_state) # Enable the SO_REUSEADDR option sock.setsockopt( socket.SOL_SOCKET,
socket.SO_REUSEADDR, 1 ) new_state = sock.getsockopt(
socket.SOL_SOCKET, socket.SO_REUSEADDR ) print ("New sock state: %s" %new_state) local_port = 8282 srv = socket.socket(socket.AF_INET,
socket.SOCK_STREAM) srv.setsockopt(socket.SOL_SOCKET,
socket.SO_REUSEADDR, 1) srv.bind( ('', local_port) ) srv.listen(1) print ("Listening on port: %s " %local_port) while True: try: connection, addr = srv.accept() print ('Connected by %s:%s'
% (addr[0], addr[1])) except KeyboardInterrupt: break except socket.error as msg: print ('%s' % (msg,)) if __name__ == '__main__': reuse_socket_addr()

The output from this recipe will be similar to the outcomes produced here, by executing the program:

$ python 1_10_reuse_socket_address.py 
Old sock state: 0
New sock state: 1
Listening on port: 8282 
  

How it works...

You may run this script from one console window and try to connect to this server from another console window by typing telnet localhost 8282.

You will see an output printed in the program window as your telnet connects to it:

Connected by 127.0.0.1:46584  

Here the host and port will defer based on the telnet instance that you are sending this request from.

After you close the server program, you can rerun it again on the same port. However, if you comment out the line that sets the SO_REUSEADDR, the server will not run for the second time.

Printing the current time from the internet time server

Many programs rely on the accurate machine time, such as the make command in UNIX. Your machine time may be different and need synchronizing with another time server in your network.

Getting ready

In order to synchronize your machine time with one of the internet time servers, you can write a Python client for that. For this, ntplib will be used. Here, the client/server conversation will be done using Network Time Protocol (NTP). If ntplib is not installed on your machine, you can get it from PyPI with the following command using pip or easy_install:

$ pip install ntplib
  

If pip is not installed on your computer, first install it before executing the preceding command. In Debian-based Linux distributions such as Ubuntu, this can be installed by:

$ sudo apt install python-pip
  

Note that you will need to install pip for Python 3 separately if you are running it along side Python 2, as typically Python 2 is set as the default version:

$ sudo apt-get install python3-pip
  

Similarly, ntplib needs to be installed for python3-pip (also called pip3) separately:

$ pip3 install ntplib  

It is a good idea to upgrade pip to the latest version if you are running an outdated version, by issuing the following command:

$ pip install --upgrade pip  

or:

$ pip3 install --upgrade pip  

If Python 2 and Python 3 are installed alongside in your computer then use pip3.

I am using the pip version 9.0.1, for both Python 2 and Python 3. This is the latest version at the time of writing.

How to do it...

We create an instance of NTPClient and then we call the request() method on it by passing the NTP server address.

Listing 1.11 shows how to print the current time from the internet time server as follows:

    #!/usr/bin/env python
    # Python Network Programming Cookbook, 
Second Edition -- Chapter - 1 # This program is optimized for Python 2.7.12
and Python 3.5.2. # It may run on any other version with/without
modifications. import ntplib from time import ctime def print_time(): ntp_client = ntplib.NTPClient() response = ntp_client.request('pool.ntp.org') print (ctime(response.tx_time)) if __name__ == '__main__': print_time()

In my machine, this recipe shows the following output:

$ python 1_11_print_machine_time.py 
Fri Jun  2 16:01:35 2017
  

How it works...

Here, an NTP client has been created and an NTP request has been sent to one of the internet NTP servers, pool.ntp.org. The ctime() function is used for printing the response.

Writing an SNTP client

Unlike the previous recipe, sometimes, you don't need to get the precise time from the NTP server. You can use a simpler version of NTP called simple network time protocol.

How to do it...

Let us create a plain SNTP client without using any third-party library.

Let us first define two constants: NTP_SERVER and TIME1970. NTP_SERVER is the server address to which our client will connect, and TIME1970 is the reference time on January 1, 1970 (also called Epoch). You may find the value of the Epoch time or convert to the Epoch time at http://www.epochconverter.com/. The actual client creates a UDP socket (SOCK_DGRAM) to connect to the server following the UDP protocol. The client then needs to send the SNTP protocol data ('\x1b' + 47 * '\0') in a packet. Our UDP client sends and receives data using the sendto() and recvfrom() methods.

When the server returns the time information in a packed array, the client needs a specialized struct module to unpack the data. The only interesting data is located in the 11th element of the array. Finally, we need to subtract the reference value, TIME1970, from the unpacked value to get the actual current time.

Listing 1.12 shows how to write an SNTP client as follows:

    #!/usr/bin/env python
    # Python Network Programming Cookbook, 
Second Edition -- Chapter - 1 # This program is optimized for Python 2.7.12
and Python 3.5.2. # It may run on any other version with/without
modifications. import socket import struct import sys import time NTP_SERVER = "0.uk.pool.ntp.org" TIME1970 = 2208988800 def sntp_client(): client = socket.socket( socket.AF_INET,
socket.SOCK_DGRAM ) data = '\x1b' + 47 * '\0' client.sendto( data.encode('utf-8'),
( NTP_SERVER, 123 )) data, address = client.recvfrom( 1024 ) if data: print ('Response received
from:', address) t = struct.unpack( '!12I', data )[10] t -= TIME1970 print ('\tTime=%s' % time.ctime(t)) if __name__ == '__main__': sntp_client()

This recipe prints the current time from the internet time server received with the SNTP protocol as follows:

$ python 1_12_sntp_client.py 
('Response received from:', 
('192.146.137.13', 123))
Time=Sat Jun 3 14:45:45 2017

How it works...

This SNTP client creates a socket connection and sends the protocol data. After receiving the response from the NTP server (in this case, 0.uk.pool.ntp.org), it unpacks the data with struct. Finally, it subtracts the reference time, which is January 1, 1970, and prints the time using the ctime() built-in method in the Python time module.

Writing a simple TCP echo client/server application

After testing with basic socket APIs in Python, let us create a TCP socket server and client now. Here, you will have the chance to utilize your basic knowledge gained in the previous recipes.

How to do it...

In this example, a server will echo whatever it receives from the client. We will use the Python argparse module to specify the TCP port from a command line. Both the server and client script will take this argument.

First, we create the server. We start by creating a TCP socket object. Then, we set the reuse address so that we can run the server as many times as we need. We bind the socket to the given port on our local machine. In the listening stage, we make sure we listen to multiple clients in a queue using the backlog argument to the listen() method. Finally, we wait for the client to be connected and send some data to the server. When the data is received, the server echoes back the data to the client.

Listing 1.13a shows how to write a simple TCP echo client/server application as follows:

    #!/usr/bin/env python
    # Python Network Programming Cookbook,
Second Edition -- Chapter - 1 # This program is optimized for Python 2.7.12
and Python 3.5.2. # It may run on any other version with/without
modifications. import socket import sys import argparse host = 'localhost' data_payload = 2048 backlog = 5 def echo_server(port): """ A simple echo server """ # Create a TCP socket sock = socket.socket(socket.AF_INET,
socket.SOCK_STREAM) # Enable reuse address/port sock.setsockopt(socket.SOL_SOCKET,
socket.SO_REUSEADDR, 1) # Bind the socket to the port server_address = (host, port) print ("Starting up echo server on %s
port %s" % server_address) sock.bind(server_address) # Listen to clients, backlog argument
specifies the max no.
of queued connections sock.listen(backlog) while True: print ("Waiting to receive message
from client") client, address = sock.accept() data = client.recv(data_payload) if data: print ("Data: %s" %data) client.send(data) print ("sent %s bytes back
to %s" % (data, address)) # end connection client.close() if __name__ == '__main__': parser = argparse.ArgumentParser
(description='Socket Server Example') parser.add_argument('--port',
action="store", dest="port", type=int,
required=True) given_args = parser.parse_args() port = given_args.port echo_server(port)

On the client side code, we create a client socket using the port argument and connect to the server. Then, the client sends the message, Test message. This will be echoed to the server, and the client immediately receives the message back in a few segments. Here, two try-except blocks are constructed to catch any exception during this interactive session.

Listing 1-13b shows the TCP echo client as follows:

#!/usr/bin/env python 
# Python Network Programming Cookbook,
Second Edition -- Chapter - 1 # This program is optimized for Python 2.7.12
and Python 3.5.2. # It may run on any other version with/without modifications. import socket import sys import argparse host = 'localhost' def echo_client(port): """ A simple echo client """ # Create a TCP/IP socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Connect the socket to the server server_address = (host, port) print ("Connecting to %s port %s" % server_address) sock.connect(server_address) # Send data try: # Send data message = "Test message. This will be
echoed" print ("Sending %s" % message) sock.sendall(message.encode('utf-8')) # Look for the response amount_received = 0 amount_expected = len(message) while amount_received < amount_expected: data = sock.recv(16) amount_received += len(data) print ("Received: %s" % data) except socket.error as e: print ("Socket error: %s" %str(e)) except Exception as e: print ("Other exception: %s" %str(e)) finally: print ("Closing connection to the server") sock.close() if __name__ == '__main__': parser = argparse.ArgumentParser
(description='Socket Server Example') parser.add_argument('--port', action="store",
dest="port", type=int, required=True) given_args = parser.parse_args() port = given_args.port echo_client(port)

How it works...

In order to see the client/server interactions, launch the following server script in one console:

$ python 1_13a_echo_server.py --port=9900 
Starting up echo server  on localhost port 9900 
    
Waiting to receive message from client 
  

Now, run the client from another Terminal as follows:

$ python 1_13b_echo_client.py --port=9900 
Connecting to localhost port 9900 
Sending Test message. This will be echoed 
Received: Test message. Th 
Received: is will be echoe 
Received: d 
Closing connection to the server
  

Upon receiving the message from the client, the server will also print something similar to the following message:

Data: Test message. This will be echoed 
sent Test message. This will be echoed 
bytes back to ('127.0.0.1', 42961)
Waiting to receive message from client

Writing a simple UDP echo client/server application

As we have developed a simple TCP server and client in the previous recipe, we will now look at how to develop the same with UDP.

How to do it...

This recipe is similar to the previous one, except this one is with UDP. The method recvfrom() reads the messages from the socket and returns the data and the client address.

Listing 1.14a shows how to write a simple UDP echo client/server application as follows:

#!/usr/bin/env python 
# Python Network Programming Cookbook,
Second Edition -- Chapter - 1 # This program is optimized for Python 2.7.12
and Python 3.5.2. # It may run on any other version with/without
modifications. import socket import sys import argparse host = 'localhost' data_payload = 2048 def echo_server(port): """ A simple echo server """ # Create a UDP socket sock = socket.socket(socket.AF_INET,
socket.SOCK_DGRAM) # Bind the socket to the port server_address = (host, port) print ("Starting up echo server
on %s port %s" % server_address) sock.bind(server_address) while True: print ("Waiting to receive message
from client") data, address = sock.
recvfrom(data_payload) print ("received %s bytes
from %s" % (len(data), address)) print ("Data: %s" %data) if data: sent = sock.sendto(data, address) print ("sent %s bytes back
to %s" % (sent, address)) if __name__ == '__main__': parser = argparse.ArgumentParser
(description='Socket Server Example') parser.add_argument('--port', action="store", dest="port", type=int, required=True) given_args = parser.parse_args() port = given_args.port echo_server(port)

On the client side code, we create a client socket using the port argument and connect to the server, as we did in the previous recipe. Then, the client sends the message, Test message. This will be echoed, and the client immediately receives the message back in a few segments.

Listing 1-14b shows the echo client as follows:

#!/usr/bin/env python 
# Python Network Programming Cookbook, Second Edition -- Chapter - 1 
# This program is optimized for Python 2.7.12 and Python 3.5.2. 
# It may run on any other version with/without modifications. 
 
import socket 
import sys 
import argparse 
 
host = 'localhost' 
data_payload = 2048 
 
def echo_client(port): 
    """ A simple echo client """ 
    # Create a UDP socket 
    sock = socket.socket(socket.AF_INET, 
socket.SOCK_DGRAM) server_address = (host, port) print ("Connecting to %s port %s" % server_address) message = 'This is the message. It will be
repeated.' try: # Send data message = "Test message. This will be
echoed" print ("Sending %s" % message) sent = sock.sendto(message.encode
('utf-8'), server_address) # Receive response data, server = sock.recvfrom(data_payload) print ("received %s" % data) finally: print ("Closing connection to the server") sock.close() if __name__ == '__main__': parser = argparse.ArgumentParser
(description='Socket Server Example') parser.add_argument('--port', action="store", dest="port", type=int, required=True) given_args = parser.parse_args() port = given_args.port echo_client(port)
Downloading the example code
Detailed steps to download the code bundle are mentioned in the Preface of this book. The code bundle for the book is also hosted on GitHub at: https://github.com/PacktPublishing/Python-Network-Programming-Cookbook-Second-Edition. We also have other code bundles from our rich catalog of books and videos available at: https://github.com/PacktPublishing/. Check them out!

How it works...

In order to see the client/server interactions, launch the following server script in one console:

$ python 1_14a_echo_server_udp.py --port=9900 
Starting up echo server on localhost port 9900
Waiting to receive message from client
  

Now, run the client from another terminal as follows:

$ python 1_14b_echo_client_udp.py --port=9900 
Connecting to localhost port 9900
Sending Test message. This will be echoed
received Test message. This will be echoed
Closing connection to the server
    
  

Upon receiving the message from the client, the server will also print something similar to the following message:

received 33 bytes from ('127.0.0.1', 43542)
Data: Test message. This will be echoed
sent 33 bytes back to ('127.0.0.1', 43542)
Waiting to receive message from client
  
Left arrow icon Right arrow icon

Key benefits

  • ?Solve real-world tasks in the area of network programming, system/networking administration, network monitoring, and more.
  • ?Familiarize yourself with the fundamentals and functionalities of SDN
  • ?Improve your skills to become the next-gen network engineer by learning the various facets of Python programming

Description

Python Network Programming Cookbook - Second Edition highlights the major aspects of network programming in Python, starting from writing simple networking clients to developing and deploying complex Software-Defined Networking (SDN) and Network Functions Virtualization (NFV) systems. It creates the building blocks for many practical web and networking applications that rely on various networking protocols. It presents the power and beauty of Python to solve numerous real-world tasks in the area of network programming, network and system administration, network monitoring, and web-application development. In this edition, you will also be introduced to network modelling to build your own cloud network. You will learn about the concepts and fundamentals of SDN and then extend your network with Mininet. Next, you’ll find recipes on Authentication, Authorization, and Accounting (AAA) and open and proprietary SDN approaches and frameworks. You will also learn to configure the Linux Foundation networking ecosystem and deploy and automate your networks with Python in the cloud and the Internet scale. By the end of this book, you will be able to analyze your network security vulnerabilities using advanced network packet capture and analysis techniques.

Who is this book for?

This book is for network engineers, system/network administrators, network programmers, and even web application developers who want to solve everyday network-related problems. If you are a novice, you will develop an understanding of the concepts as you progress with this book.

What you will learn

  • • Develop TCP/IP networking client/server applications
  • • Administer local machines IPv4/IPv6 network interfaces
  • • Write multi-purpose efficient web clients for HTTP and HTTPS protocols
  • • Perform remote system administration tasks over Telnet and SSH connections
  • • Interact with popular websites via web services such as XML-RPC, SOAP, and REST APIs
  • • Monitor and analyze major common network security vulnerabilities
  • • Develop Software-Defined Networks with Ryu, OpenDaylight, Floodlight, ONOS, and POX Controllers
  • • Emulate simple and complex networks with Mininet and its extensions for network and systems emulations
  • • Learn to configure and build network systems and Virtual Network Functions (VNF) in heterogeneous deployment environments
  • • Explore various Python modules to program the Internet

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Aug 09, 2017
Length: 450 pages
Edition : 2nd
Language : English
ISBN-13 : 9781786468475
Languages :
Concepts :

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want

Product Details

Publication date : Aug 09, 2017
Length: 450 pages
Edition : 2nd
Language : English
ISBN-13 : 9781786468475
Languages :
Concepts :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
$199.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts
$279.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total $ 164.97
Python Network Programming Cookbook
$54.99
Mastering Python Networking
$54.99
Python GUI Programming Cookbook, Second Edition
$54.99
Total $ 164.97 Stars icon

Table of Contents

14 Chapters
Sockets, IPv4, and Simple Client/Server Programming Chevron down icon Chevron up icon
Multiplexing Socket I/O for Better Performance Chevron down icon Chevron up icon
IPv6, Unix Domain Sockets, and Network Interfaces Chevron down icon Chevron up icon
Programming with HTTP for the Internet Chevron down icon Chevron up icon
Email Protocols, FTP, and CGI Programming Chevron down icon Chevron up icon
Programming Across Machine Boundaries Chevron down icon Chevron up icon
Working with Web Services – XML-RPC, SOAP, and REST Chevron down icon Chevron up icon
Network Monitoring and Security Chevron down icon Chevron up icon
Network Modeling Chevron down icon Chevron up icon
Getting Started with SDN Chevron down icon Chevron up icon
Authentication, Authorization, and Accounting (AAA) Chevron down icon Chevron up icon
Open and Proprietary Networking Solutions Chevron down icon Chevron up icon
NFV and Orchestration – A Larger Ecosystem Chevron down icon Chevron up icon
Programming the Internet Chevron down icon Chevron up icon

Customer reviews

Rating distribution
Full star icon Full star icon Full star icon Half star icon Empty star icon 3.5
(4 Ratings)
5 star 50%
4 star 0%
3 star 0%
2 star 50%
1 star 0%
ian rust Nov 07, 2021
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Have you ever read a networking textbook? Do you remember all the interesting protocols, SDN systems, network modeling, etc. that was discussed but which you never go to work with? Just kind of read about it and moved on?This is the first cookbook I found in any language that gives such a broad survey of networking. Why that is I don't really know. But show me a cookbook that covers all these topics:multiplexing servers, IPv6, UNIX domain sockets, network interfaces, FTP, CGI, POP3, IMAP, big/little Endian, advanced use of sockets, SMTP, remote shell scripting, SOAP, REST, XML-RPC, network modeling, Mininet, SDN, VMware, BGPThere's alot more advanced stuff I didn't mentionI see people complaining about the initial script. Well... I'd like to point out that the first script runs in Python2. It said run it in Python3, yes this was a mistake but it isn't something anyone that knows python should have any difficulty noticing. I didn't buy the book to complain, I bought it to learn something, and I learned alot from this book.It could have been written better, but the weird fact this sort of material is so hard to find cookbooks on, combined with the fact it's just basic information, is why I have given it 5 stars.
Amazon Verified review Amazon
Blu Wall Tech May 31, 2019
Full star icon Full star icon Full star icon Full star icon Full star icon 5
A lot of the time, you get trapped in the python's ecosystem of network-made-simple tools without any thought. Looking at things from a more broad perspective is always welcome for both teaching and practical purposes.
Amazon Verified review Amazon
H. S. Bassi Feb 24, 2018
Full star icon Full star icon Empty star icon Empty star icon Empty star icon 2
first exercise does not work due to a bits of missing code:fyi: now not looking forward to other Packt pub books i bought due to this.import sockethost_name = socket.gethostname()ip_address = socket.gethostbyname(host_name)print"Host name: %s" %host_nameprint"ip address : %s" %ip_addresswith all these miss use of %s and % it makes so confusing how about making the code more cleaner so people can read it:here is a example of exercise 1.2 rewritten so its more easier to understand with out the fluf :)import socketremote_host = 'www.python.org'print("IP address of" + remote_host + socket.gethostbyname(remote_host))yes i removed the method "def" function as 1 this is not in a class and this code is only doing one function not many methods included in thisi also removed the "try" error handling module as there is no need for it as there is nothing to execute after should it failow and the %s have gone yes i removed the stringing crap out of the code as its confusing for people that want to understand how its working this method above makes it so much more cleaner for some one to read and understand on what the code is doing!PACKT pub please remove the fluf in your book no need for it. also try the exercises before publishing the books
Amazon Verified review Amazon
DNAunion Dec 26, 2017
Full star icon Full star icon Empty star icon Empty star icon Empty star icon 2
I'm getting sick of Packt books. In this one, the very first script is wrong: it left out parentheses and so an error occurs.Packt, a piece of advise: have someone half-way knowledgeable review your books before releasing them to the public.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

How do I buy and download an eBook? Chevron down icon Chevron up icon

Where there is an eBook version of a title available, you can buy it from the book details for that title. Add either the standalone eBook or the eBook and print book bundle to your shopping cart. Your eBook will show in your cart as a product on its own. After completing checkout and payment in the normal way, you will receive your receipt on the screen containing a link to a personalised PDF download file. This link will remain active for 30 days. You can download backup copies of the file by logging in to your account at any time.

If you already have Adobe reader installed, then clicking on the link will download and open the PDF file directly. If you don't, then save the PDF file on your machine and download the Reader to view it.

Please Note: Packt eBooks are non-returnable and non-refundable.

Packt eBook and Licensing When you buy an eBook from Packt Publishing, completing your purchase means you accept the terms of our licence agreement. Please read the full text of the agreement. In it we have tried to balance the need for the ebook to be usable for you the reader with our needs to protect the rights of us as Publishers and of our authors. In summary, the agreement says:

  • You may make copies of your eBook for your own use onto any machine
  • You may not pass copies of the eBook on to anyone else
How can I make a purchase on your website? Chevron down icon Chevron up icon

If you want to purchase a video course, eBook or Bundle (Print+eBook) please follow below steps:

  1. Register on our website using your email address and the password.
  2. Search for the title by name or ISBN using the search option.
  3. Select the title you want to purchase.
  4. Choose the format you wish to purchase the title in; if you order the Print Book, you get a free eBook copy of the same title. 
  5. Proceed with the checkout process (payment to be made using Credit Card, Debit Cart, or PayPal)
Where can I access support around an eBook? Chevron down icon Chevron up icon
  • If you experience a problem with using or installing Adobe Reader, the contact Adobe directly.
  • To view the errata for the book, see www.packtpub.com/support and view the pages for the title you have.
  • To view your account details or to download a new copy of the book go to www.packtpub.com/account
  • To contact us directly if a problem is not resolved, use www.packtpub.com/contact-us
What eBook formats do Packt support? Chevron down icon Chevron up icon

Our eBooks are currently available in a variety of formats such as PDF and ePubs. In the future, this may well change with trends and development in technology, but please note that our PDFs are not Adobe eBook Reader format, which has greater restrictions on security.

You will need to use Adobe Reader v9 or later in order to read Packt's PDF eBooks.

What are the benefits of eBooks? Chevron down icon Chevron up icon
  • You can get the information you need immediately
  • You can easily take them with you on a laptop
  • You can download them an unlimited number of times
  • You can print them out
  • They are copy-paste enabled
  • They are searchable
  • There is no password protection
  • They are lower price than print
  • They save resources and space
What is an eBook? Chevron down icon Chevron up icon

Packt eBooks are a complete electronic version of the print edition, available in PDF and ePub formats. Every piece of content down to the page numbering is the same. Because we save the costs of printing and shipping the book to you, we are able to offer eBooks at a lower cost than print editions.

When you have purchased an eBook, simply login to your account and click on the link in Your Download Area. We recommend you saving the file to your hard drive before opening it.

For optimal viewing of our eBooks, we recommend you download and install the free Adobe Reader version 9.