0

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);
        }
    }
}    

また、ポートを8080に変更しない限り、このプログラムをOSXで実行できないことがわかりました。OSX10.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>
4

3 に答える 3

2

MSIEを除くすべてのブラウザで、アプレットでサーバーソケットを開くことはできません。これは、サーバーソケットを開くことがセキュリティ違反であるために行われます。これを実行したい場合は、アプレットに署名する必要があります。

から始まるスタックトレースからはこのファセットを確認できませんが、コードがアプレット環境で実行されていることを正しく理解したことを願っています(ブラウザについて言及したため)main()

編集:私はあなたの投稿をもう一度読み、あなたの質問には実際には2つの質問が含まれていることを理解しました。1つはアプレットに関するもので、もう1つはUnixでのアプリケーションとしての実行に関するものです。UNIXの場合、@ Anders R. Bystrupが答えを出しました。1024未満のポートをリッスンできるのはrootだけです。したがって、rootとして、またはを使用してプログラムを実行する必要がありますsudo

ところで、あなたは間違った方向に進んでいるようです。あなたはおそらくあなたが達成したいことを説明できますか、そしてコミュニティはおそらくあなたにもっと良い解決策のためのヒントを与えることができます。

于 2013-02-26T10:10:42.240 に答える
0

例外自体が言うようにjava.net.BindException: Permission deniedroot以下のポートをバインドするには、ユーザーである必要があります1024。Linuxを使用している場合はsudo java HTTPEchoServer、サーバーを起動する必要があります。

他の可能性としては、ポートでサーバーがすでに実行されている可能性があります80

于 2013-02-26T10:11:25.790 に答える
0

ポート80は予約済みのHTTPポートであり、予約されている他のポートもあります。

管理機能用のポート1から1023は、1024を超えるポート番号を使用できるようにします。

利用可能なポートを見つける方法

于 2013-02-26T10:11:34.957 に答える