- Learning Network Programming with Java
- Richard M.Reese
- 3455字
- 2021-08-20 10:41:38
Network addressing concepts
There are different types of network addresses. An address serves to identify a node in a network. For example, the Internetwork Packet Exchange (IPX) protocol was an earlier protocol that was used to access nodes on a network. The X.25 is a protocol suite for Wide Area Network (WAN) packet switching. A MAC address provides a unique identifier for network interfaces at the physical network level. However, our primary interests are IP addresses.
URL/URI/URN
These terms are used to refer to the name and location of an Internet resource. A URI identifies the name of a resource, such as a website, or a file on the Internet. It may contain the name of a resource and its location.
A URL specifies where a resource is located, and how to retrieve it. A protocol forms the first part of the URL, and specifies how data is retrieved. URLs always contain protocol, such as HTTP, or FTP. For example, the following two URLs use different protocols. The first one uses the HTTPS protocol, and the second one uses the FTP protocol:
https://www.packtpub.com/
ftp://speedtest.tele2.net/
Java provides classes to support URIs and URLs. The discussion of these classes begins in the next section. Here, we will discuss URNs in more depth.
A URN identifies the resource but not its location. A URN is like a city's name, while a URL is similar to a city's latitude and longitude. When a resource, such as web page, or file, is moved, the URL for the resource is no longer correct. The URL will need to be updated wherever it is used. A URN specifies the name of a resource but not its location. Some other entity, when supplied with a URN, will return its location. URNs are not used that extensively.
The syntax of a URN is shown next. The <NID>
element is a namespace identifier and <NSS>
is a namespace-specific string:
<URN> ::= "urn:" <NID> ":" <NSS>
For example, the following is a URN specifying as part of a SOAP message to qualify its namespace:
<?xml version='1.0'?> <SOAP:Envelope xmlns:SOAP='urn:schemas-xmlsoap-org:soap.v1'> <SOAP:Body> ... xmlns:i='urn:gargantuan-com:IShop'> ... </SOAP:Body> </SOAP:Envelope>
It is used in other places, such as to identify books using their ISBN. Entering the following URL in a browser will bring up a reference to an EJB book:
https://books.google.com/books?isbn=9781849682381

The syntax of a URN depends on the namespace. The IANA is responsible for the allocation of many Internet resources, including URN namespaces. URNs are still an active area of research. URLs and URNs are both URIs.
Using the URI class
The general syntax of a URI consists of a scheme and a scheme-specific-part:
[scheme:] scheme-specific-part
There are many schemes that are used with a URI, including:
- file: This is used for files systems
- FTP: This is File Transfer Protocol
- HTTP: This is commonly used for websites
- mailto: This is used as part of a mail service
- urn: This is used to identify a resource by name
The scheme-specific-part varies by the scheme that is used. URIs can be categorized as absolute or relative, or as opaque or hierarchical. These distinctions are not of immediate interest to us here, though Java provides methods to determine whether a URI falls into one of these categories.
Creating URI instances
A URI can be created for different schemes using several constructor variations. The simplest way of creating a URI is to use a string argument specifying the URI, as shown here:
URI uri = new URI("https://www.packtpub.com/books/content/support");
The next URI uses a fragment to access a subsection of the Wikipedia article dealing with the normalization of a URL:
uri = new URI("https://en.wikipedia.org/wiki/" + "URL_normalization#Normalization_process");
We can also use the following version of the constructor to specify the scheme, host, path, and fragment of the URI:
uri = new URI("https","en.wikipedia.org","/wiki/URL_normalization", "Normalization_process");
These latter two URIs are identical.
Splitting apart a URI
Java uses the URI
class to represent a URI, and it possesses several methods to extract parts of a URI. The more useful methods are listed in the following table:

There are also several "raw" methods, such as getRawPath
, or getRawFragment
, which return versions of a path or fragment, respectively. This includes special characters, such as the question mark, or character sequences beginning with an asterisk. There are several character categories defining these characters and their use, as documented at http://docs.oracle.com/javase/8/docs/api/java/net/URI.html.
We have developed the following helper method that is used to display URI characteristics:
private static void displayURI(URI uri) { System.out.println("getAuthority: " + uri.getAuthority()); System.out.println("getScheme: " + uri.getScheme()); System.out.println("getSchemeSpecificPart: " + uri.getSchemeSpecificPart()); System.out.println("getHost: " + uri.getHost()); System.out.println("getPath: " + uri.getPath()); System.out.println("getQuery: " + uri.getQuery()); System.out.println("getFragment: " + uri.getFragment()); System.out.println("getUserInfo: " + uri.getUserInfo()); System.out.println("normalize: " + uri.normalize()); }
The next code sequence creates a URI
instance for the Packtpub website and then calls the displayURI
method:
try { URI uri = new URI("https://www.packtpub.com/books/content/support"); displayURI(uri); } catch (URISyntaxException ex) { // Handle exceptions }
The output of this sequence is as follows:
getAuthority: www.packtpub.com
getScheme: https
getSchemeSpecificPart: //www.packtpub.com/books/content/support
getHost: www.packtpub.com
getPath: /books/content/support
getQuery: null
getFragment: null
getUserInfo: null
normalize: https://www.packtpub.com/books/content/support
http://www.packtpub.com
More often, these methods are used to extract relevant information for additional processing.
Using the URL class
One of the easiest ways to connect to a site and retrieve data is through the URL
class. All that you need to provide is the URL for the site and the details of the protocol. An instance of the InetAddress
class will hold an IP address and possibly the hostname for the address.
The URLConnection
class was introduced in Chapter 1, Getting Started with Network Programming. It can also be used to provide access to an Internet resource represented by a URL. We will discuss this class and its use in Chapter 4, Client/Server Development.
Creating URL instances
There are several ways of creating a URL instance. The easiest is to simply provide the URL of the site as the argument of the class' constructor. This is illustrated here where a URL
instance for the Packtpub website is created:
URL url = new URL("http://www.packtpub.com");
A URL requires a protocol to be specified. For example, the following attempt to create a URL will result in a java.net.MalformedURLException: no protocol: www.packtpub.com error message:
url = new URL("www.packtpub.com");
There are several constructor variations. The following two variations will create the same URL. The second one uses parameters for the protocol, host, port number, and file:
url = new URL("http://pluto.jhuapl.edu/"); url = new URL("http", "pluto.jhuapl.edu", 80, "News-Center/index.php");
Splitting apart a URL
It can be useful to know more about a URL. We may not even know what URL we are using if the user entered one that we need to process. There are several methods that support splitting a URL into its components, as summarized in the following table:

We will use the following method to illustrate the methods in the preceding table:
private static void displayURL(URL url) { System.out.println("URL: " + url); System.out.printf(" Protocol: %-32s Host: %-32s\n", url.getProtocol(),url.getHost()); System.out.printf(" Port: %-32d Path: %-32s\n", url.getPort(),url.getPath()); System.out.printf(" Reference: %-32s File: %-32s\n", url.getRef(),url.getFile()); System.out.printf(" Authority: %-32s Query: %-32s\n", url.getAuthority(),url.getQuery()); System.out.println(" User Info: " + url.getUserInfo()); }
The following output demonstrates the output when several URL are used as arguments to this method.
URL: http://www.packpub.com Protocol: http Host: www.packpub.com Port: -1 Path: Reference: null File: Authority: www.packpub.com Query: null User Info: null URL: http://pluto.jhuapl.edu/ Protocol: http Host: pluto.jhuapl.edu Port: -1 Path: / Reference: null File: / Authority: pluto.jhuapl.edu Query: null User Info: null URL: http://pluto.jhuapl.edu:80News-Center/index.php Protocol: http Host: pluto.jhuapl.edu Port: 80 Path: News-Center/index.php Reference: null File: News-Center/index.php Authority: pluto.jhuapl.edu:80 Query: null User Info: null URL: https://en.wikipedia.org/wiki/Uniform_resource_locator#Syntax Protocol: https Host: en.wikipedia.org Port: -1 Path: /wiki/Uniform_resource_locator Reference: Syntax File: /wiki/Uniform_resource_locator Authority: en.wikipedia.org Query: null User Info: null URL: https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=url+syntax Protocol: https Host: www.google.com Port: -1 Path: /webhp Reference: q=url+syntax File: /webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8 Authority: www.google.com Query: sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8 User Info: null URL: https://www.packtpub.com/books/content/support Protocol: https Host: www.packtpub.com Port: -1 Path: /books/content/support Reference: null File: /books/content/support Authority: www.packtpub.com Query: null User Info: null
The URL class also supports opening connections and IO streams. We demonstrated the openConnection
method in Chapter 1, Getting Started with Network Programming. The getContent
method returns the data referenced by the URL. For example, the following applies the method against the Packtpub URL:
url = new URL("http://www.packtpub.com"); System.out.println("getContent: " + url.getContent());
The output is as follows:
sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@5c647e05
This suggests that we need to use an input stream to process the resource. The type of data depends on the URL. This topic is explored with the URLConnection
class that is discussed in Chapter 4, Client/Server Development.
IP addresses and the InetAddress class
An IP address is a numerical value that is used to identify a node, such as a computer, printer, scanner, or a similar device. It is used for network interface addressing, and location addressing. The address, unique in its context, identifies the device. At the same time it constitutes a location in the network. A name designates an entity, such as unusually routed though one or more nodes.
Obtaining information about an address
The InetAddress
class represents an IP address. The IP protocol is a low-level protocol used by the UDP and TCP protocols. An IP address is either a 32-bit or a 128-bit unsigned number that is assigned to a device.
IP addresses have a long history and use two major versions: IPv4 and IPv6. The number 5 was assigned to the Internet Stream Protocol. This was an experimental protocol, but it was never actually referred to as version IPv5 and was not intended for general use.
The InetAddress
class' getAllByName
method will return the IP address for a given URL. In the following example, the addresses associated with www.google.com are displayed:
InetAddress names[] = InetAddress.getAllByName("www.google.com"); for(InetAddress element : names) { System.out.println(element); }
One possible output is as follows. The output will vary depending on the location and time because many web sites have multiple IP addresses assigned to them. In this case, it uses both IPv4 and IPv6 addresses:
www.google.com/74.125.21.105
www.google.com/74.125.21.103
www.google.com/74.125.21.147
www.google.com/74.125.21.104
www.google.com/74.125.21.99
www.google.com/74.125.21.106
www.google.com/2607:f8b0:4002:c06:0:0:0:69
The InetAddress
class possesses several methods to provide access to an IP address. We will introduce them as they become relevant. We start with methods to return its canonical hostname, hostname, and host address. They are used in the following helper method:
private static void displayInetAddressInformation( InetAddress address) { System.out.println(address); System.out.println("CanonicalHostName: " + address.getCanonicalHostName()); System.out.println("HostName: " + address.getHostName()); System.out.println("HostAddress: " + address.getHostAddress()); }
The canonical hostname is a Fully Qualified Domain Name (FQDN). As the term implies, it is the full name of the host, including the top-level domain. The values returned by these methods depend on several factors, including the DNS server. The system provides information regarding entities on the network.
The following sequence uses the display method for the Packtpub website:
InetAddress address = InetAddress.getByName("www.packtpub.com"); displayInetAddressInformation(address);
You will get an output that is similar to the following one:
www.packtpub.com/83.166.169.231
CanonicalHostName: 83.166.169.231
HostAddress: 83.166.169.231
HostName: www.packtpub.com
The InetAddress
class' toString
method returned the hostname, followed by the forward slash and then the host address. The getCanonicalHostName
method, in this case, returned the host address, which is not the FQDN. The method will do its best to return the name but may not be able to depending on the machine's configuration.
Address scoping issues
The scope of an IP address refers to the uniqueness of an IP address. Within a local network, such as those used in many homes and offices, the address may be local to that network. There are three types of scopes:
- Link-local: This is used within a single local subnet that is not connected to the Internet. No routers are present. Allocation of link-local addresses is done automatically when the computer does not have a static IP-address and cannot find a DHCP server.
- Site-local: This is used when the address does not require a global prefix and is unique within a site. It cannot be reached directly from the Internet and requires a mapping service such as NAT.
- Global: As its name implies, the address is unique throughout the Internet.
There are also private addresses that are discussed in the Private addresses in IPv4 and Private addresses in IPv6 sections. The InetAddress
class supports several methods to identify the type of address being used. Most of these methods are self-explanatory, as found in the following table where MC is an abbreviation for multicast:

The addresses types and ranges used are summarized in the following table for IPv4 and IPv6:

Testing reachability
The InetAddress
class' isReachable
method will attempt to determine whether an address can be found. If it can, the method returns true
. The following example demonstrates this method. The getAllByName
method returns an array of an InetAddress
instance available for the URL. The isReachable
method uses an integer argument to specify how long to wait in milliseconds at a maximum before deciding that the address is not reachable:
String URLAddress = "www. packtpub.com"; InetAddress[] addresses = InetAddress.getAllByName(URLAddress); for (InetAddress inetAddress : addresses) { try { if (inetAddress.isReachable(10000)) { System.out.println(inetAddress + " is reachable"); } else { System.out.println(inetAddress + " is not reachable"); } } catch (IOException ex) { // Handle exceptions } }
The URL www.packtpub.com was reachable, as shown here:
www.packtpub.com/83.166.169.231 is reachable
However, www.google.com was not:
www.google.com/173.194.121.52 is not reachable
www.google.com/173.194.121.51 is not reachable
www.google.com/2607:f8b0:4004:809:0:0:0:1014 is not reachable
Your results may vary. The isReachable
method will do its best to determine whether an address is reachable or not. However, its success depends on more than simply whether the address exists. Reasons for failure can include: the server may be down, network response time was too long, or a firewall may be blocking a site. The operating system and JVM settings can also impact how well the method works.
An alternative to this method is to use the RunTime
class' exec
method to execute a ping
command against the URL. However, this is not portable and may still suffer from some of the same factors that impact the success of the isReachable
method.
Introducing the Inet4Address
This address consists of 32 bits, permitting up to 4,294,967,296 (232) addresses. The human readable form of the address consists of four decimal numbers (8 bits), each ranging from 0 to 255. Some of the addresses have been reserved for private networks and multicast addresses.
Early on in the use of IPv4, the first octet (8 bit unit) represented a network number (also called the network prefix or network block), and the remaining bits represented a rest field (host identifier). Later, three classes were used to partition the addresses: A, B, and C. These system have largely fallen into disuse and have been replaced by the Classless Inter-Domain Routing (CIDR). This routing approach allocates addresses on bit boundaries, providing more flexibility. This scheme is called classless in contrast to the earlier class-full systems. In IPv6, 64-bit network identifiers are used.
Private addresses in IPv4
Private networks do not necessarily need global access to the Internet. This results in a series of addresses being allocated for these private networks.

You may recognize that the last set of addresses is used by the home network. A private network often interfaces with the Internet using NAT. This technique maps a local IP address to one accessible on the Internet. It was originally introduced to ease the IPv4 address shortage.
IPv4 address types
There are three address types that are supported in IPv4:
- Unicast: This address is used to identify a single node in a network
- Multicast: This address corresponds to a group of network interfaces. Members will join a group and a message is sent to all members of the group
- Broadcast: This will send a message to all network interfaces on a subnet
The Inet4Address
class supports the IPv4 protocol. We will examine this class in more depth next.
The Inet4Address class
The Inet4Address
class is derived from the InetAddress
class. As a derived class, it does not override many of the InetAddress
class' methods. For example, to obtain an InetAddress
instance, we can use the getByName
method of either class, as shown here:
Inet4Address address; address = (Inet4Address) InetAddress.getByName("www.google.com"); address = (Inet4Address) Inet4Address.getByName("www.google.com");
In either case, the address needs to be cast because the base class method is used in either case. The Inet4Address
class does not add any new methods above and beyond that of the InetAddress
class.
Special IPv4 addresses
There are several special IPv4 addresses, including these two:
- 0.0.0.0: This is called an unspecified IPv4 address (wildcard address) and is normally used when a network interface does not have a IP address and is attempting to obtain one using DHCP.
- 127.0.0.1: This is known as the loopback address. It provides a convenient way to send oneself a message, often for testing purposes.
The isAnyLocalAddress
method will return true
if the address is a wildcard address. This method is demonstrated here, where it returns true
:
address = (Inet4Address) Inet4Address.getByName("0.0.0.0"); System.out.println(address.isAnyLocalAddress());
The isLoopbackAddress
method is shown next and will return true
:
address = (Inet4Address) Inet4Address.getByName("127.0.0.1"); System.out.println(address.isLoopbackAddress());
We will use this frequently to test servers in subsequent chapters.
In addition to these, other special addresses include those used for protocol assignments, IPv6 to IPv4 relay, and testing purposes. More details about these and other special addresses can be found at https://en.wikipedia.org/wiki/IPv4#Special-use_addresses.
Introducing the Inet6Address class
IPv6 addresses use 128 bits (16 octets). This permits up to 2128 addresses. An IPv6 address is written as a series of eight groups, with 4 hexadecimal numbers each, separated by colons. The digits are case insensitive. For example, the IPv6 address for www.google.com is as follows:
2607:f8b0:4002:0c08:0000:0000:0000:0067
An IPv6 address can be simplified in several ways. Leading zeroes in a group can be removed. The previous example can be rewritten as:
2607:f8b0:4002:c08:0:0:0:67
Consecutive groups of zeroes can be replaced with ::
, as shown here:
2607:f8b0:4002:c08::67
IPv6 supports three addressing types:
- Unicast: This specifies a single network interface.
- Anycast: This type of address is assigned to a group of interfaces. When a packet is sent to this group, only one member of the group receives the packet, often the one that is closest.
- Multicast: This sends a packet to all members of a group.
This protocol does not support broadcast addressing. There is much more to IPv6 than an increase in network size. It includes several improvements, such as easier administration, more efficient routing capabilities, simple header formats, and the elimination of the need for NAT.
Private addresses in IPv6
Private address space is available in IPv6. Originally, it used site-local addresses using a block with a prefix of fec0::/10. However, this has been dropped due to problems with its definition, and it was replaced with Unique Local (UL) addresses using the address block fc00::/7
.
These addresses can be generated by anyone and do not need to be coordinated. However, they are not necessarily globally unique. Other private networks can use the same addresses. They cannot be assigned using a global DNS server and are only routable in the local address space.
The Inet6Address class
In general, using the Inet6Address
class is not necessary unless you are developing an IPv6-only application. Most networking operations are handled transparently. The Inet6Address
class is derived from the InetAddress
class. The Inet6Address
class's getByName
method uses its base class, the InetAddrress
class's getAllByName
method, to return the first address that it finds, as shown next. This might not be an IPv6 address:
public static InetAddress getByName(String host) throws UnknownHostException { return InetAddress.getAllByName(host)[0]; }
Note
For some of these examples to work correctly, your router may need to be configured to support an IPv6 Internet connection.
The Inet6Address
class added only one method above and beyond that of the InetAddress
class. This is the isIPv4CompatibleAddress
method that is discussed in the Using IPv4-compatible IPv6 addresses section.
Special IPv6 addresses
There is a block of addresses consisting of 64 network prefixes: 2001:0000::/29
through 2001:01f8::/29
. These are used for special needs. Three have been assigned by IANA:
2001::/32
: This is the teredo tunneling, which is a transition technology from IPv42001:2::/48
: This is used for benchmarking purposes2001:20::/28
: This is used for cryptographic hash identifiers
Most developers will not need to work with these addresses.
Testing for the IP address type
Normally, we are not concerned with whether the IP address is IPv4 or IPv6. The differences between the two are hidden beneath the various protocol levels. When you do need to know the difference, then you can use either of the two approaches. The getAddress
method returns a byte array. You check the size of the byte array to determine if it is IPv4 or IPv6. Or you can use the instanceOf
method. These two approaches are shown here:
byte buffer[] = address.getAddress(); if(buffer.length <= 4) { System.out.println("IPv4 Address"); } else { System.out.println("IPv6 Address"); } if(address instanceof Inet4Address) { System.out.println("IPv4 Address"); } else { System.out.println("IPv6 Address"); }
Using IPv4-compatible IPv6 addresses
The dotted quad notation is a way of expressing an IPv4 address using IPv6. The ::ffff:
prefix is placed in front of either the IPv4 address or its equivalent in hexadecimal. For example, the hexadecimal equivalent of the IPv4 address 74.125.21.105
is 4a7d1569
. Both represent a 32 bit quantity. Thus, any of the following three addresses represent the same website:
address = InetAddress.getByName("74.125.21.105"); address = InetAddress.getByName("::ffff:74.125.21.105"); address = InetAddress.getByName("::ffff:4a7d:1569");
If we used these addresses with the displayInetAddressInformation
method, the output will be identical, as shown here:
/74.125.21.105
CanonicalHostName: yv-in-f105.1e100.net
HostName: yv-in-f105.1e100.net
HostAddress: 74.125.21.105
CanonicalHostName: 83.166.169.231
These are referred to as IPv4-compatible IPv6 addresses.
The Inet6Address
class possesses an isIPv4CompatibleAddress
method. The method returns true
if the address is merely an IPv4 address that is placed inside of an IPv6 address. When this happens, all but the last four bytes are zero.
The following example illustrates how this method can be used. Each address associated with www.google.com is tested to determine whether it is an IPv4 or IPv6 address. If it is an IPv6 address, then the method is applied to it:
try { InetAddress names[] = InetAddress.getAllByName("www.google.com"); for (InetAddress address : names) { if ((address instanceof Inet6Address) && ((Inet6Address) address) .isIPv4CompatibleAddress()) { System.out.println(address + " is IPv4 Compatible Address"); } else { System.out.println(address + " is not a IPv4 Compatible Address"); } } } catch (UnknownHostException ex) { // Handle exceptions }
The output depends on the servers available. The following is one possible output:
www.google.com/173.194.46.48 is not a IPv4 Compatible Address
www.google.com/173.194.46.51 is not a IPv4 Compatible Address
www.google.com/173.194.46.49 is not a IPv4 Compatible Address
www.google.com/173.194.46.52 is not a IPv4 Compatible Address
www.google.com/173.194.46.50 is not a IPv4 Compatible Address
www.google.com/2607:f8b0:4009:80b:0:0:0:2004 is not a IPv4 Compatible Address
An alternative Java 8 solution is as follows:
names = InetAddress.getAllByName("www.google.com"); Arrays.stream(names) .map(address -> { if ((address instanceof Inet6Address) && ((Inet6Address) address) .isIPv4CompatibleAddress()) { return address + " is IPv4 Compatible Address"; } else { return address + " is not IPv4 Compatible Address"; } }) .forEach(result -> System.out.println(result));
- Fundamentals of Linux
- Mobile Web Performance Optimization
- 在最好的年紀(jì)學(xué)Python:小學(xué)生趣味編程
- Access 2010數(shù)據(jù)庫基礎(chǔ)與應(yīng)用項目式教程(第3版)
- Practical Windows Forensics
- Learning ArcGIS Pro
- Go并發(fā)編程實戰(zhàn)
- RESTful Java Web Services(Second Edition)
- Python爬蟲、數(shù)據(jù)分析與可視化:工具詳解與案例實戰(zhàn)
- OpenStack Networking Essentials
- Hands-On JavaScript for Python Developers
- SQL Server 2016 從入門到實戰(zhàn)(視頻教學(xué)版)
- After Effects CC技術(shù)大全
- 百萬在線:大型游戲服務(wù)端開發(fā)
- 實驗編程:PsychoPy從入門到精通