Connecting to a Server
Before writing our first network program, letrsquo;s discuss a great debugging tool for network programming that you already have —namely, telnet. Telnet is pre-installed on most systems. You should be able to launch it by typing telnet from a command shell.
You may have used telnet to connect to a remote computer, but you can use it to communicate with other services provided by Internet hosts as well. Here is an example of what you can do. Type telnet time-A.timefreq.bldrdoc.gov 13 As Figure 3.1 shows, you should get back a line like this: 54276 07-06-25 21:37:31 50 0 0 659.0 UTC(NIST) *
Figure 3.1. Output of the “time of day” service
What is going on? You have connected to the “time of day” service that most UNIX machines constantly run. The particular server that you connected to is operated by the National Institute of Standards and Technology in Boulder, Colorado, and gives the measurement of a Cesium atomic clock. (Of course, the reported time is not completely accurate due to network delays.) By convention, the “time of day” service is always attached to “port” number 13.
The server software is continuously running on the remote machine, waiting for any network traffic that wants to chat with port 13. When the operating system on the remote computer receives a network package that contains a request to connect to port number 13, it wakes up the listening server process and establishes the connection. The connection stays up until it is terminated by one of the parties. When you began the telnet session with time-A.timefreq.bldrdoc.gov at port 13, a piece of network software knew enough to convert the string 'time-A. timefreq.bldrdoc.gov' to its correct Internet Protocol (IP) address, 132.163.4.103. The telnet software then sent a connection request to that address, asking for a connection to port 13. Once the connection was established, the remote program sent back a line of data and closed the connection. In general, of course, clients and servers engage in a more extensive dialog before one or the other closes the connection. Here is another experiment along the same lines—but a bit more interesting. Type
telnet horstmann.com 80
Then type very carefully the following:
GET / HTTP/1.1
Host: horstmann.com
blankline
That is, hit the Enter key twice at the end.
Figure 3.3 shows the response. It should look eerily familiar—you got a page of HTML-formatted text, namely Cay Horstmannrsquo;s home page.
Figure 3.3. Using telnet to access an HTTP port
This is exactly the same process that your web browser goes through to get a web page. It uses HTTP to request web pages from servers. Of course, the browser displays the HTML code more nicely.
Our first network program in Listing 3.1 will do the same thing we did using telnet—connect to a port and print out what it finds.
socket/SocketTest.java
Socket s = new Socket('time-A.timefreq.bldrdoc.gov', 13);
InputStream inStream = s.getInputStream();
The first line opens a s o c k e t , which is a network software abstraction that enables communication out of and into this program. We pass the remote address and the port number to the socket constructor. If the connection fails, an UnknownHostException is thrown. If there is another problem, an IOException occurs. Since UnknownHostException is a subclass of IOException and this is a sample program, we just catch the superclass.
Once the socket is open, the getInputStream method in java.net.Socket returns an InputStream object that you can use just like any other stream. Once you have grabbed the stream, this program simply prints each input line to standard output. This process continues until the stream is finished and the server disconnects.
This program works only with very simple servers, such as a “time of day” service. In more complex networking programs, the client sends request data to the server, and the server might not immediately disconnect at the end of a response. You will see how to implement that behavior in several examples throughout this chapter.
The Socket class is pleasant and easy to use because the Java library hides the complexities of establishing a networking connection and sending data across it. The java.net package essentially gives you the same programming interface you would use to work with a file.
Socket Timeouts
Reading from a socket blocks until data are available. If the host is unreachable, your application waits for a long time and you are at the mercy of the underlying operating system to eventually time out.
You can decide what timeout value is reasonable for your particular application. Then, call the setSoTimeout method to set a timeout value (in milliseconds).
Socket s = new Socket(. . .);
s.setSoTimeout(10000); // time out after 10 seconds
If the timeout value has been set for a socket, all subsequent read and write operations throw a SocketTimeoutException when the timeout has been reached before the operation has completed its work. You can catch that exception and react to the timeout.
There is one additional timeout issue that you need to address. The constructor
Socket(String host, int port)
can block indefinitely until an initial connection to the host is established.
You can overcome this problem by first constructing an unconnected socket and then connecting it with a timeout:
Socket s = new Socket();
s.connect(new InetSocketAddress(host, port), timeout);
Internet Addresses
Usually, you donrsquo;t have to worry too much about Internet addresses—the numerical host addresses that consist of 4 bytes (or, with IPv6, 16 bytes) such as 132.163.4.102. However, you ca
全文共22524字,剩余内容已隐藏,支付完成后下载完整资料
连接到服务器
在编写第一个网络程序之前, 让我们讨论一下您已经拥有的网络编程的一个很好的调试工具--即 telnet。Telnet 是在大多数系统上预安装的。您应该能够通过从命令 shell 中键入 telnet 来启动它。
您可能已使用 telnet 连接到远程计算机, 但您可以使用它与 Internet 主机提供的其他服务进行通信。下面是一个你可以做什么的例子。类型 telnet 时间 a. timefreq. bldrdoc. 州长13如图3.1 所示, 您应该回到这样的线: 54276 07-06-25 21:37:31 50 0 0 659.0 UTC (NIST) *
图3.1。'日间时间' 服务的输出
这是怎么回事?您已连接到大多数 UNIX 计算机经常运行的 '日间时间' 服务。您所连接的特定服务器由美国科罗拉多州博尔德国家标准和技术研究所操作, 并提供了铯原子钟的测量。(当然, 由于网络延迟, 报告的时间并不完全准确。按照惯例, '天的时间' 服务总是附加到 '端口' 号13。
服务器软件在远程计算机上连续运行, 等待任何要与端口13进行聊天的网络通信。当远程计算机上的操作系统收到一个包含连接到13端口号的请求的网络包时, 它唤醒侦听服务器进程并建立连接。连接保持不变, 直到它被一方终止。当您开始 telnet 会话时, timefreq. bldrdoc 在端口13上, 一个网络软件知道足够的转换字符串 '时间 a。timefreq.bldrdoc.gov '到其正确的互联网协议 (IP) 地址, 132.163.4.103。然后, telnet 软件向该地址发送了一个连接请求, 要求连接到端口13。建立连接后, 远程程序发送回一行数据并关闭连接。当然, 通常情况下, 客户端和服务器在一个或另一个关闭连接之前进行更广泛的对话。这里是另一个沿着同一条线的实验-但更有趣一点。输入
telnet horstmann.com 80
然后仔细输入以下内容:
GET / HTTP/1.1
Host: horstmann.com
Blankline
即, 在末尾按 Enter 键两次。
图3.3 显示了响应。它应该看起来怪异熟悉-你有一页 HTML 格式的文本, 即 Horstmann 的主页。
图3.3。使用 telnet 访问 HTTP 端口
这与 web 浏览器通过获取网页的过程完全相同。它使用 HTTP 从服务器请求网页。当然, 浏览器更能显示 HTML 代码。
我们在清单3.1 中的第一个网络程序将做同样的事情, 我们使用 telnet-连接到一个端口, 并打印出它发现什么。
socket/SocketTest.java
Socket s = new Socket('time-A.timefreq.bldrdoc.gov', 13);
InputStream inStream = s.getInputStream();
第一行打开 s o c t, 这是一个网络软件抽象, 使通信出和进入这个程序。我们将远程地址和端口号传递给套接字构造函数。如果连接失败, 将引发 UnknownHostException。如果存在另一个问题, 则会发生 IOException。由于 UnknownHostException 是 IOException 的子类, 这是一个示例程序, 我们只捕获了超类别。
打开套接字后, java.net.Socket 中的 getInputStream 方法将返回一个 InputStream 对象, 您可以像其他任何流一样使用它。一旦你抓住了流, 这个程序只是把每个输入行打印到标准输出。此过程将继续, 直到流完成并且服务器断开连接。
此程序仅适用于非常简单的服务器, 例如 '一天中的时间' 服务。在更复杂的网络程序中, 客户端向服务器发送请求数据, 服务器在响应结束时可能不会立即断开连接。在本章的几个示例中, 您将看到如何实现该行为。
套接字类令人愉快且易于使用, 因为 Java 库隐藏了建立网络连接和跨它发送数据的复杂性。java.net 包实质上提供了与文件一起使用的编程接口。
套接字超时
在数据可用之前从套接字块读取。如果主机无法访问, 您的应用程序将等待很长时间, 并且您将在底层操作系统的摆布下最终超时。
您可以决定哪些超时值对于特定应用程序是合理的。然后, 调用 setSoTimeout 方法设置超时值 (以毫秒为单位)。
Socket s = new Socket(. . .);
s.setSoTimeout(10000); // time out after 10 seconds
如果已为套接字设置了超时值, 则在操作完成其工作之前, 所有后续读写操作都将引发 SocketTimeoutException。您可以捕获该异常并对超时做出响应。
还有一个额外的超时问题需要解决。的构造函数
Socket(String host, int port)
可以无限期阻止, 直到建立与主机的初始连接。
您可以通过首先构造一个未连接的套接字, 然后将其与超时连在一起来克服此问题:
Socket s = new Socket();
s.connect(new InetSocketAddress(host, port), timeout);
互联网地址
通常, 您不必太担心 Internet 地址--由4字节 (或 IPv6、16字节) (如 132.163.4.102) 组成的数字主机地址。但是, 如果需要在主机名和 Internet 地址之间进行转换, 则可以使用 InetAddress 类。
java.net 包支持 IPv6 Internet 地址, 前提是主机操作系统确实如此。
静态 getByName 方法返回主机的 InetAddress 对象。例如,
InetAddress address = InetAddress.getByName('time-A.timefreq.bldrdoc.gov');
返回一个封装四字节132.163.4.104 序列的 InetAddress 对象。可以使用 getAddress 方法访问字节。
byte[] addressBytes = address.getAddress();
一些具有大量通信量的主机名对应于多个 Internet 地址, 以方便负载平衡。例如, 在编写本报告时, 主机名 google.com 对应于十二种不同的 Internet 地址。访问主机时随机选取其中一个。您可以使用 getAllByName 方法获取所有主机。
InetAddress[] addresses = InetAddress.getAllByName(host);
最后, 有时需要本地主机的地址。如果您只是要求本地主机的地址, 则您总是得到当地环回地址 127.0.0.1, 而其他用户则无法使用它来连接到您的计算机。而是使用静态 getLocalHost 方法获取本地主机的地址。
最后, 有时需要本地主机的地址。如果您只是要求本地主机的地址, 则您总是得到当地环回地址 127.0.0.1, 而其他用户则无法使用它来连接到您的计算机。而是使用静态 getLocalHost 方法获取本地主机的地址。
InetAddress address = InetAddress.getLocalHost();
InetAddress/InetAddressTest java
实现服务器
现在, 我们已经实现了一个从 Internet 接收数据的基本网络客户端, 让我们编写一个可以向客户端发送信息的简单服务器。启动服务器程序后, 它会等待客户端附加到其端口。我们选择了8189号端口, 这不是任何标准服务所使用的。ServerSocket 类建立一个套接字。在我们的情况下, 命令
ServerSocket s = new ServerSocket(8189);
建立监视端口8189的服务器。该命令
Socket incoming = s.accept();
通知程序无限期地等待, 直到客户端连接到该端口。一旦有人通过网络发送正确的请求连接到此端口, 此方法将返回一个表示所做连接的套接字对象。可以使用此对象获取输入和输出流, 如下面的代码所示:
InputStream inStream = incoming.getInputStream();
OutputStream outStream = incoming.getOutputStream();
服务器发送到服务器输出流的所有内容都将成为客户端程序的输入, 客户端程序中的所有输出都在服务器输入流中结束。
在本章的所有示例中, 我们通过套接字传输文本。因此, 我们将流变成扫描仪和编写器。
Scanner in = new Scanner(inStream);
PrintWriter out = new PrintWriter(outStream, true /* autoFlush */);
让我们向客户发送一个问候语:
out.println('Hello! Enter BYE to exit.');
在端口8189上使用 telnet 连接到此服务器程序时, 将在终端屏幕上看到前面的问候语。
在这个简单的服务器中, 我们只读取客户端输入, 一次一行, 然后对它进行回显。这说明程序接收到客户端的输入。实际的服务器将明显地计算并根据输入返回答案。
String line = in.nextLine();
out.println('Echo: ' line);
if (line.trim().equals('BYE')) done = true;
最后, 我们关闭输入插座。
incoming.close();
这就是一切。每个服务器程序 (如 HTTP web 服务器) 继续执行此循环:
- 它通过传入的数据流接收来自客户端的命令 ('获取此信息')。
- 它解码客户端命令。
- 收集客户要求的信息。
- 它通过传出的数据流向客户端发送信息。
这是完整的程序:
获取 Web 数据
要访问 Java 程序中的 web 服务器, 您将希望在更高的级别上工作, 而不是进行套接字连接和发出 HTTP 请求。在以下各节中, 我们将讨论 Java 库为此目的提供的类。
urls 和 uris
URL 和 URLConnection 类封装了从远程站点检索信息的许多复杂性。可以从字符串构造 URL 对象:
URL url = new URL( u r l S t r i n g );
如果只想获取资源的内容, 请使用 URL 类的 openStream 方法。此方法生成一个 InputStream 对象。例如, 以通常的方式使用它来构造扫描仪:
InputStream inStream = url.openStream();
Scanner in = new Scanner(inStream);
java.net 包对 url (统一资源 l o c a t o s) 和 uri (统一资源 i e n) 进行了有用的区分。
URI 是一个纯粹的语法构造, 它包含指定 web 资源的字符串的各个部分。URL 是一种特殊的 URI, 即, 一个具有足够信息到 l c a 的资源。其他 uri, 如
不是定位器-没有要从该标识符找到的数据。这样的 URI 称为瓮 (统一资源 n a m e)。在 Java 库中, URI 类没有访问标识符指定的资源的方法-它的唯一目的是分析。相反, URL 类可以向资源打开流。因此, URL 类仅适用于 Java 库知道如何处理的方案, 如 http:、https:、ftp:、本地文件系统 (文件:) 和 jar 文件 (jar:)。
要了解为什么解析不是微不足道的, 请考虑 uri 的复杂程度。例如,
http://maps.yahoo.com/py/maps.py?csz=Cuper
资料编号:[11773],资料为PDF文档或Word文档,PDF文档可免费转换为Word
以上是毕业论文外文翻译,课题毕业论文、任务书、文献综述、开题报告、程序设计、图纸设计等资料可联系客服协助查找。