簡體   English   中英

為什么我的代碼無法在Java多線程中運行許多客戶端?

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

為什么此代碼不能累積許多客戶端? 我是Java新手。 它僅可用於1個客戶端。 誰能解釋為什么它不支持套接字編程的多個客戶端?

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

您沒有在代碼中啟動線程。

代替

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

呼叫

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

方法run()您的Runnable的類將被調用,當你開始你的線程,你不應該調用這個run()直接方法。

相反,您應該通過以下方式創建線程實例

Thread myThread = new Thread(aRunnableInstance);

並啟動它:

myThread.start();

您不是在啟動新線程,而只是在主線程中運行RequestHandler代碼。

查找Thread.start()Runnable.run()之間的區別。 這個問題可能會有所幫助。

編輯:

您只是缺少告訴JVM創建一個新線程來執行您的Runnable代碼的部分。 如果不調用Thread.start(),則當前(且僅)線程將一次忙於處理一個請求。 基本上,每個請求您需要一個線程。 有更高級的方法可以執行此操作(線程池等),但這應該可以幫助您入門。

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