一个秘密的套接字
1. 介绍
Java 平台在 java.net
包中提供套接字的实现。在本教程中,我们将与 java.net
中的以下三个类一起工作:
URLConnection
Socket
ServerSocket
java.net
中还有更多的类,但这些是您将最经常碰到的。让我们从 URLConnection
开始。这个类为您不必了解任何底层套接字细节就能在 Java 代码中使用套接字提供一种途径。
2. 甚至不用尝试就可使用套接字
URLConnection
类是所有在应用程序和 URL 之间创建通信链路的类的抽象超类。URLConnection
在获取 Web 服务器上的文档方面特别有用,但也可用于连接由 URL 标识的任何资源。该类的实例既可用于从资源中读,也可用于往资源中写。例如,您可以连接到一个 servlet 并发送一个格式良好的 XML String
到服务器上进行处理。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
并用一个有效的 URL String
调用 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);
}
}