2012-09-23 4 views
6

私はこれをしばらく試してきました。複数のクライアントが同時に複数の入力を受け取るようにしたいと思います。
1つの問題があります。クライアントが「print2allこんにちは」と言うと、サーバがすべてのクライアントに「こんにちは」を印刷するようにします。
私はそれを印刷するためにそれを処理する方法を知っています、ただすべてのクライアントに印刷することが問題です。ソケットを使ってJavaサーバーを作成しました。すべてのソケットに印刷するにはどうすればいいですか?

これまで私がこれまで持っていたことは次のとおりです。
サーバー

try{ 
    try{ 
     server = new ServerSocket(25565); 
    } catch (Exception e){ 
     e.printStackTrace(); 
    } 
    while (isListening){ 
     new SocketThread(server.accept()).start(); 
    } 
    server.close(); 
} catch (Exception e){ 
    e.printStackTrace(); 
} 

SocketThread

try { 
    PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 
    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 

    String inputLine, outputLine; 
    Processor kkp = new Processor(); 
    out.println("Hi!"); 

    while ((inputLine = in.readLine()) != null) { 
     outputLine = kkp.Proccess(inputLine,this.socket); 
     out.println(outputLine); 
    } 
    out.close(); 
    in.close(); 
    socket.close(); 

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

クライアント

  Processor p = new Processor(); 
      socket = new Socket("localhost",25565); 
      out = new PrintWriter(socket.getOutputStream(), true); 
      in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
  BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); 
      String fromServer; 
      String fromUser; 

      out.println("print2all Hi") 

      socket.close(); 

男。あなたはスターター・サーバとしてこれを使用したい場合は、私は完全なアクセス許可= P

答えて

5

まずを与えるあなたは、すべての接続されたクライアントを追跡する必要があります:1つのクライアントは"print2all Hi"それだけで繰り返し処理を受信した場合

final List<SocketThread> clients = new ArrayList<>(); 

while (isListening){ 
    SocketThread client = new SocketThread(server.accept()).start(); 
    clients.add(client); 
} 

は、このようなリストを持ちますすべてclientsに送信し、それぞれにメッセージを送信します。これを行うには、ほとんどクライアントソケットにアクセスするSocketThreadのメソッドを公開する必要があります。つまり、フィールドに変数outを変更する必要があります。

代替アプローチは、クライアントソケットのリストを保持することです。しかし、これはカプセル化をひどく破壊する。また、ソケットが直接公開されていると、厄介なIO /スレッドセーフの問題に遭遇するかもしれません。 (SocketThreadメソッドのような)いくつかのAPIの背後にそれらを隠し、同期を正しく内部で実行してください。

+1

1つの放送。 –

+0

@ChristopheBiocca:あなたは正しいですが、OPにははるかに単純な問題があるようです。しかし、私はスレッドの安全性について言及します、ありがとう! –

+0

+1並行性ライブラリのコレクションを使用する場合は、スレッドを追加して最後にソケットを削除して、リストを維持することができます。接続のハンドラを追加したり削除したりすると、接続の状態をよく取得できるので便利です。 –

1

あなたが探しているものの完全な実装。

サーバー

package tcpserver; 

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.ArrayList; 
import java.util.List; 
import java.util.StringTokenizer; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

public class TCPServer { 

    private int serverPort = 25565; 
    private ServerSocket serverSocket; 
    private List<ConnectionService> connections = new ArrayList<ConnectionService>(); 

    public TCPServer() { 
     try { 
      serverSocket = new ServerSocket(serverPort); 
      System.out.println("Waiting..."); 
      while (true) { 
       Socket socket = serverSocket.accept(); 
       System.out.println("Connected: " + socket); 
       ConnectionService service = new ConnectionService(socket); 
       service.start(); 
      } 

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

    } 

    public static void main(String[] args) { 
     new TCPServer(); 
    } 

    class ConnectionService extends Thread { 

     private Socket socket; 
     private BufferedReader inputReader; 
     private PrintWriter outputWriter; 
     //private String username; 

     public ConnectionService(Socket socket) { 
      this.socket = socket; 
      try { 
       inputReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
       outputWriter = new PrintWriter(socket.getOutputStream(), true); 
      } catch (IOException e) { 
       System.out.println(e.getMessage()); 
      } 
     } 

     @Override 
     public void run() { 
      while (true) { 
       try { 
        String receivedMessage = inputReader.readLine(); 
        System.out.println(receivedMessage); 
        StringTokenizer stoken = new StringTokenizer(receivedMessage); 
        String fargument = stoken.nextToken(); 
        if (fargument.equals("print2all")) { 
         this.sendToAnyone(stoken.nextToken()); 
        } 
       } catch (IOException ex) { 
        Logger.getLogger(TCPServer.class.getName()).log(Level.SEVERE, null, ex); 
       } catch (NullPointerException e) { 
        System.out.println(e.getMessage()); 
       } finally { 
        outputWriter.close(); 
       } 

      } 
     } 

     protected void sendMessage(String message) { 
      outputWriter.println(message); 
     } 

     private void sendToAnyone(String message) { 

      for (ConnectionService connection : connections) { 
       connection.sendMessage(message); 
      } 
     } 
    } 
} 

クライアント私はあなたがソケットを所有するソケットスレッドからの同時印刷で終わることができるようにソケットが、しかし、スレッドセーフであるとは思わない

package tcpclient; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.InetAddress; 
import java.net.Socket; 

public class tcpClient extends javax.swing.JFrame { 

    private Socket socket; 
    private BufferedReader inputReader; 
    private PrintWriter outputWriter; 

    public tcpClient() { 
     connectToServer(); 
    } 

    private void connectToServer() { 
     try { 
      socket = new Socket(InetAddress.getByName("localhost"), 25565); 
      inputReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
      outputWriter = new PrintWriter(socket.getOutputStream(), true); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     new Thread() { 
      @Override 
      public void run() { 
       receiveData(); 
      } 
     }.start(); 
    } 

    private void receiveData() { 
     try { 
      while (true) { 
       System.out.println(inputReader.readLine()); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    public void sendData(String messageToSend) { 
     outputWriter.println(messageToSend); 
    } 

    public void closeSocket() { 
     if (socket != null) { 
      try { 
       socket.close(); 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 
     } 
    } 

    public static void main(String args[]) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       tcpClient client = new tcpClient(); 
       client.sendData("print2all Hi"); 
       client.closeSocket(); 
      } 
     }); 
    } 
} 
関連する問題