2012-06-26 47 views
2

我在Windows 7 x64上的Java中使用ServerSocket进行实验。 我写了一个小程序,在端口8080上托管HTTP服务器,并且只返回包含类加载器的toString()的静态HTML响应。当使用ServerSocket绑定已经使用的端口时,Java 7不抛出BindException

我在节目中主要做了:

  1. 上的ServerSocket创建一个ServerSocket
  2. 呼叫setReuseAddress(假)
  3. 绑定端口8080此套接字
  4. 使用一个永远的循环接受插座并给予回复

首先我试着用JRE 1.6.0_23,一切都很好:一次启动ED和响应正常,二审无法启动,因为异常被抛出:

Exception in thread "main" java.net.BindException: Address already in use: JVM_Bind 

意想不到的事情发生了,当我和JRE 1.7.0_5尝试:比如都可以成功地推出,但只有第一个实例给出了回应。在第一个实例被杀死之后,第二个实例开始响应。

我做错了什么或者这是JRE 7的错误?

import java.io.IOException; 
import java.net.InetSocketAddress; 
import java.net.ServerSocket; 
import java.net.Socket; 

public class TestServerSocket { 
    private static final String HEADER = "HTTP/1.1 200 OK\r\n" + "Content-type: text/html\r\n" 
      + "Connection: close\r\n" + "\r\n"; 

    private static final int PORT = 8080; 

    private static void handle(Socket socket) { 
     System.out.println(socket.getInetAddress() + ":" + socket.getPort()); 
     StringBuilder buffer = new StringBuilder(); 
     buffer.append(HEADER); 
     buffer.append(TestServerSocket.class.getClassLoader()); 
     try { 
      socket.getOutputStream().write(buffer.toString().getBytes()); 
     } catch (IOException e) { 
     } finally { 
      try { 
       socket.close(); 
      } catch (IOException e) { 
      } 
     } 

    } 

    public static void main(String[] args) throws IOException { 
     int port; 

     try { 
      port = Integer.parseInt(args[0]); 
     } catch (Exception e) { 
      port = PORT; 
     } 

     final ServerSocket server = new ServerSocket(); 
     server.setReuseAddress(false); 
     server.bind(new InetSocketAddress(port)); 

     // Terminator thread, stop when Ctrl-D is entered 
     new Thread() { 
      public void run() { 
       try { 
        while (System.in.read() != 4); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
       try { 
        server.close(); 
       } catch (IOException e) { 
       } 
       System.exit(0); 
      } 
     }.start(); 

     System.out.println("Listening on: " + port); 
     Socket client = null; 
     while (true) { 
      try { 
       client = server.accept(); 
       handle(client); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 
+2

也许你可以告诉我们你的代码? – carlspring

+0

+1没有代码,它是不可能找到错误的来源 –

+0

@carlspring如你所愿。 – Lacek

回答

1

要隔离问题,我建议您运行以下测试代码。 Apache HttpCore basic server。它是标准的API,在这个特定的例子中使用了ServerSocket,所以在你的环境中出现故障的可能性很小(Java 7)。

万一它失败,你肯定会知道问题不在你的代码中。同时我会在我的工作机器上在JDK 7上试用您的代码,并且会进行更新。

+0

ElementalHttpServer按照使用构造函数'ServerSocket(int port)'的方式工作。我使用了构造函数'ServerSocket()'并使用'bind()'方法来指定端口。然后,我尝试在代码中将'setReuseAddress(false)'与'bind(...)'交换,现在在JRE 7中运行良好。但是我错过了任何提及'bind()'和' setReuseAddress()'很重要? – Lacek

+1

这是我在提到setReuseAddress()时提到的错误: 未定义在套接字绑定后启用或禁用SO_REUSEADDR(请参阅isBound())时的行为。 – Lacek

相关问题