Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
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
€41.99
Full star icon Full star icon Full star icon Half star icon Empty star icon 3.5 (4 Ratings)
Paperback Aug 2017 450 pages 2nd Edition
eBook
€8.99 €32.99
Paperback
€41.99
Subscription
Free Trial
Renews at €18.99p/m
Arrow left icon
Profile Icon Pradeeban Kathiravelu Profile Icon Gary Berger Profile Icon Dr. M. O. Faruque Sarker
Arrow right icon
€41.99
Full star icon Full star icon Full star icon Half star icon Empty star icon 3.5 (4 Ratings)
Paperback Aug 2017 450 pages 2nd Edition
eBook
€8.99 €32.99
Paperback
€41.99
Subscription
Free Trial
Renews at €18.99p/m
eBook
€8.99 €32.99
Paperback
€41.99
Subscription
Free Trial
Renews at €18.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
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
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
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
Estimated delivery fee Deliver to Estonia

Premium delivery 7 - 10 business days

€25.95
(Includes tracking information)

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 : 9781786463999
Languages :
Concepts :
Tools :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
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
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Estimated delivery fee Deliver to Estonia

Premium delivery 7 - 10 business days

€25.95
(Includes tracking information)

Product Details

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

Packt Subscriptions

See our plans and pricing
Modal Close icon
€18.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
€189.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
€264.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 125.97
Python Network Programming Cookbook
€41.99
Mastering Python Networking
€41.99
Python GUI Programming Cookbook, Second Edition
€41.99
Total 125.97 Stars icon
Banner background image

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
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
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
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela