Программирование сокетов: функция Broadcast отправляет только одному клиенту - PullRequest
0 голосов
/ 13 ноября 2011

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

Моя проблема в том, что сообщение передается только клиенту, с которого оно пришло, и я не могу определить ошибку в своем коде.

Может кто-нибудь помочь мне определить, в чем проблема или как я могу улучшить код? Спасибо.

EDIT:

public class MsgClient{

private Socket client;
private ObjectInputStream input;
private DataOutputStream output;
private BufferedReader keyboard;
private String cmdInput;


public MsgClient(String name, String server, int port){

    try{

        client = new Socket(server, port);

        DataInputStream sInput = new DataInputStream(client.getInputStream());
        output = new DataOutputStream(client.getOutputStream());
        input = new ObjectInputStream(client.getInputStream());
        keyboard = new BufferedReader(new InputStreamReader(System.in));


        output.writeUTF(name);


        while(true){
            System.out.println("Send a msg to the server: ");
            cmdInput = keyboard.readLine();
            output.writeUTF(cmdInput);
            System.out.println(sInput.readUTF());
        }

    }
    catch (Exception e){
        e.printStackTrace();
    }   
}// end constructor


public static void main(String args[]) throws IOException {
    if(args.length != 3)
        throw new RuntimeException("Syntax: java MsgClient <username> <servername> <port>");
    MsgClient aClient = new MsgClient(args[0], args[1], Integer.parseInt(args[2]));
} // end main

}

public class MsgServer {


public MsgServer(int PORT) throws IOException{

    ServerSocket server = new ServerSocket(PORT);
    System.out.println("Server Established...");


    while(true){

        Socket client = server.accept();

        DataInputStream input = new DataInputStream(client.getInputStream());
        ObjectOutputStream oo = new ObjectOutputStream(client.getOutputStream());
        DataOutput output = new DataOutputStream(client.getOutputStream());

        System.out.println("New client accepted");

        String clientName = input.readUTF();
        ClientHandler handler = new ClientHandler(clientName, client);  // construct and run thread.

        handler.start();
        System.out.println("Handler started!");

    }//end while

}//end of constructor


public static void main(String args[]) throws IOException {
    if(args.length != 1)
        throw new RuntimeException("Syntax: java MsgServer requires <PORT> number");
    new MsgServer(Integer.parseInt(args[0]));
}

}

public class ClientHandler extends Thread {

Socket client;
DataInputStream din;
DataOutputStream dout;
String name;

String clientMsg;

protected static Vector socketVector = new Vector();


public ClientHandler (String name, Socket client) throws IOException{
    this.name = name;
    this.client = client;
    din = new DataInputStream(client.getInputStream());
    dout = new DataOutputStream(client.getOutputStream());
}

// Code run at every start()
public void run(){
    try{
        socketVector.addElement(this);      
        clientMsg = din.readUTF(); // inside or outside loop?

        while(true){
            broadcast( name + " has joined auction on IP " + client.getInetAddress());
            broadcast( name + " says: " + clientMsg);
        }

    } catch(IOException ex){
        System.out.println("-- Connection to user lost");
    } finally{
        socketVector.removeElement(this);
        broadcast(name + " has left");
        try{
            client.close();
        }catch (IOException ex){
            System.out.println("socket to user already closed?");
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 14 ноября 2011

Другая проблема здесь, в коде MsgClient:

cmdInput = keyboard.readLine();
output.writeUTF(cmdInput);
System.out.println(sInput.readUTF());

Клиент не получит сообщение до тех пор, пока не отправит его.

0 голосов
/ 14 ноября 2011
  1. Где метод broadcast()?

  2. Вы создаете два набора потоков на сервере. Цикл принятия не должен создавать никаких потоков или делать ввод-вывод. Все это должно быть сделано в потоке, который обрабатывает соединение.

  3. Вам вообще не нужен ObjectInput/OutputStreams здесь.

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

...