2015-09-09 1 views
0

Я пытаюсь создать клиент-серверное Java-приложение, в котором подключено 4 пользователя, однако у меня есть некоторые проблемы с обменом сообщениями и сообщениями между классами Server и Client.Связь клиент-сервер в Java

Вот код для сервера:

public class Server { 
    private static final int port = 9991; 
    private static final String serverHost = "localhost"; 
    private static ServerSocket serverSocket; 
    private static Socket socket; 
    private static DataInputStream serverInput; 
    private static DataOutputStream serverOutput; 
    private static String message; 
    private static int noOfUsers = 0; 

    public static void main(String args[]){ 
     try{ 
      serverSocket = new ServerSocket(port); 
      System.out.println("Server is up (Port: " + port + ")"); 

      while (true){ 
       socket = serverSocket.accept(); 
       serverInput = new DataInputStream(socket.getInputStream()); 
       serverOutput = new DataOutputStream(socket.getOutputStream()); 

       message = serverInput.readUTF(); 
       if (message.equals("C_Message1")){ 
        System.out.println("Client has connected!"); 
        serverOutput.writeUTF("S_Message1"); 
       } 
       else if (message.equals("C_Message2")){ 
        if (noOfUsers <= 3){ 
         serverOutput.writeUTF("S_Message2"); 
         noOfUsers++; 
        } 
        else { 
         serverOutput.writeUTF("S_Message3"); 
         System.out.println("User rejected");    
        } 
       } 

      } 
     } catch (IOException e){ 
      System.err.println(e.getMessage() + " -> " + e.getCause()); 
     } 

    } 
} 

и вот код для класса Client:

public class Client implements Runnable { 
    private static final int serverPort = 9991; 
    private static final String serverHost = "localhost"; 

    private static Socket socket; 
    private static DataInputStream clientInput; 
    private static DataOutputStream clientOutput; 

    private static String message; 

    private static int userID; 

    @Override 
    public void run() { 

     try { 
      socket = new Socket(serverHost, serverPort); 
      System.out.println("Connection succesfull."); 

      clientInput = new DataInputStream(socket.getInputStream()); 
      clientOutput = new DataOutputStream(socket.getOutputStream()); 

      clientOutput.writeUTF("C_Message1"); 
      System.out.println("Connected to server!"); 

      while (true){ 
       message = clientInput.readUTF(); 

       if (message.equals("S_Message1")){ 
        clientOutput.writeUTF("C_Message2"); 
       } 
       else if (message.equals("S_Message2")){ 
        System.out.println("Accepted on table!"); 
       } 
       else if (message.equals("S_Message3")){ 
        System.out.println("Rejected"); 
       } 
      }     
     } catch (UnknownHostException e) { 
      System.out.println("Cannot find host."); 
     } catch (IOException e) { 
      System.out.println("IO Exception thrown"); 

     } 
    } 
} 

и я создаю экземпляр Клиента внутри моего класса GUI,

Client client = new Client(); 
Thread clientThread = new Thread(client); 
clientThread.start(); 

Проблема в том, что обмен сообщениями не работает должным образом. Я отправляю C_Message1 от клиента к серверу, когда сервер получает это сообщение, он отправляет обратно S_Message1 клиенту, а затем Клиент отправляет C_Message2 на сервер и так далее. Однако обмен сообщениями, как-то останавливается, когда клиент пытается отправить C_Message2.

+1

Ваш 'accept' находится внутри цикла while. Это означает, что после нового сообщения сервер принимает новое соединение, старый сокет заброшен и больше не будет получать от него никаких сообщений. – RealSkeptic

+0

Даже если к серверу подключен только один пользователь, проблема все еще существует. Более того, я не вижу другого места, где может быть размещен 'socket.accept()'. Спасибо за ваш ответ. –

+0

Если у вас есть только один пользователь, он будет просто ждать в 'socket.accept()' до тех пор, пока пользователь не подключится ... У вас должен быть отдельный цикл для принятия и отдельный цикл для обработки одного сеанса - предпочтительно в другом нить (или вы не сможете принять другого пользователя). – RealSkeptic

ответ

1

В системе клиент-сервер, как этот, вы должны обрабатывать два потока (по крайней мере) на клиенте и два потока на сервере:

  • один поток отправлять сообщения
  • один поток получать сообщения

это асинхронный, который работает в основном следующим образом:

  • Sender нить на клиента отправить сообщение «Hello»
  • Receiver поток на сервере появляется сообщение «Hello»
  • Receiver нити создать новое сообщение «Я получил привет сообщение» и поставить его на общий список между приемником и отправителем резьбой сервера
  • Sender нити сервера видит, что новое сообщение присутствует в общем списке
  • Sender нить извлечь сообщение из списка и послала его клиент
  • Receiver поток на клиенте появляется сообщение «Я получил привет сообщения»

Надеюсь, что процесс ясен. Удачи

+0

Спасибо за ваш ответ Давиде. Я немного смущен термином «общий список». Любые примеры кода (не обязательно основанные на моем коде) приветствуются. –

+0

Разделяется между потоками. Это означает, что вам нужно получить к нему доступ в синхронизированном блоке, иначе вы можете получить поврежденные данные, считывающие его –

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

  • Нет связанных вопросов^_^