2016-06-19 2 views
0

Я пытаюсь создать клиент-серверную программу с Java, где клиенты отправляют простую строку на сервер, и каждый клиент, подключенный к серверу, получает эту строку. Итак, я создал 2 серверных класса для сервера, которые создают новый поток для каждого клиента и слушают их. Также есть список клиентских сокетов. Я хочу использовать его для отправки каждому клиенту String, который был отправлен одним из клиентов. Для этого я использую цикл foreach. Но я получил DataOutputStream только для клиента, который послал строку на сервер:Не удается получить сокеты DataOutputStream в цикле для списка сокетов

public void run(){ 
    try{ 
     while(true){ 
      String data = in.readUTF(); 
      for(Socket soc : GlobalQdaServer.allClients){ 
       DataOutputStream sOut = new DataOutputStream(soc.getOutputStream()); 
       sOut.writeUTF(data + ". Total clients number in list: " + GlobalQdaServer.allClients.size()); 
      }     
     } 
    } 
    catch(EOFException ex){ 
     System.out.println(ex.getMessage()); 
    } 
    catch(IOException ex){ 
     System.out.println(ex.getMessage()); 
    } 
} 

Таким образом, только этот клиент recieves строки (который он послал себя). Другие ничего не получают. Эти полные классы:

import java.io.DataInputStream; 
import java.io.DataOutputStream; 
import java.io.EOFException; 
import java.io.IOException; 
import java.net.ServerSocket; 
import java.net.*; 
import java.util.ArrayList; 
import java.util.List; 


public class GlobalQdaServer { 
    public static List<Socket> allClients = new ArrayList<Socket>(); 

    public static void main(String[] args) { 
     try{ 
      int serverPort = 7896; 
      ServerSocket listenSocket = new ServerSocket(serverPort); 
      while(true){ 
       Socket clientSocket = listenSocket.accept(); 
       allClients.add(clientSocket); 
       Connection c = new Connection(clientSocket); 
      } 
     } 
     catch(IOException ex){ 
      System.out.println("Server Socket creating failiure");    
     } 
    } 

} 

class Connection extends Thread{ 
    DataInputStream in; 
    DataOutputStream out; 
    Socket clientSocket; 
    public Connection(Socket aClientSocket){ 
     try{ 
      clientSocket = aClientSocket; 
      in = new DataInputStream(clientSocket.getInputStream()); 
      out = new DataOutputStream(clientSocket.getOutputStream()); 
      this.start(); 
     } 
     catch(IOException ex){ 
      System.out.println(ex.getMessage()); 
     }   
    } 

    public void run(){ 
     try{ 
      while(true){ 
       String data = in.readUTF(); 
       for(Socket soc : GlobalQdaServer.allClients){ 
        DataOutputStream sOut = new DataOutputStream(soc.getOutputStream()); 
        sOut.writeUTF(data + ". Total clients number in list: " + GlobalQdaServer.allClients.size()); 
       }     
      } 
     } 
     catch(EOFException ex){ 
      System.out.println(ex.getMessage()); 
     } 
     catch(IOException ex){ 
      System.out.println(ex.getMessage()); 
     } 
    } 
} 


    import java.io.BufferedReader; 
import java.io.DataInputStream; 
import java.io.DataOutputStream; 
import java.io.EOFException; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.net.*; 


public class GlobalQdaClient { 

    public static void main(String[] args) throws IOException { 
     int serverPort = 7896; 
     Socket s = new Socket("localhost", serverPort); 
     BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 
     String input = ""; 
     while(!input.equals("end")){ 
      input = reader.readLine(); 
      try{ 
       DataInputStream in = new DataInputStream(s.getInputStream()); 
       DataOutputStream out = new DataOutputStream(s.getOutputStream()); 
       out.writeUTF(input); 
       String data = in.readUTF(); 
       System.out.println("Recieved this: " + data);    
      } 
      catch(UnknownHostException ex){ 
       System.out.println(ex.getMessage()); 
      } 
      catch(EOFException ex){ 
       System.out.println(ex.getMessage()); 
      } 
      catch(IOException ex){ 
       System.out.println(ex.getMessage()); 
      } 
     } 
    }  
} 

Пожалуйста, помогите найти ход проблемы. Я новичок в сокетах. Спасибо

ответ

1

Ваша программа На самом деле работает нормально.

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

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

Попробуйте следующее:

  • Run Сервер
  • Run Client1
  • Run Client2
  • Отправить сообщение От Client1 (Обратите внимание, что Client2 теперь заблокирован из-за ввода)
  • Отправить сообщение От Клиент2

Теперь вы увидите Меня ssage, отправленный ранее с client1 на client2.

Но если вам нужно, чтобы оба клиента получали сообщения после его отправки, вам нужно создать другой поток, чтобы получать обновления постоянно.

Я изменил ваш клиент, чтобы сделать это.

import java.io.BufferedReader; 
import java.io.DataInputStream; 
import java.io.DataOutputStream; 
import java.io.EOFException; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.net.*; 
import java.util.logging.Level; 
import java.util.logging.Logger; 


public class GlobalQdaClient extends Thread { 
     int serverPort = 7896; 
     BufferedReader reader ; 
     static String input = ""; 
     Socket s; 
     DataInputStream in ; 
     DataOutputStream out ; 
public GlobalQdaClient() { 
     try { 
      reader = new BufferedReader(new InputStreamReader(System.in)); 
      s = new Socket("localhost", serverPort); 
      in = new DataInputStream(s.getInputStream()); 
      out = new DataOutputStream(s.getOutputStream()); 
     } catch (IOException ex) { 
      Logger.getLogger(GlobalQdaClient.class.getName()).log(Level.SEVERE, null, ex); 
     } 
} 

public static void main(String[] args) throws IOException { 
    GlobalQdaClient client = new GlobalQdaClient(); 
    client.start(); 
    while(!client.input.equals("end")){ 
     client.input = client.reader.readLine(); 
     try{ 
      client.out.writeUTF(client.input); 
      if(client.in.available()>0){ 
      String data = client.in.readUTF(); 
      System.out.println("Recieved this: " + data);    
      } 
     } 
     catch(UnknownHostException ex){ 
      System.out.println(ex.getMessage()); 
     } 
     catch(EOFException ex){ 
      System.out.println(ex.getMessage()); 
     } 
     catch(IOException ex){ 
      System.out.println(ex.getMessage()); 
     } 
    } 
}  

@Override 
public void run(){ 

    try { 
     while(true){ 
      String data = in.readUTF(); 
      System.out.println("Recieved this: " + data);    
      }  
    } catch (IOException ex) { 
      Logger.getLogger(Message.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 

} 
+0

Благодарим за внимание. Я пытался сделать то, что написал. Но клиент 2 не получил сообщение, отправленное с клиента 1, а клиент 1 не получил сообщение, отправленное от клиента 2. Может быть, клиенты все еще заблокированы? –

+0

О, ладно, теперь я вижу, что предыдущие сообщения получены клиентами ... Но только за 1 сообщение от того или иного клиента со странным порядком. Но что делать, чтобы клиент не был заблокирован? –

+0

Он не будет получен мгновенно, вам нужно разблокировать другого клиента, отправив ему сообщение. Попытайтесь отправить с client1 Alexey, тогда ничего не будет отображаться на client2 как заблокированное еще, но после того, как вы перейдете на client2 и отправите любое сообщение, сообщение alexy появится на client2. –

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