5

クライアントAがサーバーBを介してクライアントCに何かを送信したい小さなチャットアプリケーションを構築しています。まず第一に、これは問題に対する正しいアプローチですか??. サーバーとの間でデータを送受信することはできますが、クライアントのみに制限されています。たとえば、クライアント A がサーバー B にデータを送信し、クライアント C がサーバー B にデータを送信している場合、データを A に送り返し、 C はエコー サーバーと同じです。しかし、私が望むのは、クライアントAからのデータをサーバーB経由でクライアントCに転送することです.

サーバーコードは次のとおりです。

public class Server {
    public static void main(String[] args) {
        int port = 666; //random port number
        try {
            ServerSocket ss = new ServerSocket(port);
            System.out.println("Waiting for a client....");

            System.out.println("Got a client :) ... Finally, someone saw me through all the cover!");
            System.out.println();
            while(true) {
                Socket socket = ss.accept();

                SSocket sSocket = new SSocket(socket);
                Thread t = new Thread(sSocket);
                t.start();
                System.out.println("Socket Stack Size-----"+socketMap.size());
            }
        }
        catch (Exception e) { }
    }
}

class SSocket implements Runnable {
    private Socket socket;

    public SSocket(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            InputStream in = socket.getInputStream();
            OutputStream out = socket.getOutputStream();

            DataInputStream dIn = new DataInputStream(in);
            DataOutputStream dOut = new DataOutputStream(out);

            String line = null;
            while (true) {
                line = dIn.readUTF();
                System.out.println("Recievd the line----" + line);
                dOut.writeUTF(line + " Comming back from the server");
                dOut.flush();
                System.out.println("waiting for the next line....");    
            }
        }
        catch (Exception e) { }
    }
}

クライアントコードは次のとおりです。

public class Client {
    public static void main(String[] args) {
        int serverPort = 666;

        try {
            InetAddress inetAdd = InetAddress.getByName("127.0.0.1");
            Socket socket = new Socket(inetAdd, serverPort);

            InputStream in = socket.getInputStream();
            OutputStream out = socket.getOutputStream();

            DataInputStream dIn = new DataInputStream(in);
            DataOutputStream dOut = new DataOutputStream(out);

            BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));

            System.out.println("Type in something and press enter. Will send it to the server and tell ya what it thinks.");
            System.out.println();

            String line = null;
            while (true) {
                line = keyboard.readLine();
                System.out.println("Wrinting Something on the server");
                dOut.writeUTF(line);
                dOut.flush();

                line = dIn.readUTF();
                System.out.println("Line Sent back by the server---" + line);
            }
        }
        catch (Exception e) { }
    }
}
4

3 に答える 3

5

クライアントがサーバーに接続すると、サーバーはそのSocketための を作成します。ここではSocket socket = ss.accept();、ソケット変数がそのクライアントを保持します。

クライアントソケットをループ内に追加し続けると、次のようにサーバーにアクティブに接続されているクライアントのリストが表示されarraylistます。while

受け入れた後:

clients = new ArrayList<DataOutputStream>();
Socket socket = ss.accept();
os = new DataOutputStream(socket.getOutputStream());
clients.add(os);

そのアレイリストにすべてのクライアントがあるclientsので、それをループするか、読み取り後にデータを送信する必要があるクライアントを定義するプロトコルを使用できます。

Iterator<DataOutputStream> it = clients.iterator();
while ((message = reader.readLine()) != null) { //reading    
    while (it.hasNext()) {
        try {
            DataOutputStream oss = it.next();
            oss.write(message);//writing
            oss.flush();
        }
        catch (Exception e) { }
     }
 }

これにより、arraylist 内の利用可能なすべてのクライアントがループされ、すべてに送信されます。一部にのみ送信する方法を定義できます。

例: GUI インタラクションを維持しActiveClients arraylist、メッセージを送信するすべてのクライアントを定義することができます。次に、それらのクライアントの outputStreams だけを追加しますActiveClients

ActiveClients.add(clients.get(2));

または、不要な場合は削除してください。

ActiveClients.remove(clients.get(2));

これをループしてarraylist、上記のようにデータを送信します。

于 2012-04-26T12:07:26.700 に答える
1

クライアントごとにメッセージ キューを作成できます。

  1. クライアント A は、アドレスを含むメッセージ「Hi」Client Cをサーバー B に送信します。
  2. サーバー B がメッセージを受信し、クライアント C のメッセージ キューに追加します。
  3. クライアント C と通信するサーバー B のスレッドは、メッセージ キューをチェックし、メッセージを取得してクライアント C に送信します。
  4. クライアント C がメッセージを受信します。
于 2012-04-26T11:56:49.550 に答える
0

私が間違っていなければ、Server または SSocket クラスからのメッセージの受信に問題があるはずです。あなたのコードで何が起こるかというと、クライアントからサーバーにメッセージを送信すると、サーバークラスがメッセージを受信すると、クライアントでメッセージのエコーも返されます。ただし、サーバー クラスからメッセージを送信すると、クライアント クラスにはメッセージが届きません。

これを機能させるには、次のようにコードを変更する必要があります。

SSocket クラス

String line = null;
while (true) {
    line = dIn.readUTF();
    System.out.println("Recievd the line----" + line);
    dOut.writeUTF(line + " Comming back from the server");
    dOut.flush();
    System.out.println("waiting for the next line....");
}

次の行を追加する必要があります。

String Line2 = take.nextLine(); //The user types a message for the client
dOut.writeUTF(Line2 + " Comming back from the server"); //The message is sent to the client

whileループをこれに置き換えると、正常に機能します。

while (true) {       
    line = dIn.readUTF(); //Takes the msg from the client
    System.out.println("Recievd the line----" + line); //Prints the taken message

    String Line2 = take.nextLine(); //The user types a message for the client
    dOut.writeUTF(Line2 + " Comming back from the server"); //The message is sent to the client
    dOut.flush();
    System.out.println("waiting for the next line....");
}
于 2014-11-11T22:44:45.217 に答える