8

私はこれをしばらく試してきましたが、複数のクライアントに複数の入力を同時に受信してもらいたいと思っています。
1つの問題があります。1つのクライアントが「print2allHi」と言った場合、サーバーがすべてのクライアントに「Hi」を出力するようにします。
私はそれを処理して印刷する方法を知っています。すべてのクライアントに印刷するだけが問題です。

これが私がこれまでに持っているものです。
サーバ

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();
4

2 に答える 2

6

まず、接続されているすべてのクライアントを追跡する必要があります。

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

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

1人のクライアントがそれを受け取った場合にそのようなリストを持つことは"print2all Hi"、単にすべてを繰り返し、clientsそれぞれにメッセージを送信します。SocketThreadこれを行うには、クライアントソケットにアクセスするメソッドを公開する必要があります。outこれは、変数をフィールドに変更する必要があることを意味します。

別のアプローチは、クライアントソケットのリストを保持することです。しかし、これはカプセル化をひどく壊します。また、ソケットが直接公開されている場合、厄介なIO/スレッドセーフの問題が発生する可能性があります。それらをいくつかのAPI(メソッドなど)の背後に隠しSocketThread、内部で適切に同期を行うことをお勧めします。

于 2012-09-23T08:08:34.940 に答える
3

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

サーバ

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();
            }
        });
    }
}
于 2012-09-23T08:19:39.503 に答える