【问题标题】:Java Socket Programming => only IE9 works?Java Socket 编程 => 只有 IE9 有效?
【发布时间】:2013-02-11 17:30:09
【问题描述】:

我正在创建一个多线程服务器程序,以在浏览器尝试连接到 localhost 时显示它的请求。

我发现我的 Windows 上只有 IE9 可以正常工作,但 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);
        }
    }
}    

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

<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>

【问题讨论】:

  • 1024以下的端口是特权的,你需要是(suid)root才能绑定到它们,参见。 this Q&A.

标签: java sockets


【解决方案1】:

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

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

编辑: 我再次阅读了您的帖子,了解到您的问题实际上包含 2 个问题:第一个是关于小程序的问题,第二个是关于在 Unix 下作为应用程序运行的问题。对于 unix,@Anders R. Bystrup 给了你答案:只有 root 可以监听 1024 以下的端口。所以,你必须以 root 或使用sudo 运行你的程序。

顺便说一句,您似乎走错了路。您能否解释一下您想要实现的目标,社区可能会为您提供更好的解决方案的提示。

【讨论】:

  • @Esailija,我同意你的看法。这就是我说他可能由于各种原因走错路的原因。
  • 您好 AlexR,感谢您的回复。 1. 我只是在 NetBeans(NetBeans 7.3,Java 1.7.0_15)中运行我的代码,而不是小程序。另外,我刚刚尝试从终端运行代码,发现结果是一样的。 2. 是的,SU 按预期工作。
  • > 你能解释一下你想要实现什么...只是一个命令行程序,它用基本格式回显任何http客户端的请求头。
【解决方案2】:

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

其他可能是您已经在端口80 上运行了一个服务器。

【讨论】:

    【解决方案3】:

    80端口是保留的HTTP端口,还有其他端口是保留的。

    端口 1 到 1023 用于管理功能,使大于 1024 的端口号可供使用。

    How to find available port

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      相关资源
      最近更新 更多