2013-02-26 28 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