【问题标题】:Multiple threads dont seem to be working多个线程似乎没有工作
【发布时间】:2014-03-31 16:17:08
【问题描述】:

我有 2 个类,一个服务器和一个客户端。服务器使用多个线程来接受许多客户端。所以 x 客户端可以加入同一个服务器。但是,在尝试从客户端方法中识别线程时,我似乎发现它没有创建多个线程,因为所有客户端的 ID 都是相同的。我的代码如下:

服务器:

public class Server
{
    ServerSocket serverSocket;
    int portNumber;
    public static volatile String userInput;
    public volatile int noOfClients = 0;

public static void main(String[] args)
{
    Server s = new Server();
    s.startup();
}


/**
 * Start the server on the user picked port
 */
public void startup()
{   
    try 
    {
        System.out.println("Enter a port");
        Scanner dif = new Scanner(System.in);
        portNumber = Integer.parseInt(dif.nextLine());
        dif.close();

        serverSocket = new ServerSocket(portNumber);
        newThread();
    }
    catch (IOException e) {
        System.out.println("Error");
        System.exit(0);
    }
}


public void newThread()
{
    Thread thread =new Thread()
    {

        public void run()
        {   
            while(true) {
                try {

                    accept();
                } catch (Exception e) {
                    System.out.println("Error");
                }
            }
        }
    };
    thread.start();
}

public void accept()
{
    try
    {
        Socket clientSocket = serverSocket.accept();
        new Thread(new ClientSocket(clientSocket)).start();
        System.out.println("A new client has just connected.");
        noOfClients++;

    } catch(IOException e)
    {
        System.out.println("Error");
        System.exit(0);
    }
}


class ClientSocket implements Runnable {
    Socket clientSocket;

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

    public void run() {
        {
            try
            {
                PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);                   
                BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

                while (true)
                {
                    userInput = in.readLine();
                }

            } catch (IOException e)
            {
                System.out.println("Error");
            }
        }
    }
}
}

客户:

public class Client
{
    Socket clientSocket;
    public static int threadName;


public static void main(String[] args) throws IOException {
    String hostName = args[0];
    int portNumber = Integer.parseInt(args[1]);


    try {
        Socket serverSocket = new Socket(hostName, portNumber);
        PrintWriter out = new PrintWriter(serverSocket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(new InputStreamReader(serverSocket.getInputStream()));
        BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));

        Thread thread = Thread.currentThread();
        System.out.println("RunnableJob is being run by " + thread.getName() + " (" + thread.getId() + ")");
        String userInput;

        while ((userInput = stdIn.readLine()) != null)
        {

            out.println(userInput);
            System.out.println("Server: " + userInput);
        }

    } catch(UnknownHostException e) {
        System.out.println("error in host");
    } catch(IOException e) {
        System.out.println("error in IO");
    }


}
}

当运行两个单独的客户端时,

System.out.println("RunnableJob is being run by " + thread.getName() + " (" + thread.getId() + ")");

代码行打印出相同的内容。我该如何修复它,以便每个新的客户端连接都是在自己的唯一线程中启动的。所以2个客户端总共有2个线程?谢谢:)

【问题讨论】:

  • 您正在客户端上打印线程名称。您不想知道服务器程序中的线程名称吗?
  • 我认为您的意思是检查服务器中的线程,而不是客户端。
  • @spinlok 我想要做的是如果线程 ID=1 执行此操作...否则什么也不做,然后递增到如果 ID=1 执行此操作...等等。所以基本上我想唯一地识别线程,一次只做一个,然后对下一个做同样的事情,依此类推。希望这是有道理的
  • @KyleSpence 刚刚将该行移到服务器中,它提供了单独的 ID。我已经想到了一种方法,我可以从服务器类而不是客户端做我想做的事情,谢谢你的帮助!
  • 所以你想根据他们的线程 ID 唯一地识别客户端?由于它们处于不同的运行时,因此它们彼此分开。

标签: java multithreading


【解决方案1】:

首先,您正在检查客户端的线程 ID,它们彼此分开,所以这不起作用。

但是,使用线程 ID 并不是识别客户端的好方法。相反,你为什么不计算客户端的数量,然后当有新的加入时,增加数字并将该数字作为 id 给客户端对象。

【讨论】:

    【解决方案2】:

    多个客户端将在不同的端口号与服务器连接。您可以使用该端口号来区分客户端。

    如果需要,您可以将ClientSocket 存储在某个位置以便将来检索每个客户端的其他信息,如下面的代码所示。

    代码如下:

    private static HashMap<Integer, ClientSocket> clientInfo = new HashMap<Integer, ClientSocket>();
    class ClientSocket implements Runnable {
        Socket clientSocket;
    
        public ClientSocket(Socket clientSocket) {
            this.clientSocket = clientSocket;
            System.out.println(clientSocket.getPort());
            clientInfo.put(clientSocket.getPort(), this);
        }
        ...
    

    阅读更多关于Java Server with Multiclient communication的信息。

    【讨论】:

    • 多个客户端可以连接到不同端口号的服务器,多个客户端可以连接到服务器with the same port number。服务器可以设置为以任何一种方式工作。
    • 是的,你完全正确。现在取决于你想在哪里实现逻辑。
    猜你喜欢
    • 2013-11-25
    • 2017-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-25
    相关资源
    最近更新 更多