0

(Предупреждение, что некоторые из этого кода будут похожи на онлайн-уроки)Java Sockets - одновременное выполнение одного и того же клиента параллельно.


Я думаю, что я сделал это так, что мой сервер может обрабатывать несколько запросов одновременно, используя темы, но я не совсем уверен, , И вдобавок ко всему, я не знаю, как я на самом деле отправлю несколько запросов сразу.

Моя цель состоит в том, чтобы параллельно запускать мой клиентский код, чтобы увидеть, что произойдет, если несколько клиентов подключится к серверу одновременно.

код клиента (в отдельном пакете проекта):

 Client clientSocket = new Client(9990,"localhost"); 
     Socket socket = new Socket(clientSocket.host,clientSocket.portNumber); 
     clientSocket.performTask(socket); 

(«performTask (гнездо)» отправляет данные на сервер для выполнения задачи)

кода сервера (отдельного пакета проекта от клиентского кода):

Server server = new Server(9990); 
    int clientNumber = 0; 
    ServerSocket socket = new ServerSocket(server.portNumber); 
    try { 
     while (true) { 
      new ServerHandler(socket.accept(),clientNumber).go(); 
      clientNumber++; 
     } 
    } 
    finally { 
     socket.close(); 
     } 
} 

ServerHandler класса (тот же пакет проектов как код сервера):

public class ServerHandler extends Thread { 
    private static Socket socket; 
    private static int clientNumber; 

    public ServerHandler(Socket socket, int clientNumber) { 
     ServerHandler.socket = socket; 
     ServerHandler.clientNumber = clientNumber; 
    } 

    public void go() { 
     while(true) { 
     try { 
      //do calculation, do server tasks, etc. 
      } 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     } 
    } 

Поэтому, когда клиент подключается к серверу, сервер реализует класс ServerHandler для выполнения необходимых вычислений: идея заключается в том, чтобы несколько клиентов могли подключать все одновременно.

Итак, мой вопрос состоит из двух частей:

(1) Установил я мои программы, чтобы обеспечить многопоточность, или я сделал ошибку где-то по пути? (например, кто-то сказал, что мне нужно использовать «Runnable» где-то использовать многопоточность, и я замечаю, у меня нет)

(2) После фиксации мой код, чтобы позволить многопоточности, как бы я на самом деле использовать его, чтобы я мог запускать свой клиентский код параллельно?

ответ

1

ОК для стартеров, ваш ServerHandler расширяет класс Thread. Поэтому, чтобы заставить его работать как отдельный поток, всегда вызывайте, вызывая метод start(). Вы вызываете свой метод go, который сделает команду ServerHandler в том же потоке, что и ваш бесконечный цикл while. Так должно быть что-то вроде этого ServerHandler(socket.accept(),clientNumber).start(). Также всегда лучше реализовать Runnable, потому что java не поддерживает множественное наследование через концепцию «extends». Поэтому в будущем, если серверу ServerHandler необходимо фактически расширить пользовательский класс, он не сможет его использовать, так как он уже расширяет класс Thread. Его лучше реализовать интерфейсы, поскольку нет ограничений на то, сколько вы можете реализовать.

Следовательно, внедрение интерфейса Runnable - хороший выбор дизайна. Вы можете запустить свой клиентский код параллельно, сделав клиента в поточную модель.Вот один из таких примеров нескольких клиентских сокетов, подключенных к серверу параллельно

код сервера

public class WebServer { 
    static int hitCount = 0; 

    public static void main(String[] args) throws Exception { 
     ServerSocket serverSocket = new ServerSocket(7777, 10000); 
     while (true) { 
      Socket defaultSocket = serverSocket.accept(); 
      new Thread(new ServerSlave(defaultSocket)).start(); 
      System.out.println("Size is :" + hitCount); 
     } 

    } 
} 

class ServerSlave implements Runnable { 
    Socket clientSocket; 

    public ServerSlave(Socket socket) { 
     clientSocket = socket; 
     WebServer.hitCount++; 
    } 

    public void run() { 

     try { 

      DataInputStream inputStream = new DataInputStream(clientSocket.getInputStream()); 
      DataOutputStream outputStream = new DataOutputStream(clientSocket.getOutputStream()); 
      System.out.println(inputStream.readUTF()); 
      outputStream.writeUTF("Thank you for contacting the web server"); 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      try { 
       clientSocket.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

код клиента:

public class Client { 
    static int excepCount=0; 
    public static void main(String[] args) throws Exception { 
     for (int i = 0; i < 100; i++) { 
      new Thread(new Worker("" + i)).start(); 
     } 
     Thread.sleep(10000); 
     System.out.println(Client.excepCount); 
    } 
} 


class Worker implements Runnable { 
    String clientName; 

    public Worker(String name) { 
     clientName = name; 
    } 

    public void run() { 
     System.out.println("Process started for : " + clientName); 
     Socket socket = null; 
     try { 
      socket = new Socket("127.0.0.1", 7777); 
      DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream()); 
      outputStream.writeUTF("Hello socket. Client number " + clientName + "here"); 
      InputStream inFromServer = socket.getInputStream(); 
      DataInputStream in = 
        new DataInputStream(inFromServer); 
      System.out.println("Server says " + in.readUTF()); 
      System.out.println("Closing socket"); 

     } catch (IOException e) { 
      Client.excepCount++; 
      e.printStackTrace(); 
     }finally{ 
      try { 
       socket.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 
+0

Спасибо за объяснения, Так способ генерировать несколько одновременных запросов от клиента состоит в том, чтобы иметь 2-й класс в проекте Client, а также аналогичный второму классу, который у меня есть в моем проекте сервера? – user83676

+0

Вы можете это сделать, или вы можете сами реализовать класс клиента Runnable, а затем создать цикл в основном методе и сгенерировать новый объект Thread и передать ему экземпляр вашего клиента и запустить его. :) – Rishi

+0

Что-то вроде 'new Thread (new YourClient()). Start()' :) – Rishi

0

Вы должны использовать многопоточность. Вы должны переименовать метод для «запуска»/и вызвать этот метод с помощью «Пуск» на стороне изменения Пожалуйста посылайте сервера код

try { 
     while (true) { 
      new ServerHandler(socket.accept(),clientNumber).start(); 
      clientNumber++; 
     } 
    } 
    finally { 
     socket.close(); 
     } 

и на стороне клиента

public class ServerHandler extends Thread { 
    private static Socket socket; 
    private static int clientNumber; 

    public ServerHandler(Socket socket, int clientNumber) { 
     ServerHandler.socket = socket; 
     ServerHandler.clientNumber = clientNumber; 
    } 

    public void run() { 
     while(true) { 
     try { 
      //do calculation, do server tasks, etc. 
      } 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     } 
+0

Я установил run() vs start(), но моя клиентская сторона находится в другом проектном пакете, чем мой класс ServerHandler. После изменения run() и start(), как мне теперь генерировать одновременные запросы от моего клиента? – user83676

+0

Если вы не можете запускать свой проект клиента с отдельного компьютера, то вы можете сделать, это запустить клик nt несколько раз с вашей машины. Большинство IDE поддерживают это. Какую IDE вы используете? – Spray

Смежные вопросы