socket详解
8. 创建 RemoteFileServer 类
这里是 RemoteFileServer 类的结构:
Java代码
1. import java.io.*;
2. import java.net.*;
3.
4. public class RemoteFileServer {
5. protected int listenPort = 3000;
6. public static void main(String[] args) {
7. }
8. public void acceptConnections() {
9. }
10. public void handleConnection(Socket incomingConnection) {
11. }
12. }
[java] view plain copy
print?
1. import java.io.*;
2. import java.net.*;
3.
4. public class RemoteFileServer {
5. protected int listenPort = 3000;
6. public static void main(String[] args) {
7. }
8. public void acceptConnections() {
9. }
10. public void handleConnection(Socket incomingConnection) {
11. }
12. }
跟客户机中一样,我们首先导入 java.net 的 java.io。接着,我们给我们的类一个实例变量以保存端口,我们从该端口侦听进入的连接。缺省情况下,端口是 3000。
我们的类有一个 main() 方法和两个其它方法。稍后我们将探究这些方法的细节。现在您只需知道 acceptConnections() 将允许客户机连接到服务器以及handleConnection() 与客户机 Socket 交互以将您所请求的文件的内容发送到客户机。
9. 实现 main()
这里我们实现 main() 方法,它将创建 RemoteFileServer 并告诉它接受连接:
Java代码
1. public static void main(String[] args) {
2. RemoteFileServer server = new RemoteFileServer();
3. server.acceptConnections();
4. }
[java] view plain copy
print?
1. public static void main(String[] args) {
2. RemoteFileServer server = new RemoteFileServer();
3. server.acceptConnections();
4. }
服务器端的 main() 方法甚至比客户机端的更简单。我们实例化一个新 RemoteFileServer,它将在缺省侦听端口上侦听进入的连接请求。然后我们调用acceptConnections() 来告诉该 server 进行侦听。
10. 接受连接
这里我们实现 acceptConnections() 方法,它将创建一个 ServerSocket 并等待连接请求:
Java代码
1. public void acceptConnections() {
2. try {
3. ServerSocket server = new ServerSocket(listenPort);
4. Socket incomingConnection = null;
5. while (true) {
6. incomingConnection = server.accept();
7. handleConnection(incomingConnection);
8. }
9. } catch (BindException e) {
10. System.out.println("Unable to bind to port " + listenPort);
11. } catch (IOException e) {
12. System.out.println("Unable to instantiate a ServerSocket on port: " + listenPort);
13. }
14. } <span>
15. </span>
[java] view plain copy
print?
1. public void acceptConnections() {
2. try {
3. ServerSocket server = new ServerSocket(listenPort);
4. Socket incomingConnection = null;
5. while (true) {
6. incomingConnection = server.accept();
7. handleConnection(incomingConnection);
8. }
9. } catch (BindException e) {
10. System.out.println("Unable to bind to port " + listenPort);
11. } catch (IOException e) {
12. System.out.println("Unable to instantiate a ServerSocket on port: " + listenPort);
13. }
14. } <span>
15. </span>
acceptConnections() 用欲侦听的端口号来创建 ServerSocket。然后我们通过调用该 ServerSocket 的 accept() 来告诉它开始侦听。accept() 方法将造成阻塞直到来了一个连接请求。此时,accept() 返回一个新的 Socket,这个 Socket 绑定到服务器上一个随机指定的端口,返回的 Socket 被传递给handleConnection()。请注意我们在一个无限循环中处理对连接的接受。这里不支持任何关机。
无论何时如果您创建了一个无法绑定到指定端口(可能是因为别的什么控制了该端口)的 ServerSocket,Java 代码都将抛出一个错误。所以这里我们必须捕捉可能的 BindException。就跟在客户机端上时一样,我们必须捕捉 IOException,当我们试图在 ServerSocket 上接受连接时,它就会被抛出。请注意,您可以通过用毫秒数调用 setSoTimeout() 来为 accept() 调用设置超时,以避免实际长时间的等待。调用 setSoTimeout() 将使 accept() 经过指定占用时间后抛出 IOException。