Поток сервер / клиент останавливается после присоединения второго клиента

1

У меня есть сервер, который использует несколько потоков для приема нескольких клиентов. У меня есть тот момент, когда клиент что-то набирает, он появляется на сервере как Client: text Это отлично работает для 1 клиента. Однако проблема заключается в том, когда присоединяется второй клиент.

Они присоединяются к штрафу, и они могут набирать штраф. Но первый клиент может набирать только одно, а затем останавливается, то есть их сообщения не появляются на сервере. Я предполагаю, что они могут сделать 1, поскольку метод был запущен, но не повторяется. Я пробовал while (true) цикл (как видно из кода) и, ссылаясь на метод в конце, не работает. Я новичок в программировании, поэтому у меня нет большого опыта в этом. Пожалуйста, найдите код ниже :) (Примечание, отступ правильный, просто не скопирован правильно)

Сервер:

    package dod;

    import java.net.*;
    import java.util.*;
    import java.util.concurrent.atomic.AtomicInteger;
    import java.io.*;

    public class Server implements Runnable
    {
    PrintWriter out;
    BufferedReader in;
    Socket clientSocket;
    ServerSocket serverSocket;
    int portNumber;
    AtomicInteger numClients = new AtomicInteger(0);


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

        s.startup();
    }

    public void run()
    {}


    /**
     * 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("C"+numClients.getAndIncrement())
        {
            public void run()
            {
                accept();
            }
        };
        thread.start();
    }

    public void accept()
    {
        try
        {
            clientSocket = serverSocket.accept();
            System.out.println("A new client has just connected.");
        } catch(IOException e)
        {
            System.out.println("error");
            System.exit(0);
        }
        newThread();
        listenCommand();

    }


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

                String userInput;
                while ((userInput = in.readLine()) != null)
                {
                    System.out.println("client: " + userInput);
                }
            } catch (IOException e)
            {
                System.out.println("Error");
                System.exit(0);
            }
        }
    }
}

Клиент:

    package dod;

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


    public class Client
    {
    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));

            String userInput;
            while ((userInput = stdIn.readLine()) != null)
            {
                out.println(userInput);
            }
        } catch(UnknownHostException e) {
            System.out.println("error in host");
        } catch(IOException e) {
            System.out.println("error in IO");
        }


    }
}

Спасибо! :)

Теги:
multithreading
networking
client

1 ответ

1
Лучший ответ

* подчеркнутый текст * В классе Server у вас должен быть поток, который прослушивает появление новых клиентов и присваивает им свой собственный сокет. У вас есть сокет и потоки как переменные-члены, поэтому каждый раз, когда приходит новый клиент, вы заменяете сокет. Также вы открываете новый поток для соединения accept, а не для самого клиента.

Проверьте следующее (см., Что клиентский сокет - это другой поток, и я создал для него Runnable):

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicInteger;

public class Server
{
    ServerSocket serverSocket;
    int portNumber;
    AtomicInteger numClients = new AtomicInteger(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("C"+numClients.getAndIncrement())
        {
            public void run()
            {   
                while(true) {
                    try {
                        accept();
                    } catch (Exception e) {
                        // lof the exception
                    }
                }
            }
        };
        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.");
        } catch(IOException e)
        {
            System.out.println("User disconnected");
            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()));

                    String userInput;
                    while ((userInput = in.readLine()) != null)
                    {
                        System.out.println("client: " + userInput);
                    }
                } catch (IOException e)
                {
                    System.out.println("Error. Probably client disconnected");
                    // System.exit(0); do you want to exist when a client disconnects?
                }
            }
        }
    }
}
  • 1
    Почти готово. Не совсем. Потоки все еще являются переменными класса. В классе сервера не должно быть переменных уровня потока.
  • 0
    Ой, спасибо. Я исправил это.
Показать ещё 9 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню