简体   繁体   English

为什么我的代码无法在Java多线程中运行许多客户端?

[英]Why is it my code cannot run many clients in java multithreading?

Why is this code nott accumulating many clients? 为什么此代码不能累积许多客户端? I'm new to java. 我是Java新手。 It only runs for only 1 client. 它仅可用于1个客户端。 Can anyone explain why it doesn't support multiple clients for socket programming? 谁能解释为什么它不支持套接字编程的多个客户端?

import java.net.*;
import java.io.*;

/**
 * Demo Server: Contains a multi-threaded socket server sample code.
 */
public class ServerDemo extends Thread
{
    final static int _portNumber = 5559; //Arbitrary port number

    public static void main(String[] args) 
    {
        try {
            new ServerDemo().startServer();
        } catch (Exception e) {
            System.out.println("I/O failure: " + e.getMessage());
            e.printStackTrace();
        }

    }

    public void startServer() throws Exception {
        ServerSocket serverSocket = null;
        boolean listening = true;

        try {
            serverSocket = new ServerSocket(_portNumber);
        } catch (IOException e) {
            System.err.println("Could not listen on port: " + _portNumber);
            System.exit(-1);
        }

        while (listening) {
            handleClientRequest(serverSocket);
        }

        serverSocket.close();
    }

    private void handleClientRequest(ServerSocket serverSocket) {
        try {
            new ConnectionRequestHandler(serverSocket.accept()).run();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Handles client connection requests. 
     */
    public class ConnectionRequestHandler implements Runnable{
        private Socket _socket = null;
        private PrintWriter _out = null;
        private BufferedReader _in = null;

        public ConnectionRequestHandler(Socket socket) {
            _socket = socket;
        }

        public void run() {
            System.out.println("Client connected to socket: " + _socket.toString());

            try {
                _out = new PrintWriter(_socket.getOutputStream(), true);
                _in = new BufferedReader(new InputStreamReader(_socket.getInputStream()));

                String inputLine, outputLine;
                BusinessLogic businessLogic = new BusinessLogic();
                outputLine = businessLogic.processInput(null);
                _out.println(outputLine);

                //Read from socket and write back the response to client. 
                while ((inputLine = _in.readLine()) != null) {
                    outputLine = businessLogic.processInput(inputLine);
                    if(outputLine != null) {
                        _out.println(outputLine);
                        if (outputLine.equals("exit")) {
                            System.out.println("Server is closing socket for client:" + _socket.getLocalSocketAddress());
                            break;
                        }
                    } else {
                        System.out.println("OutputLine is null!!!");
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally { //In case anything goes wrong we need to close our I/O streams and sockets.
                try {
                    _out.close();
                    _in.close();
                    _socket.close();
                } catch(Exception e) { 
                    System.out.println("Couldn't close I/O streams");
                }
            }
        }

    }

    /**
     * Handles business logic of application.
     */
    public static class BusinessLogic {
        private static final int LoginUserName = 0;
        private static final int LoginPassword = 1;
        private static final int AuthenticateUser = 2;
        private static final int AuthSuccess   = 3;

        private int state = LoginUserName;

        private String userName =  null;
        private String userPassword =  null;

        public String processInput(String clientRequest) {
            String reply = null;
            try {
                if(clientRequest != null && clientRequest.equalsIgnoreCase("login")) {
                    state = LoginPassword;
                }if(clientRequest != null && clientRequest.equalsIgnoreCase("exit")) {
                    return "exit";
                }

                if(state == LoginUserName) {
                    reply = "Please Enter your user name: ";
                    state = LoginPassword;
                } else if(state == LoginPassword) {
                    userName = clientRequest;
                    reply = "Please Enter your password: ";
                    state = AuthenticateUser;
                } else if(state == AuthenticateUser) {
                    userPassword = clientRequest;
                    if(userName.equalsIgnoreCase("John") && userPassword.equals("doe")) { 
                        reply = "Login Successful...";
                        state = AuthSuccess;
                    } else {
                        reply = "Invalid Credentials!!! Please try again. Enter you user name: ";
                        state = LoginPassword;
                    }
                } else {
                    reply = "Invalid Request!!!";
                }
            } catch(Exception e) {
                System.out.println("input process falied: " + e.getMessage());
                return "exit";
            }

            return reply;
        }
    }
}

You are not starting the thread in your code. 您没有在代码中启动线程。

instead of 代替

new ConnectionRequestHandler(serverSocket.accept()).run();

call 呼叫

new Thread(new ConnectionRequestHandler(serverSocket.accept())).start();

method run() of your Runnable class will be invoked when you start your thread, you should not call this run() method directly. 方法run()您的Runnable的类将被调用,当你开始你的线程,你不应该调用这个run()直接方法。

Instead of that you should make a thread instance via 相反,您应该通过以下方式创建线程实例

Thread myThread = new Thread(aRunnableInstance);

and start it: 并启动它:

myThread.start();

You're not starting a new thread, but simply running the RequestHandler code in the main thread. 您不是在启动新线程,而只是在主线程中运行RequestHandler代码。

Look up the difference between Thread.start() and Runnable.run() . 查找Thread.start()Runnable.run()之间的区别。 This question might help. 这个问题可能会有所帮助。

Edit: 编辑:

You're just missing the part where you would tell the JVM to create a new Thread to execute your Runnable code. 您只是缺少告诉JVM创建一个新线程来执行您的Runnable代码的部分。 Without a call to Thread.start() your current (and only) thread would be busy handling one request at a time. 如果不调用Thread.start(),则当前(且仅)线程将一次忙于处理一个请求。 You want one Thread per request, basically. 基本上,每个请求您需要一个线程。 There are more advanced ways of doing this (thread pools and whatnot), but this should get you started. 有更高级的方法可以执行此操作(线程池等),但这应该可以帮助您入门。

private void handleClientRequest(ServerSocket serverSocket) {
    try {
        new Thread(ConnectionRequestHandler(serverSocket.accept())).start();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM