提交 0cc68459 编写于 作者: W wizardforcel

2021-10-12 21:31:01

上级 790f6700
# 序言 # 零、序言
随着互联网上提供的服务越来越多,世界正以前所未有的规模相互联系。从商业交易到嵌入式应用程序(如冰箱中的应用程序)的各种应用程序正在连接到互联网。随着孤立的应用程序不再是常态,应用程序的网络化变得越来越重要。 随着互联网上提供的服务越来越多,世界正以前所未有的规模相互联系。从商业交易到嵌入式应用程序(如冰箱中的应用程序)的各种应用程序正在连接到互联网。随着孤立的应用程序不再是常态,应用程序的网络化变得越来越重要。
...@@ -6,15 +6,15 @@ ...@@ -6,15 +6,15 @@
# 这本书涵盖的内容 # 这本书涵盖的内容
[第一章](1.html "Chapter 1. Getting Started with Network Programming")*网络编程入门*,介绍了基本的网络术语和概念。Java 提供的网络支持用简单的例子加以说明。一个简单的客户/服务器应用程序与服务器的线程版本一起提供。 [第一章](1.html "Chapter 1. Getting Started with Network Programming")*网络编程入门*,介绍了基本的网络术语和概念。Java 提供的网络支持用简单的例子加以说明。一个简单的客户/服务器应用程序与服务器的线程版本一起提供。
[第 2 章](2.html "Chapter 2. Network Addressing")*网络寻址*解释了网络上的节点如何使用地址。介绍了 Java 如何表示这些地址,以及对 IPv4 和 IPv6 的支持。本章还介绍 Java 如何配置各种网络属性。 [第 2 章](2.html "Chapter 2. Network Addressing")*网络寻址*解释了网络上的节点如何使用地址。介绍了 Java 如何表示这些地址,以及对 IPv4 和 IPv6 的支持。本章还介绍 Java 如何配置各种网络属性。
[第 3 章](3.html "Chapter 3. NIO Support for Networking")*NIO 对网络的支持*解释了 NIO 包如何为使用缓冲区和通道的通信提供支持。这些技术以客户/服务器应用程序为例进行了说明。还演示了 NIO 对异步通信的支持。 [第 3 章](3.html "Chapter 3. NIO Support for Networking")*NIO 对网络的支持*解释了 NIO 包如何为使用缓冲区和通道的通信提供支持。这些技术以客户/服务器应用程序为例进行了说明。还演示了 NIO 对异步通信的支持。
[第 4 章](4.html "Chapter 4. Client/Server Development")*客户/服务器开发*介绍了 HTTP 是一种重要且广泛使用的协议。Java 以多种方式提供对该协议的支持。这些技术与如何在 Java 中处理 Cookie 的演示一起进行了说明。 [第 4 章](4.html "Chapter 4. Client/Server Development")*客户/服务器开发*介绍了 HTTP 是一种重要且广泛使用的协议。Java 以多种方式提供对该协议的支持。这些技术与如何在 Java 中处理 Cookie 的演示一起进行了说明。
[第 5 章](5.html "Chapter 5. Peer-to-Peer Networks")*对等网络*讨论了对等网络如何为传统的客户/服务器架构提供灵活的替代方案。介绍了基本的对等概念,并演示了 Java 如何支持这种体系结构。FreePastry 用于说明一个开源对等解决方案框架。 [第 5 章](5.html "Chapter 5. Peer-to-Peer Networks")*对等网络*讨论了对等网络如何为传统的客户/服务器架构提供灵活的替代方案。介绍了基本的对等概念,并演示了 Java 如何支持这种体系结构。FreePastry 用于说明一个开源对等解决方案框架。
[第 6 章](6.html "Chapter 6. UDP and Multicasting")*UDP 和多播*解释了 UDP 是如何替代 TCP 的。它为应用程序跨 Internet 进行通信提供了一种不太可靠但更高效的方式。演示了 Java 对该协议的广泛支持,包括 NIO 支持,以及 UDP 如何支持流媒体。 [第 6 章](6.html "Chapter 6. UDP and Multicasting")*UDP 和多播*解释了 UDP 是如何替代 TCP 的。它为应用程序跨 Internet 进行通信提供了一种不太可靠但更高效的方式。演示了 Java 对该协议的广泛支持,包括 NIO 支持,以及 UDP 如何支持流媒体。
......
# 第一章网络编程入门 # 一、网络编程入门
访问网络(特别是互联网)正成为应用程序的一个重要且经常是必要的功能。应用程序经常需要访问和提供服务。随着**物联网****物联网**)连接越来越多的设备,了解如何接入网络变得至关重要。 访问网络(特别是互联网)正成为应用程序的一个重要且经常是必要的功能。应用程序经常需要访问和提供服务。随着**物联网****物联网**)连接越来越多的设备,了解如何接入网络变得至关重要。
...@@ -21,9 +21,9 @@ ...@@ -21,9 +21,9 @@
网络通信的目的是在其他应用程序之间传输信息。这通过使用缓冲区和通道来实现。缓冲区暂时保存信息,直到应用程序可以处理它为止。通道是简化应用程序之间通信的抽象。NIO 和 NIO.2 包提供了对缓冲区和通道的大部分支持。我们将在[第 3 章](3.html "Chapter 3. NIO Support for Networking")*网络 NIO 支持*中探讨这些技术以及其他技术,如阻塞和非阻塞 IO。 网络通信的目的是在其他应用程序之间传输信息。这通过使用缓冲区和通道来实现。缓冲区暂时保存信息,直到应用程序可以处理它为止。通道是简化应用程序之间通信的抽象。NIO 和 NIO.2 包提供了对缓冲区和通道的大部分支持。我们将在[第 3 章](3.html "Chapter 3. NIO Support for Networking")*网络 NIO 支持*中探讨这些技术以及其他技术,如阻塞和非阻塞 IO。
服务由服务器提供。这方面的一个例子是简单的 echo 服务器,它重新传输发送的内容。更复杂的服务器,如 HTTP 服务器,可以支持广泛的服务以满足广泛的需求。客户/服务器模型及其 Java 支持见[第 3 章](3.html "Chapter 3. NIO Support for Networking")*网络 NIO 支持* 服务由服务器提供。这方面的一个例子是简单的 echo 服务器,它重新传输发送的内容。更复杂的服务器,如 HTTP 服务器,可以支持广泛的服务以满足广泛的需求。客户/服务器模型及其 Java 支持见[第 3 章](3.html "Chapter 3. NIO Support for Networking")*网络 NIO 支持*
另一种服务模式是**对等****P2P**模式)。在这种体系结构中,没有中央服务器,而是一个应用程序网络,通过通信提供服务。该模型由应用程序表示,如 BitTorrent、Skype 和 BBC 的 iPlayer。虽然开发这些类型的应用程序所需的许多支持超出了本书的范围,[第 4 章](4.html "Chapter 4. Client/Server Development")*客户/服务器开发*探讨了 P2P 问题以及 Java 和 JXTA 提供的支持。 另一种服务模式是**对等****P2P**模式)。在这种体系结构中,没有中央服务器,而是一个应用程序网络,通过通信提供服务。该模型由应用程序表示,如 BitTorrent、Skype 和 BBC 的 iPlayer。虽然开发这些类型的应用程序所需的许多支持超出了本书的范围,[第 4 章](4.html "Chapter 4. Client/Server Development")*客户/服务器开发*探讨了 P2P 问题以及 Java 和 JXTA 提供的支持。
IP 在较低级别上用于通过网络发送和接收信息包。我们还将演示**用户数据报协议****UDP****传输控制协议****TCP**通信协议的使用。这些协议是在 IP 之上分层的。UDP 用于广播短数据包或消息,但不保证可靠传递。TCP 比 UDP 更常用,并提供更高级别的服务。我们将在[第 5 章](5.html "Chapter 5. Peer-to-Peer Networks")*对等网络*中介绍这些相关技术的使用。 IP 在较低级别上用于通过网络发送和接收信息包。我们还将演示**用户数据报协议****UDP****传输控制协议****TCP**通信协议的使用。这些协议是在 IP 之上分层的。UDP 用于广播短数据包或消息,但不保证可靠传递。TCP 比 UDP 更常用,并提供更高级别的服务。我们将在[第 5 章](5.html "Chapter 5. Peer-to-Peer Networks")*对等网络*中介绍这些相关技术的使用。
...@@ -172,17 +172,17 @@ NIO 包中使用了三个关键概念: ...@@ -172,17 +172,17 @@ NIO 包中使用了三个关键概念:
`Channel`类及其派生类为提供了一种改进的技术来访问网络上发现的数据,而不是旧技术提供的数据。我们将看到更多这门课。 `Channel`类及其派生类为提供了一种改进的技术来访问网络上发现的数据,而不是旧技术提供的数据。我们将看到更多这门课。
# 客户/服务器架构 # 客户/服务器架构
有几种使用 Java 创建服务器的方法。我们将演示一些简单的方法,并将这些技术的详细讨论推迟到[第 4 章](4.html "Chapter 4. Client/Server Development")*客户/服务器开发*之后。将同时创建客户端和服务器。 有几种使用 Java 创建服务器的方法。我们将演示一些简单的方法,并将这些技术的详细讨论推迟到[第 4 章](4.html "Chapter 4. Client/Server Development")*客户/服务器开发*之后。将同时创建客户端和服务器。
在具有 IP 地址的机器上安装了服务器。在任何给定时间,一台机器上都可能运行多台服务器。当操作系统收到机器上的服务请求时,它还将收到端口号。端口号将标识请求应转发到的服务器。因此,服务器由其 IP 地址和端口号的组合来标识。 在具有 IP 地址的机器上安装了服务器。在任何给定时间,一台机器上都可能运行多台服务器。当操作系统收到机器上的服务请求时,它还将收到端口号。端口号将标识请求应转发到的服务器。因此,服务器由其 IP 地址和端口号的组合来标识。
通常,客户端会向服务器发出请求。服务器将接收请求并发送回响应。请求/响应的性质以及用于通信的协议取决于客户端/服务器。有时会使用一个记录良好的协议,例如**超文本传输协议****HTTP**)。对于更简单的体系结构,会来回发送一系列文本消息。 通常,客户端会向服务器发出请求。服务器将接收请求并发送回响应。请求/响应的性质以及用于通信的协议取决于客户端/服务器。有时会使用一个记录良好的协议,例如**超文本传输协议****HTTP**)。对于更简单的体系结构,会来回发送一系列文本消息。
为了使服务器与发出请求的应用程序通信,使用专用软件发送和接收消息。这个软件叫做套接字。一个套接字位于客户端,另一个套接字位于服务器端。当他们连接时,通信是可能的。有几种不同类型的插座。这些包括数据报套接字;流套接字,经常使用 TCP;和原始套接字,它们通常在 IP 级别工作。我们将重点介绍客户/服务器应用程序的 TCP 套接字。 为了使服务器与发出请求的应用程序通信,使用专用软件发送和接收消息。这个软件叫做套接字。一个套接字位于客户端,另一个套接字位于服务器端。当他们连接时,通信是可能的。有几种不同类型的插座。这些包括数据报套接字;流套接字,经常使用 TCP;和原始套接字,它们通常在 IP 级别工作。我们将重点介绍客户/服务器应用程序的 TCP 套接字。
具体来说,我们将创建一个简单的 echo 服务器。此服务器将从客户端接收文本消息,并立即将其发送回该客户端。该服务器的简单性使我们能够专注于客户-服务器基础。 具体来说,我们将创建一个简单的 echo 服务器。此服务器将从客户端接收文本消息,并立即将其发送回该客户端。该服务器的简单性使我们能够专注于客户-服务器基础。
# 创建一个简单的 echo 服务器 # 创建一个简单的 echo 服务器
...@@ -295,7 +295,7 @@ Localhost 是指当前机器。它有一个特定的 IP 地址:`127.0.0.1`。 ...@@ -295,7 +295,7 @@ Localhost 是指当前机器。它有一个特定的 IP 地址:`127.0.0.1`。
} }
``` ```
这些计划可以作为两个单独的项目或在单个项目中实施。无论哪种方式,首先启动服务器,然后启动客户。服务器启动时,将显示以下内容: 这些计划可以作为两个单独的项目或在单个项目中实施。无论哪种方式,首先启动服务器,然后启动客户。服务器启动时,将显示以下内容:
**简单回音服务器** **简单回音服务器**
...@@ -335,7 +335,7 @@ Localhost 是指当前机器。它有一个特定的 IP 地址:`127.0.0.1`。 ...@@ -335,7 +335,7 @@ Localhost 是指当前机器。它有一个特定的 IP 地址:`127.0.0.1`。
**客户请求:回显!** **客户请求:回显!**
这是实现客户和服务器的一种方法。我们将在后面的章节中增强此实现。 这是实现客户和服务器的一种方法。我们将在后面的章节中增强此实现。
## 使用 Java 8 支持 echo 服务器和客户端 ## 使用 Java 8 支持 echo 服务器和客户端
...@@ -473,7 +473,7 @@ try 块的主体使用无限循环创建一个字节数组来保存当前日期 ...@@ -473,7 +473,7 @@ try 块的主体使用无限循环创建一个字节数组来保存当前日期
## 创建多播客户端 ## 创建多播客户端
客户是使用以下`MulticastClient`类创建的。为了接收消息,客户端必须使用相同的组地址和端口号。在接收消息之前,它必须使用`joinGroup`方法加入组。在这个实现中,它接收 5 条日期和时间消息,显示它们,然后终止。`trim`方法从字符串中删除前导空格和尾随空格。否则,将显示消息的所有 256 字节: 客户是使用以下`MulticastClient`类创建的。为了接收消息,客户端必须使用相同的组地址和端口号。在接收消息之前,它必须使用`joinGroup`方法加入组。在这个实现中,它接收 5 条日期和时间消息,显示它们,然后终止。`trim`方法从字符串中删除前导空格和尾随空格。否则,将显示消息的所有 256 字节:
```java ```java
public class MulticastClient { public class MulticastClient {
...@@ -861,9 +861,9 @@ java -Djavax.net.ssl.trustStore=keystore.jks -Djavax.net.ssl.trustStorePassword= ...@@ -861,9 +861,9 @@ java -Djavax.net.ssl.trustStore=keystore.jks -Djavax.net.ssl.trustStorePassword=
网络应用在当今社会中扮演着越来越重要的角色。随着越来越多的设备连接到 Internet,了解如何构建能够与其他应用程序通信的应用程序非常重要。 网络应用在当今社会中扮演着越来越重要的角色。随着越来越多的设备连接到 Internet,了解如何构建能够与其他应用程序通信的应用程序非常重要。
我们简要地识别并解释了 Java 用于连接网络的几种技术。我们演示了`InetAddress`类如何表示 IP 地址,并在几个示例中使用了该类。使用 UDP、TCP 和 SSL 技术演示了客户/服务器体系结构的基本元素。它们提供不同类型的支持。UDP 速度快,但不如 TCP 可靠或功能强大。TCP 是一种可靠且方便的通信方式,但除非与 SSL 一起使用,否则不安全。 我们简要地识别并解释了 Java 用于连接网络的几种技术。我们演示了`InetAddress`类如何表示 IP 地址,并在几个示例中使用了该类。使用 UDP、TCP 和 SSL 技术演示了客户/服务器体系结构的基本元素。它们提供不同类型的支持。UDP 速度快,但不如 TCP 可靠或功能强大。TCP 是一种可靠且方便的通信方式,但除非与 SSL 一起使用,否则不安全。
说明了 NIO 对缓冲区和通道的支持。这些技术可以提高通信效率。应用程序的可伸缩性对于许多应用程序来说是至关重要的,特别是客户/服务器模型。我们还了解了线程如何支持可伸缩性。 说明了 NIO 对缓冲区和通道的支持。这些技术可以提高通信效率。应用程序的可伸缩性对于许多应用程序来说是至关重要的,特别是客户/服务器模型。我们还了解了线程如何支持可伸缩性。
这些主题中的每一个都将在后面的章节中进行更详细的讨论。这包括 NIO 对可伸缩性的支持、P2P 应用程序的工作方式以及可用于 Java 的各种互操作性技术。 这些主题中的每一个都将在后面的章节中进行更详细的讨论。这包括 NIO 对可伸缩性的支持、P2P 应用程序的工作方式以及可用于 Java 的各种互操作性技术。
......
# 第二章网络寻址 # 二、网络寻址
要使一个程序与另一个程序通信,它必须有一个地址。本章将研究地址的使用,包括互联网地址。我们将在本章第一部分介绍许多基本概念。这包括网络体系结构和用于节点之间通信的协议。 要使一个程序与另一个程序通信,它必须有一个地址。本章将研究地址的使用,包括互联网地址。我们将在本章第一部分介绍许多基本概念。这包括网络体系结构和用于节点之间通信的协议。
...@@ -94,7 +94,7 @@ NIC 有一个 IP 地址,是计算机的一部分。网桥连接两个网段, ...@@ -94,7 +94,7 @@ NIC 有一个 IP 地址,是计算机的一部分。网桥连接两个网段,
有关 OSI 层的更完整协议列表,请参见[https://en.wikipedia.org/wiki/List_of_network_protocols_(OSI_ 模型)](https://en.wikipedia.org/wiki/List_of_network_protocols_(OSI_model))。我们无法解决所有这些协议,我们将重点讨论 Java SDK 支持的更重要的协议。 有关 OSI 层的更完整协议列表,请参见[https://en.wikipedia.org/wiki/List_of_network_protocols_(OSI_ 模型)](https://en.wikipedia.org/wiki/List_of_network_protocols_(OSI_model))。我们无法解决所有这些协议,我们将重点讨论 Java SDK 支持的更重要的协议。
考虑 Web 页面从服务器到客户端的传输方式。当数据发送到客户机时,它将被封装在 HTTP 消息中,HTTP 消息进一步封装在 TCP、IP 和链路级协议消息中,每个消息通常包含一个页眉和页脚。这个封装的头集通过 Internet 发送到目标客户机,在那里为每个封装头提取数据,直到显示原始 HTML 文件。 考虑 Web 页面从服务器到客户端的传输方式。当数据发送到客户端时,它将被封装在 HTTP 消息中,HTTP 消息进一步封装在 TCP、IP 和链路级协议消息中,每个消息通常包含一个页眉和页脚。这个封装的头集通过 Internet 发送到目标客户端,在那里为每个封装头提取数据,直到显示原始 HTML 文件。
幸运的是,我们不需要熟悉这个过程的细节。许多类隐藏了这是如何发生的,从而使我们能够专注于数据。 幸运的是,我们不需要熟悉这个过程的细节。许多类隐藏了这是如何发生的,从而使我们能够专注于数据。
...@@ -525,7 +525,7 @@ Java 使用`URI`类来表示 URI,并且它拥有几种方法来提取 URI 的 ...@@ -525,7 +525,7 @@ Java 使用`URI`类来表示 URI,并且它拥有几种方法来提取 URI 的
连接到站点并检索数据的最简单方法之一是通过`URL`类。您只需要提供站点的 URL 和协议的详细信息。`InetAddress`类的实例将包含一个 IP 地址,可能还有该地址的主机名。 连接到站点并检索数据的最简单方法之一是通过`URL`类。您只需要提供站点的 URL 和协议的详细信息。`InetAddress`类的实例将包含一个 IP 地址,可能还有该地址的主机名。
`URLConnection`课程在[第一章](1.html "Chapter 1. Getting Started with Network Programming")*网络编程入门*中介绍。它还可以用于提供对由 URL 表示的 Internet 资源的访问。我们将在[第 4 章](4.html "Chapter 4. Client/Server Development")*客户/服务器开发*中讨论该类及其使用。 `URLConnection`课程在[第一章](1.html "Chapter 1. Getting Started with Network Programming")*网络编程入门*中介绍。它还可以用于提供对由 URL 表示的 Internet 资源的访问。我们将在[第 4 章](4.html "Chapter 4. Client/Server Development")*客户/服务器开发*中讨论该类及其使用。
### 创建 URL 实例 ### 创建 URL 实例
...@@ -650,7 +650,7 @@ URL 类还支持打开连接和 IO 流。我们在[第一章](1.html "Chapter 1 ...@@ -650,7 +650,7 @@ URL 类还支持打开连接和 IO 流。我们在[第一章](1.html "Chapter 1
**sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@5c647e05** **sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@5c647e05**
这表明我们需要使用输入流来处理资源。数据类型取决于 URL。本主题通过[第 4 章](4.html "Chapter 4. Client/Server Development")*客户/服务器开发*中讨论的`URLConnection`类进行探讨。 这表明我们需要使用输入流来处理资源。数据类型取决于 URL。本主题通过[第 4 章](4.html "Chapter 4. Client/Server Development")*客户/服务器开发*中讨论的`URLConnection`类进行探讨。
## IP 地址和 InetAddress 类 ## IP 地址和 InetAddress 类
......
# 第三章 NIO 对网络的支持 # 三、NIO 对网络的支持
在本章中,我们将重点介绍 Java**新 IO****NIO**)包的`Buffer``Channels`类。NIO 是早期 Java IO API 和部分网络 API 的替代品。虽然 NIO 是一个广泛而复杂的主题,但我们感兴趣的是它如何为网络应用程序提供支持。 在本章中,我们将重点介绍 Java**新 IO****NIO**)包的`Buffer``Channels`类。NIO 是早期 Java IO API 和部分网络 API 的替代品。虽然 NIO 是一个广泛而复杂的主题,但我们感兴趣的是它如何为网络应用程序提供支持。
我们将探讨几个主题,包括以下内容: 我们将探讨几个主题,包括以下内容:
* 缓冲区、通道和选择器之间的性质和关系 * 缓冲区、通道和选择器之间的性质和关系
* 使用 NIO 技术构建客户/服务器 * 使用 NIO 技术构建客户/服务器
* 处理多个客户的过程 * 处理多个客户的过程
* 支持异步套接字通道 * 支持异步套接字通道
* 基本缓冲区操作 * 基本缓冲区操作
...@@ -69,7 +69,7 @@ Java NIO 使用三个核心类: ...@@ -69,7 +69,7 @@ Java NIO 使用三个核心类:
当应用程序使用许多低流量连接时,`Selector`类非常有用,这些连接可以使用单个线程处理。这比为每个连接创建线程更有效。这也是一种用于使应用程序更具可伸缩性的技术,我们将在[第 7 章](7.html "Chapter 7. Network Scalability")*网络可伸缩性*中讨论。 当应用程序使用许多低流量连接时,`Selector`类非常有用,这些连接可以使用单个线程处理。这比为每个连接创建线程更有效。这也是一种用于使应用程序更具可伸缩性的技术,我们将在[第 7 章](7.html "Chapter 7. Network Scalability")*网络可伸缩性*中讨论。
在本章中,我们将创建客户/服务器应用程序来说明通道和缓冲区之间的交互。这包括一个简单的时间服务器、一个用于演示可变长度消息的聊天服务器、一个用于演示处理多个客户端的一种技术的部件服务器,以及一个异步服务器。我们还将研究专门的缓冲区技术,包括批量传输和视图。 在本章中,我们将创建客户/服务器应用程序来说明通道和缓冲区之间的交互。这包括一个简单的时间服务器、一个用于演示可变长度消息的聊天服务器、一个用于演示处理多个客户端的一种技术的部件服务器,以及一个异步服务器。我们还将研究专门的缓冲区技术,包括批量传输和视图。
我们将从缓冲区的概述以及它们如何与通道一起工作开始讨论。 我们将从缓冲区的概述以及它们如何与通道一起工作开始讨论。
...@@ -117,7 +117,7 @@ Java NIO 使用三个核心类: ...@@ -117,7 +117,7 @@ Java NIO 使用三个核心类:
# 使用带有时间服务器的通道 # 使用带有时间服务器的通道
[第 1 章](1.html "Chapter 1. Getting Started with Network Programming")*网络编程入门*中介绍的时间服务器和客户端将在此处实现,以演示缓冲区和通道的使用。这些应用程序很简单,但它们说明了如何将缓冲区和通道一起使用。我们将首先创建一个服务器,然后创建一个使用该服务器的客户 [第 1 章](1.html "Chapter 1. Getting Started with Network Programming")*网络编程入门*中介绍的时间服务器和客户端将在此处实现,以演示缓冲区和通道的使用。这些应用程序很简单,但它们说明了如何将缓冲区和通道一起使用。我们将首先创建一个服务器,然后创建一个使用该服务器的客户
## 创建时间服务器 ## 创建时间服务器
...@@ -188,7 +188,7 @@ public class ServerSocketChannelTimeServer { ...@@ -188,7 +188,7 @@ public class ServerSocketChannelTimeServer {
## 创建时间客户端 ## 创建时间客户端
客户机是在`SocketChannelTimeClient`类中实现的,定义如下。为了简化示例,假定客户机与服务器位于同一台机器上。使用 IP 地址`127.0.0.1`创建`SocketAddress`实例,并与端口`5000`关联。`SocketChannel`类的`open`方法返回一个`SocketChannel`实例,该实例将用于处理 try with resources 块中服务器的响应: 客户端是在`SocketChannelTimeClient`类中实现的,定义如下。为了简化示例,假定客户端与服务器位于同一台机器上。使用 IP 地址`127.0.0.1`创建`SocketAddress`实例,并与端口`5000`关联。`SocketChannel`类的`open`方法返回一个`SocketChannel`实例,该实例将用于处理 try with resources 块中服务器的响应:
```java ```java
public class SocketChannelTimeClient { public class SocketChannelTimeClient {
...@@ -571,7 +571,7 @@ public class HelperMethods { ...@@ -571,7 +571,7 @@ public class HelperMethods {
处理使用线程可以实现多个客户端。在本节中,我们将开发一个简单的部件服务器和客户端应用程序。服务器将使用一个单独的线程来处理每个客户端。此技术易于实现,但并不总是适用于要求更高的应用程序。我们将在[第 7 章](7.html "Chapter 7. Network Scalability")*网络可扩展性*中介绍多任务的替代技术。 处理使用线程可以实现多个客户端。在本节中,我们将开发一个简单的部件服务器和客户端应用程序。服务器将使用一个单独的线程来处理每个客户端。此技术易于实现,但并不总是适用于要求更高的应用程序。我们将在[第 7 章](7.html "Chapter 7. Network Scalability")*网络可扩展性*中介绍多任务的替代技术。
零件服务器在`PartsServer`类中实现,客户`PartsClient`类中实现。将为每个客户端创建一个`ClientHandler`类的新实例。此处理程序将接受零件价格的请求。客户端将向处理程序发送部件的名称。经办人将使用`PartsServer``getPrice`方法查询零件的价格。然后它会将价格返回给客户。 零件服务器在`PartsServer`类中实现,客户`PartsClient`类中实现。将为每个客户端创建一个`ClientHandler`类的新实例。此处理程序将接受零件价格的请求。客户端将向处理程序发送部件的名称。经办人将使用`PartsServer``getPrice`方法查询零件的价格。然后它会将价格返回给客户。
## 零件服务器 ## 零件服务器
...@@ -632,7 +632,7 @@ public class PartsServer { ...@@ -632,7 +632,7 @@ public class PartsServer {
} }
``` ```
接下来,一个无限循环将为每个客户机创建一个新的处理程序。虽然 Java 中有几种创建线程的方法,但接下来使用的方法是创建`ClientHandler`类的新实例,将客户机的套接字传递给该类的构造函数。此方法不限制应用程序创建的线程数,这使其容易受到拒绝服务攻击。在[第 7 章](7.html "Chapter 7. Network Scalability")*网络可扩展性*中,我们将研究几种可选的线程方法。 接下来,一个无限循环将为每个客户端创建一个新的处理程序。虽然 Java 中有几种创建线程的方法,但接下来使用的方法是创建`ClientHandler`类的新实例,将客户端的套接字传递给该类的构造函数。此方法不限制应用程序创建的线程数,这使其容易受到拒绝服务攻击。在[第 7 章](7.html "Chapter 7. Network Scalability")*网络可扩展性*中,我们将研究几种可选的线程方法。
`ClientHandler`实例用作`Thread`类的参数。该类将创建一个新线程,该线程将执行`ClientHandler`类的`run`方法。但是,不应该直接调用`run`方法,而是调用`start`方法。此方法将创建线程所需的程序堆栈: `ClientHandler`实例用作`Thread`类的参数。该类将创建一个新线程,该线程将执行`ClientHandler`类的`run`方法。但是,不应该直接调用`run`方法,而是调用`start`方法。此方法将创建线程所需的程序堆栈:
...@@ -656,7 +656,7 @@ public class PartsServer { ...@@ -656,7 +656,7 @@ public class PartsServer {
## 零件客户处理人 ## 零件客户处理人
`ClientHandler`类在下面的代码中定义为。`socketChannel`实例变量用于连接客户端。在`run`方法中,将显示一条指示处理程序启动的消息。这不是必需的,但它将帮助我们了解服务器、客户和处理程序是如何交互的。 `ClientHandler`类在下面的代码中定义为。`socketChannel`实例变量用于连接客户端。在`run`方法中,将显示一条指示处理程序启动的消息。这不是必需的,但它将帮助我们了解服务器、客户和处理程序是如何交互的。
进入一个无限循环,其中使用*HelperMethods 类*中开发的`receiveMessage`方法获取零件名称。一条`quit`消息将终止处理程序。否则调用`getPrice`方法,使用`sendMessage`方法返回给客户端: 进入一个无限循环,其中使用*HelperMethods 类*中开发的`receiveMessage`方法获取零件名称。一条`quit`消息将终止处理程序。否则调用`getPrice`方法,使用`sendMessage`方法返回给客户端:
...@@ -944,11 +944,11 @@ try 块的主体将分配一个缓冲区,然后从通道读取以填充缓冲 ...@@ -944,11 +944,11 @@ try 块的主体将分配一个缓冲区,然后从通道读取以填充缓冲
**正在等待客户端连接。。。** **正在等待客户端连接。。。**
现在,让我们检查一下客户 现在,让我们检查一下客户
## 创建异步套接字通道客户端 ## 创建异步套接字通道客户端
客户是在下一个代码段中使用`AsynchronousSocketChannelClient`类实现的。将显示一条消息,指示客户端已启动,随后是创建`AsynchronousSocketChannel`实例的 try 块: 客户是在下一个代码段中使用`AsynchronousSocketChannelClient`类实现的。将显示一条消息,指示客户端已启动,随后是创建`AsynchronousSocketChannel`实例的 try 块:
```java ```java
public class AsynchronousSocketChannelClient { public class AsynchronousSocketChannelClient {
...@@ -1213,8 +1213,8 @@ public class AsynchronousSocketChannelClient { ...@@ -1213,8 +1213,8 @@ public class AsynchronousSocketChannelClient {
我们检查了几种类型的通道插座,包括`SocketChannel``ServerSocketChannel``AsynchronousSocketChannel`类。`ServerSocketChannel`类支持服务器,并使用`accept`方法阻塞,直到客户端请求连接。该方法将返回一个`SocketChannel`实例,该实例将连接到客户端的`SocketChannel``AsynchronousSocketChannel``AsynchronousSocketChannel`类支持异步通信,实现两个应用程序之间的无阻塞通信。也支持`DatagramChannel`,我们将在[第 6 章](6.html "Chapter 6. UDP and Multicasting")*UDP 和多播*中研究。 我们检查了几种类型的通道插座,包括`SocketChannel``ServerSocketChannel``AsynchronousSocketChannel`类。`ServerSocketChannel`类支持服务器,并使用`accept`方法阻塞,直到客户端请求连接。该方法将返回一个`SocketChannel`实例,该实例将连接到客户端的`SocketChannel``AsynchronousSocketChannel``AsynchronousSocketChannel`类支持异步通信,实现两个应用程序之间的无阻塞通信。也支持`DatagramChannel`,我们将在[第 6 章](6.html "Chapter 6. UDP and Multicasting")*UDP 和多播*中研究。
我们解释了缓冲区和通道类如何协同工作,并说明了它们在几个客户/服务器应用程序中的使用。我们还研究了一种使用线程处理多个客户端的简单方法。 我们解释了缓冲区和通道类如何协同工作,并说明了它们在几个客户/服务器应用程序中的使用。我们还研究了一种使用线程处理多个客户端的简单方法。
我们演示了如何在数组和缓冲区之间执行批量数据传输。还检查了视图和只读缓冲区的使用。最后,我们介绍了如何配置底层 OS 套接字支持。 我们演示了如何在数组和缓冲区之间执行批量数据传输。还检查了视图和只读缓冲区的使用。最后,我们介绍了如何配置底层 OS 套接字支持。
在下一章中,我们将使用许多此类和技术来支持其他客户机/服务器应用程序。 在下一章中,我们将使用许多此类和技术来支持其他客户端/服务器应用程序。
\ No newline at end of file \ No newline at end of file
# 第四章客户机/服务器开发 # 四、客户端/服务器开发
在本章中,我们将探讨开发主要面向 HTTP 的客户机/服务器应用程序的过程。这是一个重要的协议,它是多种应用程序的主要通信媒介。我们将检查协议、客户机上的需求以及服务器上各种版本协议的需求。 在本章中,我们将探讨开发主要面向 HTTP 的客户端/服务器应用程序的过程。这是一个重要的协议,它是多种应用程序的主要通信媒介。我们将检查协议、客户端上的需求以及服务器上各种版本协议的需求。
具体而言,我们将: 具体而言,我们将:
...@@ -197,7 +197,7 @@ HTTP 1.0 定义了 16 个头文件([http://www.w3.org/Protocols/HTTP/1.0/spec. ...@@ -197,7 +197,7 @@ HTTP 1.0 定义了 16 个头文件([http://www.w3.org/Protocols/HTTP/1.0/spec.
可以包括其他标题行。 可以包括其他标题行。
# 对 HTTP 客户/服务器应用程序的 Java 套接字支持 # 对 HTTP 客户/服务器应用程序的 Java 套接字支持
HTTP 客户端将与 HTTP 服务器建立连接。客户端将向服务器发送请求消息。服务器通常会以 HTML 文档的形式发回响应消息。在早期的 HTTP 版本中,一旦发送响应,服务器就会终止连接。这有时被称为无状态协议,因为没有维护连接。 HTTP 客户端将与 HTTP 服务器建立连接。客户端将向服务器发送请求消息。服务器通常会以 HTML 文档的形式发回响应消息。在早期的 HTTP 版本中,一旦发送响应,服务器就会终止连接。这有时被称为无状态协议,因为没有维护连接。
...@@ -448,9 +448,9 @@ public class HTTPClient { ...@@ -448,9 +448,9 @@ public class HTTPClient {
![Building a simple HTTP client](img/B04915_04_02.jpg) ![Building a simple HTTP client](img/B04915_04_02.jpg)
这些客户端和服务器应用程序可以进一步增强。但是,我们可以使用`HttpURLConnection`类来获得类似的结果。** **# 使用标准 Java 类开发客户/服务器 这些客户端和服务器应用程序可以进一步增强。但是,我们可以使用`HttpURLConnection`类来获得类似的结果。** **# 使用标准 Java 类开发客户/服务器
具体来说,我们将使用`HttpURLConnection``HTTPServer`类来实现客户和服务器应用程序。这些类支持客户端和服务器所需的大部分功能。使用这些类将避免编写底层代码来实现 HTTP 功能。低级代码是指非专业类,如`Socket`类。更高级别和更专业的课程,如`HttpURLConnection``HTTPServer`课程,补充并提供专业操作的额外支持。 具体来说,我们将使用`HttpURLConnection``HTTPServer`类来实现客户和服务器应用程序。这些类支持客户端和服务器所需的大部分功能。使用这些类将避免编写底层代码来实现 HTTP 功能。低级代码是指非专业类,如`Socket`类。更高级别和更专业的课程,如`HttpURLConnection``HTTPServer`课程,补充并提供专业操作的额外支持。
`HttpURLConnection`类派生自`HttpConnection`类。这个基类有许多与 HTTP 协议没有直接关系的方法。 `HttpURLConnection`类派生自`HttpConnection`类。这个基类有许多与 HTTP 协议没有直接关系的方法。
...@@ -575,7 +575,7 @@ public class HttpURLConnectionExample { ...@@ -575,7 +575,7 @@ public class HttpURLConnectionExample {
## 使用 HTTPServer 类 ## 使用 HTTPServer 类
`HTTPServer`类在`com.sun.net.httpserver`包中找到。它提供了一组功能强大的功能来支持一个简单的 HTTP 服务器。我们必须使用以前的服务器手动执行的许多任务都使用此服务器进行了简化。客户和服务器之间的交互称为交换。 `HTTPServer`类在`com.sun.net.httpserver`包中找到。它提供了一组功能强大的功能来支持一个简单的 HTTP 服务器。我们必须使用以前的服务器手动执行的许多任务都使用此服务器进行了简化。客户和服务器之间的交互称为交换。
此类和其他支持类及接口是`com.sun.net.httpserver`包的成员。它们通常包含在大多数 IDE 中。API 文档可在[中找到 http://docs.oracle.com/javase/8/docs/jre/api/net/httpserver/spec/index.html?com/sun/net/httpserver/package-summary.html](http://docs.oracle.com/javase/8/docs/jre/api/net/httpserver/spec/index.html?com/sun/net/httpserver/package-summary.html) 此类和其他支持类及接口是`com.sun.net.httpserver`包的成员。它们通常包含在大多数 IDE 中。API 文档可在[中找到 http://docs.oracle.com/javase/8/docs/jre/api/net/httpserver/spec/index.html?com/sun/net/httpserver/package-summary.html](http://docs.oracle.com/javase/8/docs/jre/api/net/httpserver/spec/index.html?com/sun/net/httpserver/package-summary.html)
...@@ -593,14 +593,14 @@ public class HttpURLConnectionExample { ...@@ -593,14 +593,14 @@ public class HttpURLConnectionExample {
| |
| --- | --- | | --- | --- |
| `HttpServer` | 这个类支持 HTTP 服务器的基本功能 | | `HttpServer` | 这个类支持 HTTP 服务器的基本功能 |
| `HttpExchange` | 这个类封装了与客户/服务器交换相关联的请求和响应 | | `HttpExchange` | 这个类封装了与客户/服务器交换相关联的请求和响应 |
| `HttpHandler` | 这个类定义了一个用于处理特定交换的句柄方法 | | `HttpHandler` | 这个类定义了一个用于处理特定交换的句柄方法 |
| `HttpContext` | 此类将 URI 路径映射到`HttpHandler`实例 | | `HttpContext` | 此类将 URI 路径映射到`HttpHandler`实例 |
| `Filter` | 这个类支持请求的预处理和后处理 | | `Filter` | 这个类支持请求的预处理和后处理 |
服务器使用`HttpHandler`派生的类来处理客户端请求。例如,一个处理程序可以处理基本网页的请求,而另一个处理程序可以处理与服务相关的请求。 服务器使用`HttpHandler`派生的类来处理客户端请求。例如,一个处理程序可以处理基本网页的请求,而另一个处理程序可以处理与服务相关的请求。
`HttpExchange`类支持客户和服务器之间交换的生命周期活动。它拥有许多方法来提供对请求和响应信息的访问。下表按正常使用顺序列出了这些方法。并非所有方法都需要用于所有请求: `HttpExchange`类支持客户和服务器之间交换的生命周期活动。它拥有许多方法来提供对请求和响应信息的访问。下表按正常使用顺序列出了这些方法。并非所有方法都需要用于所有请求:
<colgroup><col style="text-align: left"> <col style="text-align: left"></colgroup> <colgroup><col style="text-align: left"> <col style="text-align: left"></colgroup>
| |
...@@ -716,7 +716,7 @@ public class MyHTTPServer { ...@@ -716,7 +716,7 @@ public class MyHTTPServer {
**/127.0.0.1:50273** **/127.0.0.1:50273**
此类在处理客户请求时起着作用。在这里,我们将使用一个名为`DetailHandler`的不同处理程序来说明这个类的几个方法,如下所述: 此类在处理客户请求时起着作用。在这里,我们将使用一个名为`DetailHandler`的不同处理程序来说明这个类的几个方法,如下所述:
```java ```java
static class DetailHandler implements HttpHandler { static class DetailHandler implements HttpHandler {
...@@ -989,14 +989,14 @@ cookie 是一个字符串,由一个名称、一个等号和一个值组成。 ...@@ -989,14 +989,14 @@ cookie 是一个字符串,由一个名称、一个等号和一个值组成。
# 总结 # 总结
在本章中,我们研究了可用于开发 HTTP 客户/服务器应用程序的各种 Java 方法。使用 HTTP 进行通信是一种常见做法。了解 Java 如何支持这个过程是一项很有价值的技能。 在本章中,我们研究了可用于开发 HTTP 客户/服务器应用程序的各种 Java 方法。使用 HTTP 进行通信是一种常见做法。了解 Java 如何支持这个过程是一项很有价值的技能。
我们从 HTTP 消息的概述开始。我们检查了初始请求和响应行的格式。还检查了用于传递消息信息的标题行。HTTP 消息中可能会出现可选的消息正文。这在正文通常是 HTML 文档的响应中更为常见。 我们从 HTTP 消息的概述开始。我们检查了初始请求和响应行的格式。还检查了用于传递消息信息的标题行。HTTP 消息中可能会出现可选的消息正文。这在正文通常是 HTML 文档的响应中更为常见。
我们演示了如何使用简单的套接字开发客户机/服务器。虽然可能,但这种方法需要大量的工作来开发功能齐全的 HTTP 服务器。本次讨论之后,使用了`HTTPServer``HttpURLConnection`类分别支持服务器和客户机。这些类的使用使得开发过程更加容易。 我们演示了如何使用简单的套接字开发客户端/服务器。虽然可能,但这种方法需要大量的工作来开发功能齐全的 HTTP 服务器。本次讨论之后,使用了`HTTPServer``HttpURLConnection`类分别支持服务器和客户端。这些类的使用使得开发过程更加容易。
有许多基于 Java 的开源 HTTP 服务器可用。对于某些环境来说,这些可能是可行的备选方案。还讨论了以 ApacheTomcat 为代表的更复杂的 web 服务器。它们与 servlet 一起工作,并向开发人员隐藏许多底层 HTTP 细节。 有许多基于 Java 的开源 HTTP 服务器可用。对于某些环境来说,这些可能是可行的备选方案。还讨论了以 ApacheTomcat 为代表的更复杂的 web 服务器。它们与 servlet 一起工作,并向开发人员隐藏许多底层 HTTP 细节。
我们在本章结尾简要讨论了服务器配置问题以及服务器和客户端如何创建和使用 cookie。 我们在本章结尾简要讨论了服务器配置问题以及服务器和客户端如何创建和使用 cookie。
虽然客户机/服务器体系结构非常常见,但对等体系结构是跨网络共享信息的替代方案。我们将在下一章深入探讨这个话题。** 虽然客户端/服务器体系结构非常常见,但对等体系结构是跨网络共享信息的替代方案。我们将在下一章深入探讨这个话题。**
\ No newline at end of file \ No newline at end of file
# 第五章对等网络 # 五、对等网络
**对等****P2P**计算机网络是指其节点经常同时充当服务器和客户端的体系结构。P2P 系统的主要目标是消除对单独服务器管理系统的需要。随着节点以不可预测的方式加入和离开网络,P2P 网络的配置将动态变化。节点在处理速度、带宽支持和存储能力等因素方面可能有所不同。“对等”一词意味着节点之间的平等程度。 **对等****P2P**计算机网络是指其节点经常同时充当服务器和客户端的体系结构。P2P 系统的主要目标是消除对单独服务器管理系统的需要。随着节点以不可预测的方式加入和离开网络,P2P 网络的配置将动态变化。节点在处理速度、带宽支持和存储能力等因素方面可能有所不同。“对等”一词意味着节点之间的平等程度。
P2P 网络有多种定义和解释。它们可以被描述为一个分散的、不断变化的、自我调节的体系结构。服务器倾向于提供服务,而客户端则请求服务。P2P 节点通常同时执行这两种操作。纯 P2P 网络不会将节点指定为客户端或服务器。事实上,这些网络非常罕见。大多数 P2P 网络都依赖于一个中心设施,如 DNS 服务器来提供支持。 P2P 网络有多种定义和解释。它们可以被描述为一个分散的、不断变化的、自我调节的体系结构。服务器倾向于提供服务,而客户端则请求服务。P2P 节点通常同时执行这两种操作。纯 P2P 网络不会将节点指定为客户端或服务器。事实上,这些网络非常罕见。大多数 P2P 网络都依赖于一个中心设施,如 DNS 服务器来提供支持。
某些网络可能是客户/服务器体系结构和更纯粹的 P2P 体系结构的混合体,在 P2P 体系结构中,没有特定节点充当“主”服务器。例如,文件共享 P2P 可以使用网络节点下载文件,而服务器可以提供额外的支持信息。 某些网络可能是客户/服务器体系结构和更纯粹的 P2P 体系结构的混合体,在 P2P 体系结构中,没有特定节点充当“主”服务器。例如,文件共享 P2P 可以使用网络节点下载文件,而服务器可以提供额外的支持信息。
P2P 可以通过几种方式进行分类。我们将使用两种常见的分类类别,它们有助于理解 P2P 网络的本质。一种分类基于如何执行**索引**(查找节点的过程): P2P 可以通过几种方式进行分类。我们将使用两种常见的分类类别,它们有助于理解 P2P 网络的本质。一种分类基于如何执行**索引**(查找节点的过程):
...@@ -25,7 +25,7 @@ P2P 可以通过几种方式进行分类。我们将使用两种常见的分类 ...@@ -25,7 +25,7 @@ P2P 可以通过几种方式进行分类。我们将使用两种常见的分类
### 注 ### 注
P2P 应用程序为传统的客户/服务器体系结构提供了灵活的替代方案。 P2P 应用程序为传统的客户/服务器体系结构提供了灵活的替代方案。
# P2P 功能/特点 # P2P 功能/特点
......
# 第 6 章 UDP 和多播 # 六、UDP 和多播
**用户数据报协议****UDP**)位于 IP 之上,为 TCP 提供了不可靠的对应物。UDP 在网络中的两个节点之间发送单个数据包。UDP 数据包不知道其他数据包,也不能保证数据包将实际到达其预期目的地。当发送多个数据包时,无法保证到达顺序。UDP 消息只是简单地发送,然后被忘记,因为没有从收件人发送确认。 **用户数据报协议****UDP**)位于 IP 之上,为 TCP 提供了不可靠的对应物。UDP 在网络中的两个节点之间发送单个数据包。UDP 数据包不知道其他数据包,也不能保证数据包将实际到达其预期目的地。当发送多个数据包时,无法保证到达顺序。UDP 消息只是简单地发送,然后被忘记,因为没有从收件人发送确认。
...@@ -19,7 +19,7 @@ UDP 数据包也可以是多播的。这意味着数据包被发送到属于 UDP ...@@ -19,7 +19,7 @@ UDP 数据包也可以是多播的。这意味着数据包被发送到属于 UDP
在本章中,我们将说明如何使用 UDP 协议: 在本章中,我们将说明如何使用 UDP 协议:
* 支持传统的客户/服务器模型 * 支持传统的客户/服务器模型
* 使用 NIO 通道执行 UDP 操作 * 使用 NIO 通道执行 UDP 操作
* 向组成员发送多播数据包 * 向组成员发送多播数据包
* 将音频或视频等流媒体传送到客户端 * 将音频或视频等流媒体传送到客户端
...@@ -104,11 +104,11 @@ TCP 保留数据包的发送顺序,而 UDP 不保留。如果 TCP 数据包到 ...@@ -104,11 +104,11 @@ TCP 保留数据包的发送顺序,而 UDP 不保留。如果 TCP 数据包到
由于具有较小的报头大小和确保可靠性所需的开销,UDP 比 TCP 更高效。此外,创建连接所需的工作更少。这种效率使得流媒体成为更好的选择。 由于具有较小的报头大小和确保可靠性所需的开销,UDP 比 TCP 更高效。此外,创建连接所需的工作更少。这种效率使得流媒体成为更好的选择。
让我们从 UDP 示例开始,了解如何支持传统的客户/服务器体系结构。 让我们从 UDP 示例开始,了解如何支持传统的客户/服务器体系结构。
# UDP 客户端/服务器 # UDP 客户端/服务器
UDP 客户机/服务器应用程序的结构与 TCP 客户机/服务器应用程序的结构相似。在服务器端,创建一个 UDP 服务器套接字,等待客户端请求。客户端将创建相应的 UDP 套接字,并使用它向服务器发送消息。然后,服务器可以处理请求并发回响应。 UDP 客户端/服务器应用程序的结构与 TCP 客户端/服务器应用程序的结构相似。在服务器端,创建一个 UDP 服务器套接字,等待客户端请求。客户端将创建相应的 UDP 套接字,并使用它向服务器发送消息。然后,服务器可以处理请求并发回响应。
UDP 客户端/服务器将使用`DatagramSocket`类作为套接字,并使用`DatagramPacket`保存消息。消息的内容类型没有限制。在我们的示例中,我们将使用文本消息。 UDP 客户端/服务器将使用`DatagramSocket`类作为套接字,并使用`DatagramPacket`保存消息。消息的内容类型没有限制。在我们的示例中,我们将使用文本消息。
...@@ -282,7 +282,7 @@ class UDPClient { ...@@ -282,7 +282,7 @@ class UDPClient {
**UDP 服务器启动** **UDP 服务器启动**
接下来,启动客户应用程序。它将显示以下消息: 接下来,启动客户应用程序。它将显示以下消息:
**UDP 客户端启动** **UDP 客户端启动**
...@@ -326,7 +326,7 @@ class UDPClient { ...@@ -326,7 +326,7 @@ class UDPClient {
**From:/127.0.0.1** **From:/127.0.0.1**
此客户机/服务器应用程序可以通过多种方式进行增强,包括使用线程,以使其能够更好地处理多个客户机。此示例演示了用 Java 开发 UDP 客户机/服务器应用程序的基础知识。在下一节中,我们将了解通道如何支持 UDP。**** ****# 对 UDP 的通道支持 此客户端/服务器应用程序可以通过多种方式进行增强,包括使用线程,以使其能够更好地处理多个客户端。此示例演示了用 Java 开发 UDP 客户端/服务器应用程序的基础知识。在下一节中,我们将了解通道如何支持 UDP。**** ****# 对 UDP 的通道支持
`DatagramChannel`类提供了对 UDP 的额外支持。它可以支持非阻塞交换。`DatagramChannel`类派生自`SelectableChannel`类,使多线程应用程序更容易。我们将在[第 7 章](7.html "Chapter 7. Network Scalability")*网络可扩展性*中探讨其使用。 `DatagramChannel`类提供了对 UDP 的额外支持。它可以支持非阻塞交换。`DatagramChannel`类派生自`SelectableChannel`类,使多线程应用程序更容易。我们将在[第 7 章](7.html "Chapter 7. Network Scalability")*网络可扩展性*中探讨其使用。
...@@ -420,7 +420,7 @@ public class UDPEchoServer { ...@@ -420,7 +420,7 @@ public class UDPEchoServer {
**UDP 回显服务器启动** **UDP 回显服务器启动**
我们现在准备好看看客户是如何实现的。 我们现在准备好看看客户是如何实现的。
## UDP echo 客户端应用程序 ## UDP echo 客户端应用程序
...@@ -505,7 +505,7 @@ public class UDPEchoClient { ...@@ -505,7 +505,7 @@ public class UDPEchoClient {
**UDP 回显服务器启动** **UDP 回显服务器启动**
接下来,启动客户。将显示以下输出,显示发送消息的客户端,然后显示返回的消息: 接下来,启动客户。将显示以下输出,显示发送消息的客户端,然后显示返回的消息:
**UDP 回显客户端启动** **UDP 回显客户端启动**
...@@ -658,7 +658,7 @@ public class UDPMulticastClient { ...@@ -658,7 +658,7 @@ public class UDPMulticastClient {
**。。。** **。。。**
接下来,启动客户应用程序。它将开始接收类似以下内容的消息: 接下来,启动客户应用程序。它将开始接收类似以下内容的消息:
**UDP 多播时间客户端启动** **UDP 多播时间客户端启动**
...@@ -763,7 +763,7 @@ public class UDPMulticastClient { ...@@ -763,7 +763,7 @@ public class UDPMulticastClient {
**。。。** **。。。**
对于我们的客户/服务器,我们将使用`eth0`接口。您需要选择一个最适合您的平台。例如,在 Mac 上,这可能是`en0``awdl0` 对于我们的客户/服务器,我们将使用`eth0`接口。您需要选择一个最适合您的平台。例如,在 Mac 上,这可能是`en0``awdl0`
## UDP 通道多播服务器 ## UDP 通道多播服务器
...@@ -920,7 +920,7 @@ public class UDPDatagramMulticastClient { ...@@ -920,7 +920,7 @@ public class UDPDatagramMulticastClient {
**。。。** **。。。**
接下来,启动客户应用程序。它将显示多播组,等待消息,然后显示消息,如下所示: 接下来,启动客户应用程序。它将显示多播组,等待消息,然后显示消息,如下所示:
**加入多播组:<ff01:0:0:0:0:fc,eth1>** **加入多播组:<ff01:0:0:0:0:fc,eth1>**
...@@ -934,7 +934,7 @@ public class UDPDatagramMulticastClient { ...@@ -934,7 +934,7 @@ public class UDPDatagramMulticastClient {
使用 UDP 传输音频或视频是很常见的。它是有效的,任何数据包丢失或无序数据包都会导致最小的问题。我们将通过播放现场音频来说明这项技术。UDP 服务器将捕获麦克风的声音并将其发送到客户端。UDP 客户端将接收音频并在系统扬声器上播放。 使用 UDP 传输音频或视频是很常见的。它是有效的,任何数据包丢失或无序数据包都会导致最小的问题。我们将通过播放现场音频来说明这项技术。UDP 服务器将捕获麦克风的声音并将其发送到客户端。UDP 客户端将接收音频并在系统扬声器上播放。
UDP 流媒体服务器的思想是将流分解为一系列数据包,然后发送到 UDP 客户端。然后,客户将接收这些数据包,并使用它们来重建流。 UDP 流媒体服务器的思想是将流分解为一系列数据包,然后发送到 UDP 客户端。然后,客户将接收这些数据包,并使用它们来重建流。
为了演示流式音频,我们需要了解一些 Java 如何处理音频流。音频由`javax.sound.sampled`包中的一系列类处理。用于捕获和播放音频的主要类包括: 为了演示流式音频,我们需要了解一些 Java 如何处理音频流。音频由`javax.sound.sampled`包中的一系列类处理。用于捕获和播放音频的主要类包括:
...@@ -1131,7 +1131,7 @@ public class AudioUDPClient { ...@@ -1131,7 +1131,7 @@ public class AudioUDPClient {
在本章中,我们研究了 UDP 协议的性质以及 Java 如何支持它。我们对比了 TCP 和 UDP,以便在决定哪种协议最适合于给定问题时提供一些指导。 在本章中,我们研究了 UDP 协议的性质以及 Java 如何支持它。我们对比了 TCP 和 UDP,以便在决定哪种协议最适合于给定问题时提供一些指导。
我们从一个简单的 UDP 客户/服务器开始,演示如何使用`DatagramPacket``DatagramSocket`类。我们看到了如何使用`InetAddress`类来获取套接字和数据包使用的地址。 我们从一个简单的 UDP 客户/服务器开始,演示如何使用`DatagramPacket``DatagramSocket`类。我们看到了如何使用`InetAddress`类来获取套接字和数据包使用的地址。
`DatagramChannel`类支持在 UDP 环境中使用 NIO 技术,这比使用`DatagramPacket``DatagramSocket`方法更有效。该方法使用字节缓冲区来保存服务器和客户端之间发送的消息。此示例说明了在[第 3 章](3.html "Chapter 3. NIO Support for Networking")*NIO 网络支持*中开发的许多技术。 `DatagramChannel`类支持在 UDP 环境中使用 NIO 技术,这比使用`DatagramPacket``DatagramSocket`方法更有效。该方法使用字节缓冲区来保存服务器和客户端之间发送的消息。此示例说明了在[第 3 章](3.html "Chapter 3. NIO Support for Networking")*NIO 网络支持*中开发的许多技术。
...@@ -1139,4 +1139,4 @@ public class AudioUDPClient { ...@@ -1139,4 +1139,4 @@ public class AudioUDPClient {
我们最后给出了一个示例,说明如何使用 UDP 支持音频流。我们详细介绍了`javax.sound.sampled`包中几个类的使用,包括`AudioFormat``TargetDataLine`类用于收集和播放音频。我们使用`DatagramSocket``DatagramPacket`类来传输音频。 我们最后给出了一个示例,说明如何使用 UDP 支持音频流。我们详细介绍了`javax.sound.sampled`包中几个类的使用,包括`AudioFormat``TargetDataLine`类用于收集和播放音频。我们使用`DatagramSocket``DatagramPacket`类来传输音频。
在下一章中,我们将研究可用于提高客户机/服务器应用程序可伸缩性的技术。**** 在下一章中,我们将研究可用于提高客户端/服务器应用程序可伸缩性的技术。****
\ No newline at end of file \ No newline at end of file
# 第 7 章网络可扩展性 # 七、网络可扩展性
网络可伸缩性关注的是如何构建应用程序,使其能够随着对应用程序的需求增加而调整以应对压力。需求的形式可能是更多的用户、更多的请求、更复杂的请求以及网络特性的变化。 网络可伸缩性关注的是如何构建应用程序,使其能够随着对应用程序的需求增加而调整以应对压力。需求的形式可能是更多的用户、更多的请求、更复杂的请求以及网络特性的变化。
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
在每线程连接模型中,客户端连接在会话期间保持。会话由一系列请求和响应组成。通过特定命令或在超时时间过后终止会话。这种方法允许在请求之间维护状态信息。 在每线程连接模型中,客户端连接在会话期间保持。会话由一系列请求和响应组成。通过特定命令或在超时时间过后终止会话。这种方法允许在请求之间维护状态信息。
下图说明了这种方法。虚线表示来自同一客户的多个请求由同一线程处理。 下图说明了这种方法。虚线表示来自同一客户的多个请求由同一线程处理。
![Multithreaded server overview](img/B04915_07_02.jpg) ![Multithreaded server overview](img/B04915_07_02.jpg)
...@@ -186,7 +186,7 @@ public class SimpleClient { ...@@ -186,7 +186,7 @@ public class SimpleClient {
**正在侦听客户端连接** **正在侦听客户端连接**
接下来,启动客户应用程序。将显示以下输出: 接下来,启动客户应用程序。将显示以下输出:
**客户端启动** **客户端启动**
...@@ -307,7 +307,7 @@ public class SimpleClient { ...@@ -307,7 +307,7 @@ public class SimpleClient {
# 每个连接方法的螺纹 # 每个连接方法的螺纹
在这种方法中,使用一个单线程来处理客户的所有请求。这种方法将要求客户端发送某种通知,表示它没有进一步的请求。可能需要设置超时来代替显式通知,以便在经过足够的时间后自动断开客户端。 在这种方法中,使用一个单线程来处理客户的所有请求。这种方法将要求客户端发送某种通知,表示它没有进一步的请求。可能需要设置超时来代替显式通知,以便在经过足够的时间后自动断开客户端。
## 每个连接服务器的线程数 ## 每个连接服务器的线程数
...@@ -468,7 +468,7 @@ public class WorkerThread implements Runnable { ...@@ -468,7 +468,7 @@ public class WorkerThread implements Runnable {
} }
``` ```
该类的构造函数将客户套接字分配给`clientSocket`实例变量以供以后使用,如下所示: 该类的构造函数将客户套接字分配给`clientSocket`实例变量以供以后使用,如下所示:
```java ```java
public WorkerThread(Socket clientSocket) { public WorkerThread(Socket clientSocket) {
...@@ -547,7 +547,7 @@ public class SimpleClient { ...@@ -547,7 +547,7 @@ public class SimpleClient {
**正在侦听客户端连接** **正在侦听客户端连接**
接下来,启动客户。它将产生以下输出,其中发送车轴价格请求,然后收到响应`238.5` 接下来,启动客户。它将产生以下输出,其中发送车轴价格请求,然后收到响应`238.5`
**客户端启动** **客户端启动**
...@@ -575,7 +575,7 @@ public class SimpleClient { ...@@ -575,7 +575,7 @@ public class SimpleClient {
**工作线程终止** **工作线程终止**
如果启动第二个客户机,服务器将生成类似于以下客户机的输出。您将注意到,将为每个请求创建一个新线程: 如果启动第二个客户端,服务器将生成类似于以下客户端的输出。您将注意到,将为每个请求创建一个新线程:
**线程池服务器启动** **线程池服务器启动**
...@@ -722,7 +722,7 @@ public class WorkerCallable implements Callable<Float> { ...@@ -722,7 +722,7 @@ public class WorkerCallable implements Callable<Float> {
# 使用 HttpServer 执行器 # 使用 HttpServer 执行器
我们在[第 4 章](4.html "Chapter 4. Client/Server Development")*客户/服务器开发*中介绍了`HTTPServer`类。当 HTTP 服务器收到请求时,默认情况下,它使用在调用`start`方法时创建的线程。但是,也可以使用不同的线程。`setExecutor`方法指定如何将这些请求分配给线程。 我们在[第 4 章](4.html "Chapter 4. Client/Server Development")*客户/服务器开发*中介绍了`HTTPServer`类。当 HTTP 服务器收到请求时,默认情况下,它使用在调用`start`方法时创建的线程。但是,也可以使用不同的线程。`setExecutor`方法指定如何将这些请求分配给线程。
此方法的参数是一个`Executor`对象。对于这个参数,我们可以使用几种实现中的任何一种。按照以下顺序,使用缓存线程池: 此方法的参数是一个`Executor`对象。对于这个参数,我们可以使用几种实现中的任何一种。按照以下顺序,使用缓存线程池:
...@@ -736,7 +736,7 @@ public class WorkerCallable implements Callable<Float> { ...@@ -736,7 +736,7 @@ public class WorkerCallable implements Callable<Float> {
server.setExecutor(Executors.newFixedThreadPool(5)); server.setExecutor(Executors.newFixedThreadPool(5));
``` ```
必须先调用此方法,然后才能调用`HTTPServer``start`方法。然后将所有请求提交给执行人。以下是从[第 4 章](4.html "Chapter 4. Client/Server Development")*客户/服务器开发*中开发的`HTTPServer`类复制而来,并向您展示了`setExecutor`方法的使用: 必须先调用此方法,然后才能调用`HTTPServer``start`方法。然后将所有请求提交给执行人。以下是从[第 4 章](4.html "Chapter 4. Client/Server Development")*客户/服务器开发*中开发的`HTTPServer`类复制而来,并向您展示了`setExecutor`方法的使用:
```java ```java
public class MyHTTPServer { public class MyHTTPServer {
...@@ -877,7 +877,7 @@ public class MyHTTPServer { ...@@ -877,7 +877,7 @@ public class MyHTTPServer {
### 频道时间服务器 ### 频道时间服务器
时间服务器将接受与客户端应用程序的连接,并每秒向客户端发送当前日期和时间。当我们讨论客户机时会发现,客户机可能不会收到所有这些消息。 时间服务器将接受与客户端应用程序的连接,并每秒向客户端发送当前日期和时间。当我们讨论客户端时会发现,客户端可能不会收到所有这些消息。
时间服务器使用内部静态类`SelectorHandler`来处理选择器并发送消息。此类实现了`Runnable`接口,并将成为选择器的线程。 时间服务器使用内部静态类`SelectorHandler`来处理选择器并发送消息。此类实现了`Runnable`接口,并将成为选择器的线程。
...@@ -1132,12 +1132,12 @@ public class SocketChannelTimeClient { ...@@ -1132,12 +1132,12 @@ public class SocketChannelTimeClient {
我们介绍了三种线程体系结构,重点介绍了其中两种:每个请求的线程和每个连接的线程。每个请求线程模型为到达服务器的每个请求创建一个新线程。这适用于客户端一次发出一个或几个请求的情况。 我们介绍了三种线程体系结构,重点介绍了其中两种:每个请求的线程和每个连接的线程。每个请求线程模型为到达服务器的每个请求创建一个新线程。这适用于客户端一次发出一个或几个请求的情况。
每个连接的线程模型将创建一个线程来处理来自客户端的多个请求。这避免了必须多次重新连接到客户机以及必须承担创建多个线程的成本。这种方法适用于需要维护会话和状态信息的客户机 每个连接的线程模型将创建一个线程来处理来自客户端的多个请求。这避免了必须多次重新连接到客户端以及必须承担创建多个线程的成本。这种方法适用于需要维护会话和状态信息的客户端
线程池支持一种避免创建和销毁线程的方法。线程集合由线程池管理。未被使用的线程可以针对不同的请求重新调整用途。线程池的大小可以控制,因此可以根据应用程序和环境的要求进行限制。`Executor`类用于创建和管理线程池。 线程池支持一种避免创建和销毁线程的方法。线程集合由线程池管理。未被使用的线程可以针对不同的请求重新调整用途。线程池的大小可以控制,因此可以根据应用程序和环境的要求进行限制。`Executor`类用于创建和管理线程池。
NIO 的`Selector`课程进行了说明。这个类使得使用线程和 NIO 通道更容易。使用选择器注册通道和通道相关事件。当发生某个事件(如通道可用于读取操作)时,选择器提供对通道和事件的访问。这允许单个线程管理多个通道。 NIO 的`Selector`课程进行了说明。这个类使得使用线程和 NIO 通道更容易。使用选择器注册通道和通道相关事件。当发生某个事件(如通道可用于读取操作)时,选择器提供对通道和事件的访问。这允许单个线程管理多个通道。
我们简要地重新检查了[第 4 章](4.html "Chapter 4. Client/Server Development")*客户/服务器开发*中介绍的`HttpServer`类。我们演示了添加线程池以提高服务器性能是多么容易。我们还研究了网络超时的性质以及如何处理它们。当网络无法支持应用程序之间的及时通信时,可能会发生这种情况。 我们简要地重新检查了[第 4 章](4.html "Chapter 4. Client/Server Development")*客户/服务器开发*中介绍的`HttpServer`类。我们演示了添加线程池以提高服务器性能是多么容易。我们还研究了网络超时的性质以及如何处理它们。当网络无法支持应用程序之间的及时通信时,可能会发生这种情况。
在下一章中,我们将探讨网络安全威胁以及如何应对这些威胁。 在下一章中,我们将探讨网络安全威胁以及如何应对这些威胁。
\ No newline at end of file
# 第八章网络安全 # 八、网络安全
在本章中,我们将探讨 Java 为保护应用程序之间的通信提供的支持。我们将研究几个主题,包括以下内容: 在本章中,我们将探讨 Java 为保护应用程序之间的通信提供的支持。我们将研究几个主题,包括以下内容:
...@@ -148,7 +148,7 @@ Java 支持的对称算法包括以下算法,其中以位为单位的密钥大 ...@@ -148,7 +148,7 @@ Java 支持的对称算法包括以下算法,其中以位为单位的密钥大
} }
``` ```
我们将在*对称加密客户机/服务器*部分所示的 echo 客户机/服务器应用程序中使用这些方法。 我们将在*对称加密客户端/服务器*部分所示的 echo 客户端/服务器应用程序中使用这些方法。
## 非对称加密技术 ## 非对称加密技术
...@@ -229,7 +229,7 @@ public class AsymmetricKeyUtility { ...@@ -229,7 +229,7 @@ public class AsymmetricKeyUtility {
} }
``` ```
我们将使用一组方法将这些键保存和检索到单独的文件。这种方法不是最安全的,但它将简化 echo 客户/服务器的使用。下面的语句调用 save 方法: 我们将使用一组方法将这些键保存和检索到单独的文件。这种方法不是最安全的,但它将简化 echo 客户/服务器的使用。下面的语句调用 save 方法:
```java ```java
savePrivateKey(privateKey); savePrivateKey(privateKey);
...@@ -727,7 +727,7 @@ public class SymmetricKeyStoreCreation { ...@@ -727,7 +727,7 @@ public class SymmetricKeyStoreCreation {
# 对称加密客户端/服务器 # 对称加密客户端/服务器
本节演示如何在客户机/服务器应用程序中使用对称加密/解密。下面的示例实现了一个简单的 echo 客户机/服务器,使我们能够专注于基本流程,而不必脱离具体的客户机/服务器问题。服务器使用`SymmetricEchoServer`类实现,客户端使用`SymmetricEchoClient`类实现。 本节演示如何在客户端/服务器应用程序中使用对称加密/解密。下面的示例实现了一个简单的 echo 客户端/服务器,使我们能够专注于基本流程,而不必脱离具体的客户端/服务器问题。服务器使用`SymmetricEchoServer`类实现,客户端使用`SymmetricEchoClient`类实现。
客户端将加密消息并将其发送到服务器。然后,服务器将解密消息并以纯文本形式将其发送回。如果需要,可以轻松加密响应。这种单向加密足以说明基本过程。 客户端将加密消息并将其发送到服务器。然后,服务器将解密消息并以纯文本形式将其发送回。如果需要,可以轻松加密响应。这种单向加密足以说明基本过程。
...@@ -837,7 +837,7 @@ public class SymmetricEchoServer { ...@@ -837,7 +837,7 @@ public class SymmetricEchoServer {
## 对称客户端应用 ## 对称客户端应用
下面将介绍客户机应用程序,它与[第 1 章](1.html "Chapter 1. Getting Started with Network Programming")*网络编程入门*中开发的客户机应用程序非常相似。它使用与服务器中相同的`getSecretKey`方法。对称加密技术中解释的`encrypt`方法用于加密用户的消息。这两种方法在此不重复: 下面将介绍客户端应用程序,它与[第 1 章](1.html "Chapter 1. Getting Started with Network Programming")*网络编程入门*中开发的客户端应用程序非常相似。它使用与服务器中相同的`getSecretKey`方法。对称加密技术中解释的`encrypt`方法用于加密用户的消息。这两种方法在此不重复:
```java ```java
public class SymmetricEchoClient { public class SymmetricEchoClient {
...@@ -905,7 +905,7 @@ public class SymmetricEchoClient { ...@@ -905,7 +905,7 @@ public class SymmetricEchoClient {
} }
``` ```
我们现在准备好看客户和服务器是如何交互的。 我们现在准备好看客户和服务器是如何交互的。
## 对称客户端/服务器正在运行 ## 对称客户端/服务器正在运行
...@@ -947,7 +947,7 @@ public class SymmetricEchoClient { ...@@ -947,7 +947,7 @@ public class SymmetricEchoClient {
# 非对称加密客户端/服务器 # 非对称加密客户端/服务器
在非对称加密技术中开发的`AsymmetricKeyUtility`类用于支持客户端和服务器应用程序。我们将使用它的`encrypt``decrypt`方法。客户和服务器应用程序的结构与前几节中使用的类似。客户端将向服务器发送一条加密消息,服务器将解密该消息,然后用纯文本响应。 在非对称加密技术中开发的`AsymmetricKeyUtility`类用于支持客户端和服务器应用程序。我们将使用它的`encrypt``decrypt`方法。客户和服务器应用程序的结构与前几节中使用的类似。客户端将向服务器发送一条加密消息,服务器将解密该消息,然后用纯文本响应。
## 非对称服务器应用 ## 非对称服务器应用
...@@ -1017,7 +1017,7 @@ while 循环将从客户端读入加密消息。使用消息和私钥调用`decr ...@@ -1017,7 +1017,7 @@ while 循环将从客户端读入加密消息。使用消息和私钥调用`decr
## 非对称客户端应用 ## 非对称客户端应用
客户应用程序位于`AsymmetricEchoClient`类中的,如下所示。它也只有一个`main`方法。建立服务器连接后,将建立 IO 流: 客户应用程序位于`AsymmetricEchoClient`类中的,如下所示。它也只有一个`main`方法。建立服务器连接后,将建立 IO 流:
```java ```java
public class AsymmetricEchoClient { public class AsymmetricEchoClient {
...@@ -1130,7 +1130,7 @@ TLS/SSL 在提供这些功能时确实会导致性能下降。然而,随着互 ...@@ -1130,7 +1130,7 @@ TLS/SSL 在提供这些功能时确实会导致性能下降。然而,随着互
我们将不深入探讨 SSL 协议如何工作的细节。然而,关于本协议的简要讨论可在[中找到 http://www.javacodegeeks.com/2013/04/understanding-transport-layer-security-secure-socket-layer.html](http://www.javacodegeeks.com/2013/04/understanding-transport-layer-security-secure-socket-layer.html) 。在本节中,我们将说明如何创建和使用 SSL 服务器以及用于支持此协议的 Java 类。 我们将不深入探讨 SSL 协议如何工作的细节。然而,关于本协议的简要讨论可在[中找到 http://www.javacodegeeks.com/2013/04/understanding-transport-layer-security-secure-socket-layer.html](http://www.javacodegeeks.com/2013/04/understanding-transport-layer-security-secure-socket-layer.html) 。在本节中,我们将说明如何创建和使用 SSL 服务器以及用于支持此协议的 Java 类。
为了简化应用程序,客户机向服务器发送一条消息,然后服务器显示该消息。没有将响应发送回客户端。客户端使用 SSL 连接到服务器并与服务器通信。使用 SSL 将消息返回给客户机是留给读者的一个练习。 为了简化应用程序,客户端向服务器发送一条消息,然后服务器显示该消息。没有将响应发送回客户端。客户端使用 SSL 连接到服务器并与服务器通信。使用 SSL 将消息返回给客户端是留给读者的一个练习。
## SSL 服务器 ## SSL 服务器
...@@ -1176,7 +1176,7 @@ public class SSLServer { ...@@ -1176,7 +1176,7 @@ public class SSLServer {
new InputStreamReader(sslSocket.getInputStream())); new InputStreamReader(sslSocket.getInputStream()));
``` ```
下面的 while 循环读取并显示客户请求。如果消息为`quit`,则服务器终止: 下面的 while 循环读取并显示客户请求。如果消息为`quit`,则服务器终止:
```java ```java
String inputLine; String inputLine;
...@@ -1351,7 +1351,7 @@ public class SHAHashingExample { ...@@ -1351,7 +1351,7 @@ public class SHAHashingExample {
第二种方法使用非对称加密。此技术使用私钥和公钥。用其中一个密钥加密的消息可以用另一个密钥解密。通常,使用来自可信来源的证书分发公钥。私钥的持有者需要保护私钥,以便其他人无法访问它。公钥可以与任何需要它的人自由共享。 第二种方法使用非对称加密。此技术使用私钥和公钥。用其中一个密钥加密的消息可以用另一个密钥解密。通常,使用来自可信来源的证书分发公钥。私钥的持有者需要保护私钥,以便其他人无法访问它。公钥可以与任何需要它的人自由共享。
加密密钥通常存储在密钥库中,该密钥库允许对密钥进行编程访问。密钥库是通过 keytool 应用程序创建和维护的。我们在几个应用程序中演示了密钥库的创建和使用。此外,我们使用对称密钥和非对称密钥对来支持 echo 客户/服务器应用程序。 加密密钥通常存储在密钥库中,该密钥库允许对密钥进行编程访问。密钥库是通过 keytool 应用程序创建和维护的。我们在几个应用程序中演示了密钥库的创建和使用。此外,我们使用对称密钥和非对称密钥对来支持 echo 客户/服务器应用程序。
创建安全客户端和服务器的一种更常见的方法是使用`SSLServerSocket`类。这将根据密钥库中找到的密钥对数据执行自动加密和解密。我们演示了如何在服务器和客户端应用程序中使用该类。 创建安全客户端和服务器的一种更常见的方法是使用`SSLServerSocket`类。这将根据密钥库中找到的密钥对数据执行自动加密和解密。我们演示了如何在服务器和客户端应用程序中使用该类。
......
# 第 9 章网络互操作性 # 九、网络互操作性
网络互操作性是指在实现技术上不同的系统能够可靠、准确地交换信息。这意味着,基础硬件、操作系统和实现语言等因素在不同平台之间可能有所不同,但它们不会对这些系统的通信能力产生不利影响。 网络互操作性是指在实现技术上不同的系统能够可靠、准确地交换信息。这意味着,基础硬件、操作系统和实现语言等因素在不同平台之间可能有所不同,但它们不会对这些系统的通信能力产生不利影响。
...@@ -219,7 +219,7 @@ public class JavaSocket { ...@@ -219,7 +219,7 @@ public class JavaSocket {
## 客户 ## 客户
`CSharpClient`类实现了客户,如下所示。C#在形式和语法上与 Java 相似,尽管类库通常不同。我们将不提供代码的详细解释,但我们将介绍应用程序的重要功能。 `CSharpClient`类实现了客户,如下所示。C#在形式和语法上与 Java 相似,尽管类库通常不同。我们将不提供代码的详细解释,但我们将介绍应用程序的重要功能。
`using`语句对应 Java 中的 import 语句。与 Java 类似,第一个要执行的方法是`Main`方法。C#通常使用与 Java 不同的缩进样式和名称约定: `using`语句对应 Java 中的 import 语句。与 Java 类似,第一个要执行的方法是`Main`方法。C#通常使用与 Java 不同的缩进样式和名称约定:
...@@ -453,7 +453,7 @@ RESTful 服务可以被任意数量的用各种语言编写的应用程序调用 ...@@ -453,7 +453,7 @@ RESTful 服务可以被任意数量的用各种语言编写的应用程序调用
如果我们需要与其他语言通信,我们发现基于 JVM 的语言更容易使用,因为它们共享相同的字节码库。如果我们需要使用其他语言,那么 JNI 是常用的。 如果我们需要与其他语言通信,我们发现基于 JVM 的语言更容易使用,因为它们共享相同的字节码库。如果我们需要使用其他语言,那么 JNI 是常用的。
套接字不是 Java 特有的概念。它通常用于 TCP/IP 环境,这意味着用一种语言编写的套接字可以轻松地与用另一种语言编写的套接字通信。我们使用 Java 服务器和 C#客户演示了这种能力。 套接字不是 Java 特有的概念。它通常用于 TCP/IP 环境,这意味着用一种语言编写的套接字可以轻松地与用另一种语言编写的套接字通信。我们使用 Java 服务器和 C#客户演示了这种能力。
我们还探讨了中间件如何通过抽象许多底层通信细节来支持互操作性。通过使用 web 服务等概念,我们了解到底层套接字交互的细节是隐藏的。我们使用 JAX-RS 演示了这一点,JAX-RS 支持 RESTful 方法,其中 HTTP 命令(如 GET 和 POST)映射到特定的 Java 功能。 我们还探讨了中间件如何通过抽象许多底层通信细节来支持互操作性。通过使用 web 服务等概念,我们了解到底层套接字交互的细节是隐藏的。我们使用 JAX-RS 演示了这一点,JAX-RS 支持 RESTful 方法,其中 HTTP 命令(如 GET 和 POST)映射到特定的 Java 功能。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册