java线程池服务器:我只能读取请求或成功发送响应,但不能两者兼有

bfhwhh0e  于 2021-07-08  发布在  Java
关注(0)|答案(1)|浏览(289)

我目前正在测试我正在编写的一个java服务器,它实际上不是http服务器,但目前我正在尝试将从浏览器接收到的客户机请求数据输出到控制台,然后向浏览器发送响应,浏览器将显示我在浏览器窗口中发送的文本。我正在遵循jenkov.com的教程,但我正在尝试创建一个抽象的connectionhandler来处理特定服务器上的所有请求。以下是我目前的代码:
测试客户端.java

public class TestClient {
    public static void main(String[] args) {
        Server messageServer = new Server(80);
        messageServer.start(new ConnectionHandler() {
            @Override
            public void request(InputStream req, OutputStream res) {
                try {
                    // When I comment out the code for reading from req, then the response
                    // successfully sends, but if I try to read the request and output it to
                    // to the console, it hangs forever
                    BufferedReader reader = new BufferedReader(new InputStreamReader(req));

                    String line;
                    while ((line = reader.readLine()) != null)
                        System.out.println(line);

                    reader.close();
                    long time = System.currentTimeMillis();
                    res.write(("HTTP/1.1 200 OK\n\nWorkerRunnable: " +
                            "Multithreaded Server" + " - " +
                            time +
                            "").getBytes());
                    res.close();
                    System.out.println("Request processed: " + time);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

服务器.java:

public class Server implements Runnable {
    private int port;
    private Thread runningThread = null;
    private ServerSocket ss = null;
    private boolean running = false;
    private ExecutorService threadPool = Executors.newFixedThreadPool(100);
    private ConnectionHandler handler;

    public Server(int port) {
        this.port = port;
    }

    public void start(ConnectionHandler handler) {
        this.handler = handler;
        this.running = true;
        new Thread(this).start();
    }

    public synchronized boolean isRunning() {
        return running;
    }

    public synchronized void stop() {
        this.running = false;
        try {
            this.ss.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void run() {
        synchronized (this) {
            this.runningThread = Thread.currentThread();
        }
        try {
            this.ss = new ServerSocket(this.port);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("Listening on port " + this.port + "...");

        while (this.isRunning()) {
            Socket client;
            try {
                client = this.ss.accept();
                System.out.println("Incoming connection from " + client.getRemoteSocketAddress());
            } catch (IOException e) {
                if (!this.isRunning()) {
                    System.out.println("The server stopped.");
                    return;
                }
                e.printStackTrace();
                continue;
            }
            this.threadPool.execute(new ClientHandler(client, this.handler));
        }
        this.threadPool.shutdown();
    }
}

clienthandler.java文件:

public class ClientHandler implements Runnable {
    private Socket sock = null;
    private String serverText = "Multithreaded Server";
    private ConnectionHandler handler;

    public ClientHandler(Socket sock, ConnectionHandler handler) {
        this.sock = sock;
        this.handler = handler;
    }

    public void run() {
        try {
            this.handler.request(this.sock.getInputStream(), this.sock.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

connectionhandler.java:

public abstract class ConnectionHandler {
    public abstract void request(InputStream req, OutputStream res);
}

在控制台中输出请求读取代码(但浏览器挂起,页面未加载):

Listening on port 80...
Incoming connection from /0:0:0:0:0:0:0:1:59404
GET / HTTP/1.1
Host: localhost
User-Agent: ...
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: ...
Accept-Encoding: gzip, deflate
Connection: keep-alive
Cookie: ...
Upgrade-Insecure-Requests: 1

我想我想知道我做得对不对。我真的希望能够有一个单一的连接处理程序,可以在testclient内部定义的多个线程上正常工作。我不确定是否应该同步server.java中的connectionhandler,因为我只有一个处理连接的每个线程可以访问的处理程序。请帮我找出我做错了什么,我对java线程有点陌生…谢谢。

ca1c2owp

ca1c2owp1#

我似乎在这里找到了问题的答案。当从req流中读取一行时,您必须编写如下内容:

while ((line = reader.readLine()) != null && !line.equals(""))
    System.out.println(line);

这似乎解决了我的问题!

相关问题