如何使用套接字将数据从服务器发送到多个客户端?

时间:2015-08-03 11:54:54

标签: java multithreading sockets client server

我有简单的服务器客户端程序:

public class Server extends Thread {
    private ServerSocket server;

    public Server(int port) {
        try {
            this.server = new ServerSocket(port);
            System.out.println("New server initialized!");
            this.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void run() {
        while (true) {
            try {
                Socket client = server.accept();
                System.out.println(client.getInetAddress().getHostName()
                        + " connected");
                new ServerHandler(client);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

服务器处理程序必须在流中发送消息:

public class ServerHandler extends Thread {
    protected Socket client;
    protected String userInput;
    protected PrintWriter out;
    protected BufferedReader console;

    public ServerHandler(Socket client) {
        this.client = client;
        this.userInput = null;
        this.start();
    }

    public void run() {
        System.out.println("New Communication Thread Started");
        System.out.println("Enter message:");
        try {
            this.out = new PrintWriter(client.getOutputStream(), true);
            this.console = new BufferedReader(new InputStreamReader(System.in));
            while ((this.userInput = console.readLine()) != null) {
                this.out.println(userInput);
            }               
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

客户端收到该消息:

public class Client {
    protected Socket client;
    protected BufferedReader in;

    public Client(String hostName, int ip) {
        try {
            this.client = new Socket(hostName, ip);
            this.in = new BufferedReader(new InputStreamReader(
                    this.client.getInputStream()));
            String buffer = null;
            while ((buffer = in.readLine()) != null) {
                System.out.println(buffer);
            }
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

它适用于一个客户端,但是当我从服务器接收消息时出现新客户端问题时出现。 我做错了什么?

1 个答案:

答案 0 :(得分:5)

我找到了答案:

public class Server extends Thread {
    private ServerSocket server;
    protected List<ClientHandler> clients;

    public Server(int port) {
        try {
            this.server = new ServerSocket(port);
            System.out.println("New server initialized!");
            clients = Collections
                    .synchronizedList(new ArrayList<ClientHandler>());
            this.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void run() {
        while (true) {
            try {
                Socket client = server.accept();
                System.out.println(client.getInetAddress().getHostName()
                        + " connected");
                ClientHandler newClient = new ClientHandler(client);
                clients.add(newClient);
                new SendMessage(clients);

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

ClientHandler而不是Serverhandler类:

public class ClientHandler {
    protected Socket client;
    protected PrintWriter out;

    public ClientHandler(Socket client) {
        this.client = client;
        try {
            this.out = new PrintWriter(client.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

线程可以添加到Client类,但没有它可以正常工作。我假设因为当自动创建名为new thread的main方法时:

public class Client {
    protected Socket client;
    protected BufferedReader in;

    public Client(String hostName, int ip) {
        try {
            this.client = new Socket(hostName, ip);
            this.in = new BufferedReader(new InputStreamReader(
                    this.client.getInputStream()));
            String buffer = null;
            while ((buffer = in.readLine()) != null) {
                System.out.println(buffer);
            }
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }       
}

向客户发送数据的类:

 public class SendMessage extends Thread {
        protected List<ClientHandler> clients;
        protected String userInput;
        protected BufferedReader console;

        public SendMessage(List<ClientHandler> clients) {
            this.clients = clients;
            this.userInput = null;
            this.start();
        }

        public void run() {
            System.out.println("New Communication Thread Started");
            if (clients.size() == 1) {
                System.out.println("Enter message:");
            }
            try {
                if (clients.size() > 0) {
                    this.console = new BufferedReader(new InputStreamReader(
                            System.in));
                    while ((this.userInput = console.readLine()) != null) {
                        if (userInput != null & userInput.length() > 0) {
                            for (ClientHandler client : clients) {
                                client.out.println(userInput);
                                client.out.flush();
                            Thread.currentThread();
                            Thread.sleep(1 * 1000);
                            }
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

现在它有效! 刷新数据后需要使SendMessage线程休眠。 主要用于服务器启动器:

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

主要为客户启动:

public static void main(String[] args) {
new Client("127.233.0.1", 1200);
}