2013-02-26 68 views
0

我正在创建一个多线程服务器程序,当它尝试连接到本地主机时显示浏览器的请求。Java Socket Programming =>只有IE9的作品?

我发现只有IE9在我的Windows上工作正常,但不是Firefox 19,Chrome,Opera。只是坐在那里等待我的程序响应。

我错过了什么?

import java.io.*; 
import java.net.*; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

public class HTTPEchoServer { 

    private static final String serverName = "HTTPEchoServer"; 
    private static final int port = 80; 
    private static final String CRLF = "\r\n"; 
    private static final Logger logger = Logger.getLogger(serverName); 

    private static void printHeader(PrintWriter out) { 
     out.println("HTTP/1.0 200 OK\r\n" + "Server: " + serverName + CRLF 
       + "Content-Type: text/html" + CRLF + CRLF 
       + "<!DOCTYPE HTML PUBLIC " 
       + "\"-//W3C//DTD HTML 4.0 Transitional//EN\">\n" 
       + "<HTML>\n" 
       + "<HEAD>\n" 
       + " <TITLE>" + "HTTP Echo Server Result</TITLE>\n" 
       + "</HEAD>\n" 
       + "<H1>HTML Received from HTTP Echo Server</H1>\n" 
       + "<B>Here is the request sent by your browser:</B>\n" 
       + "<PRE>"); 
    } 

    private static void printTrailer(PrintWriter out) { 
     out.println("</PRE>\n" + "</BODY>\n" + "</HTML>\n"); 
    } 

    static class ClientHandler extends Thread { 

     Socket socket = null; 

     public ClientHandler(Socket socket) { 
      this.socket = socket; 
     } 

     @Override 
     public void run() { 

      logger.log(Level.INFO, "Accepted client {0}:{1}", 
        new Object[]{socket.getInetAddress(), socket.getPort()}); 
      try { 

       InputStream is = socket.getInputStream(); 
       OutputStream os = socket.getOutputStream(); 
       try (PrintWriter writer = new PrintWriter(os, true)) { 
        synchronized (this) { 
         printHeader(writer); 
         writer.flush(); 
         BufferedReader reader = new BufferedReader 
          (new InputStreamReader(is)); 
         String line; 
         while ((line = reader.readLine()) != null) { 
          writer.println(line); 
          writer.flush(); 
         } 
         printTrailer(writer); 
         writer.flush(); 
         writer.close(); 
        } 
       } 
       socket.close(); 
      } catch (IOException ex) { 
       logger.log(Level.SEVERE, null, ex); 
      } 
      logger.log(Level.INFO, "Disconnected client {0}:{1}", 
new Object[]{socket.getInetAddress(), socket.getPort()}); 
     } 
    } 

    public static void main(String[] args) {  

     try { 
      ServerSocket server = new ServerSocket(port); 
      logger.log(Level.INFO, "Server started, listening at port {0} ...", port); 
      ExecutorService executor = Executors.newCachedThreadPool(); 
      while (true) { 
       Socket socket = server.accept(); 
       ClientHandler handler = new ClientHandler(socket); 
       executor.execute(handler); 
      } 
     } catch (IOException ex) { 
      logger.log(Level.SEVERE, null, ex); 
     } 
    } 
}  

另外,我发现,除非我改变端口为8080。我已经我的OS X 10.8.2计算机上禁用防火墙我不能运行在OS X这个程序。我得到的错误是:

<pre> 
java.net.BindException: Permission denied 
    at java.net.PlainSocketImpl.socketBind(Native Method) 
    at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:376) 
    at java.net.ServerSocket.bind(ServerSocket.java:376) 
    at java.net.ServerSocket.<init>(ServerSocket.java:237) 
    at java.net.ServerSocket.<init>(ServerSocket.java:128) 
    at HTTPEcho.HTTPEchoServer.main(HTTPEchoServer.java:80) 
</pre> 
+1

端口是特权,你需要(SUID)根绑定到他们,比照[这个问答](http://stackoverflow.com/questions/10182798/why-are-ports-below-1024-privileged)。 – 2013-02-26 10:08:31

回答

0

由于例外本身说java.net.BindException: Permission denied。您需要成为root用户才能绑定1024以下的端口。如果你在linux上,你可以通过sudo java HTTPEchoServer来启动服务器。

其他可能性可能是您已经有一台运行在端口80上的服务器。

2

你可以在除了MSIE所有浏览器中的小应用程序无法打开服务器套接字。这是因为打开服务器套接字是违反安全性的。如果你确实想这样做,你必须签署你的小程序。

我希望我能正确理解您的代码在applet环境中运行(因为您提到过浏览器),尽管我无法从您的堆栈跟踪中看到这个方面,它从main()开始。

编辑: 我再次阅读您的文章,并理解您的问题实际上包含两个问题:第一个关于小程序,第二个关于在Unix下运行的应用程序。对于unix @Anders R. Bystrup给出了答案:只有root可以听取1024以下的端口。因此,您必须以root身份或使用sudo来运行程序。

顺便说一句,你似乎错了。你可能会解释一下你想达到什么目标,社区可能会给你一个更好的解决方案。

+1

他应该使用[网络套接字](http://en.wikipedia.org/wiki/Web_Socket)而不是 – Esailija 2013-02-26 10:14:02

+0

@Esailija,我同意你的意见。这就是我说他出于各种原因可能出错的原因。 – AlexR 2013-02-26 10:15:25

+0

你好AlexR, 感谢您的回复。 1.我只是在NetBeans(NetBeans 7.3,Java 1.7.0_15)中运行我的代码而不是applet。另外,我试图从终端运行代码,发现结果是一样的。 2.是的,SU按预期工作。 – 2013-02-26 15:34:08