Java多线程服务器无法按预期工作 [英] Java Multi threaded server not working as expected

查看:88
本文介绍了Java多线程服务器无法按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个多线程服务器,该服务器应该能够一次接受多个HTTP请求.

I am trying to write a multi-threaded server which should be capable of accepting multiple HTTP requests at a time.

服务器代码:

package test.thread.server;

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;

    public class MyServer implements Runnable {
        private int serverPort = 8080;
        private ServerSocket serverSocket;
        private Thread runningThread;
        private boolean isStopped;

        public MyServer(int port){
            this.serverPort = port;
        }


        @Override
        public void run() {
            synchronized (this) {
                this.runningThread = Thread.currentThread();
            }

            openServerSocket();


            while(!isStopped){

                Socket clientSocket = null;

                try {
                    clientSocket = this.serverSocket.accept();
                } catch (IOException e) {
                    e.printStackTrace();
                }


                //start a new thread for processing each request
                new Thread(new RequestHandler(clientSocket)).start();
            }

        }

    public synchronized void stop(){
        this.isStopped = true;
        try {
            this.serverSocket.close();
        } catch (IOException e) {
            throw new RuntimeException("Error closing server", e);
        }
    }


    private void openServerSocket(){
        try {
            this.serverSocket = new ServerSocket(this.serverPort);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

处理请求的工作人员:

它从输入流中读取数据并进行打印.之后,它应该进行30秒钟的睡眠(表示不需要CPU的某些工作).睡眠时间过后,服务器将响应客户端.

It reads the data from input stream and prints it. After that it should go for a 30 second sleep[represents some work which does not need CPU]. After sleep time, server will respond to client.

package test.thread.server;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Date;

public class RequestHandler implements Runnable {
    Socket clientSocket;

    static int counter = 0;

    public RequestHandler(Socket clientSocket){
        this.clientSocket = clientSocket;
    }

    @Override
    public void run() {

        try {
            InputStream input = this.clientSocket.getInputStream();
            OutputStream output = this.clientSocket.getOutputStream();


            DataInputStream inFromClient = new DataInputStream(input);
            System.out.println(new Date()+": " +Thread.currentThread().getName() + " - Started : "+inFromClient.readUTF());

            Thread.sleep(30000);

            /*output.write(("HTTP/1.1 200 OK\n\n<html><body>" +
                    "Multi-threaded Server " +
                    "</body></html>").getBytes());*/

            DataOutputStream outFromServer = new DataOutputStream(output);
            outFromServer.writeUTF("Output");
            outFromServer.flush();

            output.close();
            input.close();

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }

}

HTTP客户端:

客户端无需担心服务器的睡眠时间,它将连续发送5个请求.

Client is not bothered about the server sleep time and will send 5 consecutive requests.

package test.thread.server;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Date;

public class MyClient {

    public static void main(String[] args) throws UnknownHostException, IOException {
        // TODO Auto-generated method stub
        for(int i=0; i<5; i++){
            Socket clientSocket = new Socket("localhost", 8080);
             DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
             DataInputStream inFromServer = new DataInputStream(clientSocket.getInputStream());


             outToServer.writeUTF("Input");
             outToServer.flush();

             String output = inFromServer.readUTF();
             System.out.println(new Date()+": "+output);
             clientSocket.close();
        }
    }

}

现在,我希望服务器在一个线程进入睡眠状态时处理下一个客户端请求.但是很遗憾,服务器仅在处理前一个请求之后才接受下一个请求.

Now i am expecting the server to process the next client request when one thread goes on sleep. But unfortunately server is accepting next request only after the previous request is processed.

期望o/p:

在为下一个请求打印"Thread-X-Started:Input"之前,服务器不应等待当前请求过程完成.

Server should not wait for current request process to complete before printing 'Thread-X - Started : Input' for next request.

当前o/p:

Server: Wed Feb 15 18:17:06 IST 2017: Thread-1 - Started : Input
Client: Wed Feb 15 18:17:36 IST 2017: Output
Server:Wed Feb 15 18:17:36 IST 2017: Thread-2 - Started : Input
Client:Wed Feb 15 18:18:06 IST 2017: Output
Server:Wed Feb 15 18:18:06 IST 2017: Thread-3 - Started : Input
Client:Wed Feb 15 18:18:36 IST 2017: Output
Server:Wed Feb 15 18:18:43 IST 2017: Thread-4 - Started : Input
Client:Wed Feb 15 18:19:13 IST 2017: Output
Server:Wed Feb 15 18:19:13 IST 2017: Thread-5 - Started : Input
Client:Wed Feb 15 18:19:43 IST 2017: Output

可能是什么问题?

推荐答案

我相信问题出在您的客户中.客户端仅在回答前一个请求后才发送下一个请求. inFromServer.readUTF()会一直阻塞,直到有可用数据为止,只有在您的服务器发送实际答案时,这种情况才会发生.

I believe the problem is in your client. The client only sends the next request after the previous one was answered. The inFromServer.readUTF() blocks until data is available, which is only the case when your server sends an actual answer.

我建议您调试程序.

这篇关于Java多线程服务器无法按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆