一个秘密的套接字
1. 介绍
Java 平台在 java.net
包中提供套接字的实现。在本教程中,我们将与 java.net
中的以下三个类一起工作:
-
URLConnection
-
Socket
-
ServerSocket
java.net
中还有更多的类,但这些是您将最经常碰到的。让我们从URLConnection
开始。这个类为您不必了解任何底层套接字细节就能在 Java 代码中使用套接字提供一种途径。
2. 甚至不用尝试就可使用套接字
URLConnection
类是所有在应用程序和 URL 之间创建通信链路的类的抽象超类。URLConnection
在获取 Web 服务器上的文档方面特别有用,但也可用于连接由 URL 标识的任何资源。该类的实例既可用于从资源中读,也可用于往资源中写。例如,您可以连接到一个 servlet 并发送一个格式良好的 XMLString
到服务器上进行处理。URLConnection
的具体子类(例如 HttpURLConnection
)提供特定于它们实现的额外功能。对于我们的示例,我们不想做任何特别的事情,所以我们将使用URLConnection
本身提供的缺省行为。
连接到 URL 包括几个步骤:
- 创建
URLConnection
- 用各种 setter 方法配置它
- 连接到 URL
- 用各种 getter 方法与它交互
接着,我们将看一些演示如何用 URLConnection
来从服务器请求文档的样本代码
3. URLClient 类
我们将从 URLClient
类的结构讲起。
import java.io.*;
import java.net.*;
public class URLClient {
protected URLConnection connection;
public static void main(String[] args) {
}
public String getDocumentAt(String urlString) {
}
}
要做的第一件事是导入 java.net
和java.io
。
我们给我们的类一个实例变量以保存一个 URLConnection
。
我们的类有一个 main()
方法,它处理浏览文档的逻辑流。我们的类还有一个getDocumentAt()
方法,该方法连接到服务器并向它请求给定文档。下面我们将分别探究这些方法的细节。
4. 浏览文档
main()
方法处理浏览文档的逻辑流:
public static void main(String[] args) {
URLClient client = new URLClient();
String yahoo = client.getDocumentAt("http://www.yahoo.com");
System.out.println(yahoo);
}
我们的 main()
方法只是创建一个新的URLClient
并用一个有效的 URLString
调用 getDocumentAt()
。当调用返回该文档时,我们把它存储在String
,然后将它打印到控制台。然而,实际的工作是在getDocumentAt()
方法中完成的。
5. 从服务器请求一个文档
getDocumentAt()
方法处理获取 Web 上的文档的实际工作
public String getDocumentAt(String urlString) {
StringBuffer document = new StringBuffer();
try {
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null)
document.append(line + "\n");
reader.close();
} catch (MalformedURLException e) {
System.out.println("Unable to connect to URL: " + urlString);
} catch (IOException e) {
System.out.println("IOException when connecting to URL: " + urlString);
}
return document.toString();
}
getDocumentAt()
方法有一个String
参数,该参数包含我们想获取的文档的 URL。我们在开始时创建一个StringBuffer
来保存文档的行。然后我们用我们传进去的urlString
创建一个新URL
。接着创建一个 URLConnection
并打开它:
URLConnection conn = url.openConnection();
一旦有了一个 URLConnection
,我们就获取它的InputStream
并包装进InputStreamReader
,然后我们又把InputStreamReader
包装进BufferedReader
以使我们能够读取想从服务器上获取的文档的行。在 Java 代码中处理套接字时,我们将经常使用这种包装技术,但我们不会总是详细讨论它。在我们继续往前讲之前,您应该熟悉它:
BufferedReader reader =
new BufferedReader(new InputStreamReader(conn.getInputStream()));
有了 BufferedReader
,就使得我们能够容易地读取文档内容。我们在while
循环中调用reader
上的 readLine()
:
String line = null;
while ((line = reader.readLine()) != null)
document.append(line + "\n");
对 readLine()
的调用将直至碰到一个从InputStream
传入的行终止符(例如换行符)时才阻塞。如果没碰到,它将继续等待。只有当连接被关闭时,它才会返回null
。在这个案例中,一旦我们获取一个行(line),我们就把它连同一个换行符一起附加(append)到名为document
的 StringBuffer
上。这保留了服务器端上读取的文档的格式。
我们在读完行之后关闭 BufferedReader
:
reader.close();
如果提供给 URL
构造器的urlString
是无效的,那么将抛出MalformedURLException
。如果发生了别的错误,例如当从连接上获取InputStream
时,那么将抛出IOException
。
6. 总结
实际上,URLConnection
使用套接字从我们指定的 URL 中读取信息(它只是解析成 IP 地址),但我们无须了解它,我们也不关心。但有很多事;我们马上就去看看。
在继续往前讲之前,让我们回顾一下创建和使用 URLConnection
的步骤:
- 用您想连接的资源的有效 URL
String
实例化一个URL
(如有问题则抛出MalformedURLException
)。
- 打开该
URL
上的一个连接。
- 把该连接的
InputStream
包装进BufferedReader
以使您能够读取行。
- 用
BufferedReader
读文档。
- 关闭
BufferedReader
。
附: URLClient
的完整代码清单:
import java.io.*;
import java.net.*;
public class URLClient {
protected HttpURLConnection connection;
public String getDocumentAt(String urlString) {
StringBuffer document = new StringBuffer();
try {
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null)
document.append(line + "\n");
reader.close();
} catch (MalformedURLException e) {
System.out.println("Unable to connect to URL: " + urlString);
} catch (IOException e) {
System.out.println("IOException when connecting to URL: " + urlString);
}
return document.toString();
}
public static void main(String[] args) {
URLClient client = new URLClient();
String yahoo = client.getDocumentAt("http://www.yahoo.com");
System.out.println(yahoo);
}
}